「社内のSSOにSAMLを使っているが、どんな脆弱性があるのか把握できていない」——そんな不安を持つ情シス担当者は少なくありません。
SAML(Security Assertion Markup Language)は、Okta・Azure AD・Google Workspaceといった企業向けSSOの基盤として広く利用されています。しかし実装の細部に落とし穴があり、攻撃者はその隙を突いて認証を完全にバイパスし、管理者権限を含む任意のアカウントに不正ログインすることができます。
この記事では、SAMLに潜む脆弱性の種類と攻撃の仕組みを防御目的で解説し、IdP・SP双方で今すぐ実施できる対策を現場で使えるレベルでお伝えします。SAMLライブラリの選定から設定の具体的なポイントまで、情シス1人体制でも対応できる内容にまとめました。

SAMLとは?なぜ今セキュリティ上の注意が必要か
SAMLとは、XMLをベースにした認証・認可情報の交換標準です。2002年に策定され、現在もエンタープライズ向けSSOの事実上の標準として使われています。
SAMLの登場人物は大きく3つです。
・ユーザー(Subject): ログインしようとする人
・IdP(Identity Provider): 認証を行いアサーション(証明書)を発行する側。Okta、Azure ADなど
・SP(Service Provider): そのアサーションを受け取り、サービスへのアクセスを許可する側。SalesforceやSlackなど
ユーザーがSPにアクセスすると、SPはIdPにリダイレクトし、IdPで認証が通ればSAMLアサーション(XML文書)がSPに渡されます。SPはその内容を信頼してログインを完了します。
問題は、SAMLアサーションがXML形式である点です。XMLは仕様が複雑で、パーサーの実装差異や設定ミスが攻撃者に悪用されるケースが後を絶ちません。シングルサインオン(SSO)の便利さの裏に、実装の複雑さが潜んでいるのです。
また、SAMLに問題があるとSSOで連携している全サービスが影響を受けるという点も見逃せません。1つの脆弱性が、社内の全アプリケーションへの不正アクセスにつながる可能性があります。
SAMLに潜む主な脆弱性の種類
1. XML署名ラッピング攻撃(XSW攻撃)
SAMLの脆弱性の中でも特に深刻なのが、XML Signature Wrapping(XSW)攻撃です。
SAMLアサーションには、改ざんを防ぐためのXML署名が付いています。しかし、一部のSAMLライブラリは「署名の検証に成功したこと」と「実際に処理するアサーションが署名対象と同一であること」を別々にしか確認しない実装になっています。
攻撃者はこの隙を突きます。具体的には次のような手順です。
・Step 1: 攻撃者が正規ユーザーとしてログインし、有効なSAMLレスポンスを入手する
・Step 2: そのXMLを改ざんして、自分のNameIDを管理者のものに書き換えた偽アサーションを元のXML内に「ラップ(包み込む)」する
・Step 3: SPは署名を検証するが、署名の対象は元のアサーション(正規のもの)のため検証は成功する
・Step 4: しかしSPが実際に読むのは攻撃者が差し込んだ偽アサーションの内容であり、管理者として認証される
この攻撃が成立するかどうかは、SPが「どのアサーションを署名対象として処理するか」の実装に依存します。古いSAMLライブラリや設定が不十分な実装で特に発生しやすく、過去に複数のOSSライブラリで実際の脆弱性として報告されています。
2. コメントインジェクション攻撃
XMLにはコメント(<!-- -->)を記述する機能があります。これを悪用したのがコメントインジェクション攻撃です。
攻撃者は、SAMLのNameID(ユーザー識別子)にXMLコメントを埋め込みます。たとえば次のような形です。
# NameIDに埋め込まれた悪意あるコメントの例(概念) <NameID>user@example.com<!-- fake -->admin</NameID>
XMLパーサーによっては、コメント部分を除去した結果を「有効な値」として解釈することがあります。署名検証時のパーサーと、NameIDを取り出す際のパーサーで挙動が異なる場合、攻撃者は署名が通ったまま別のユーザー名を注入することが可能です。
この攻撃はパーサーの実装差異を突くもので、SAMLライブラリのバージョンや設定によって影響範囲が変わります。
3. リプレイ攻撃(アサーション再利用)
SAMLアサーションは一時的に有効な「トークン」です。適切な有効期限管理がなければ、攻撃者は過去に盗んだアサーションを再利用してログインできます。これがリプレイ攻撃です。
SAMLにはリプレイを防ぐための仕組みが標準で用意されています。
・NotBefore / NotOnOrAfter属性: アサーションの有効期間を明示する
・InResponseTo属性: SAMLレスポンスが、特定のSAMLリクエスト(AuthnRequest)に対応していることを示す
・AssertionIDのキャッシュ: 一度使用したアサーションIDを記録し、再利用を拒否する
しかしこれらの検証を省略または誤って実装していると、攻撃者は傍受したアサーションを繰り返し使用できます。公共のWi-Fiや中間者攻撃で傍受されるリスクと組み合わさると、特に危険です。
4. XML外部エンティティ(XXE)経由の攻撃
SAMLはXML形式であるため、XMLパーサーがDTD(文書型定義)の外部エンティティ処理を許可している場合、XXE脆弱性も発生します。
攻撃者はSAMLリクエストやレスポンスにXXEペイロードを埋め込み、SP側のサーバーから内部ファイル(/etc/passwdなど)を読み取ったり、内部ネットワークへのSSRFに悪用したりする可能性があります。SAMLを受け取るエンドポイントは必ずXXE対策が必要です。
具体的な防御手順
1. 署名検証を必須化し、正しく実装する
XSW攻撃を防ぐ最重要対策は、署名の検証と実際に処理するアサーションを同一であると確認することです。
具体的には次の点を確認してください。
・署名なしのSAMLレスポンスを一切受け付けない設定になっているか
・SP側でアサーションの署名を検証しているか(レスポンスの署名だけでなく)
・使用しているSAMLライブラリがXSW攻撃に対して修正済みのバージョンか
SAMLライブラリの選定では、活発にメンテナンスされているものを選び、脆弱性情報を定期的に確認することが重要です。Python系ならpython3-samlやpysaml2、JavaならOpenSAMLなどが広く使われていますが、いずれも最新バージョンへのアップデートを怠らないようにしてください。
2. アサーション有効期限を短く設定する
リプレイ攻撃の被害を最小化するには、SAMLアサーションの有効期間をできるだけ短く設定します。
# SAMLアサーションの有効期限設定例(IdP側の設定概念) # NotBefore と NotOnOrAfter の間隔を短くする # 推奨: 5分以内(最大でも15分) <saml:Conditions NotBefore="2026-08-13T10:00:00Z" NotOnOrAfter="2026-08-13T10:05:00Z">
有効期間が長いほど、傍受されたアサーションが悪用される時間的余裕が生まれます。多少の時刻のずれ(クロックスキュー)を許容する設定は通常必要ですが、それでも5分前後が推奨です。
3. InResponseToとアサーションIDの検証でリプレイを防ぐ
SP側で次の検証を必ず実装します。
・InResponseToの検証: SAMLレスポンスのInResponseTo属性が、自分が送ったAuthnRequestのIDと一致するかを確認する。一致しない場合は処理を拒否する
・アサーションIDのキャッシュ: 受け取ったアサーションのIDをキャッシュし、同じIDのアサーションが再度送られてきた場合は拒否する
・NotOnOrAfterの厳格な検証: 有効期限切れのアサーションを一切受け付けない
これらはSAML仕様で定められているにもかかわらず、実装を省略しているケースが見受けられます。使用しているSAMLライブラリのドキュメントで、これらの検証がデフォルトで有効かどうか確認してください。
4. XXE対策:DTD処理を無効化する
SAMLを受け取るXMLパーサーでは、外部エンティティ(DTD)の処理を無効にします。
# Javaの場合:SAXParserFactoryでDTD処理を無効化する例 factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
多くの現代的なSAMLライブラリはデフォルトでXXE対策済みですが、古いバージョンや自前実装の場合は明示的な設定が必要です。
5. SAMLライブラリを常に最新に保つ
SAMLライブラリには過去にも複数の脆弱性が発見・修正されてきました。使用しているライブラリのバージョンをGitHubや公式サイトで定期的に確認し、セキュリティアップデートは速やかに適用します。
IdP側(Okta、Azure AD等のクラウドサービス)はプロバイダが自動的にアップデートしますが、SP側のライブラリは自社管理です。この点を見落とさないようにしてください。
中小企業でも今日からできること
大手のIdPサービス(Okta、Azure AD、Google Workspace)をそのまま使っている場合、IdP側の実装はプロバイダが管理しています。ただし、SP側の設定と実装は自社責任です。
今すぐ確認すべきチェックリストです。
・SaaSのSAML設定画面を確認: 署名アルゴリズムがSHA-256以上になっているか(SHA-1は非推奨)。設定画面で確認できる
・アサーション有効期限: IdP管理画面でセッション有効期限を短めに設定する(8時間以内を推奨)
・自社開発SPのライブラリ確認: 使用しているSAMLライブラリのバージョンをnpm/pip/Mavenで確認し、最新版と比較する
・ログ確認: 認証ログで同じSAMLアサーションIDが複数回使用されていないかを定期チェックする
・テスト実施: SAMLの設定変更後は必ずテストユーザーで動作確認を行う
Okta等のIdPを使っている場合は、管理コンソールの「セキュリティ」設定でSAML関連のオプションを一度通しで確認することをお勧めします。デフォルトから変更すべき設定が見つかることがあります。
よくある誤解と注意点
「大手IdPを使っているから安全」は半分だけ正しい
OktaやAzure ADなどのIdP自体は安全に保たれていますが、SP(アプリケーション)側のSAML実装は自社責任です。「クラウドだから安全」という思い込みは禁物で、SP側のライブラリや設定の管理が不可欠です。
「SAMLはJWTより安全」とは言い切れない
SAMLとJWTはどちらも認証情報の伝達手段ですが、優劣はなくそれぞれ異なる脆弱性を持ちます。JWTにはalg:none攻撃などの固有リスクがあり、SAMLにはXMLの複雑さに起因するリスクがあります。どちらを選ぶにしても、実装の正確さが最も重要です。
「SAMLよりOAuthに移行すれば解決」は早計
OAuth 2.0にも固有のセキュリティリスクがあります。プロトコルを変えるだけでリスクがゼロになるわけではなく、新しいプロトコルには新しい落とし穴があります。移行する場合は、移行先のプロトコルの脆弱性についても同様に学ぶ必要があります。
SAMLのテストには専用ツールを活用する
自社のSAML実装が安全かを確認するには、SAML Tracerブラウザ拡張機能やBurp Suiteなどを使った手動確認が有効です。ペネトレーションテストを外部委託する場合も、SAMLエンドポイントをテスト範囲に含めるよう明示的に指定してください。

本記事のまとめ
SAMLは企業SSOの根幹を担う仕組みですが、XMLの複雑さに起因するさまざまな脆弱性が存在します。主な脅威と対策を以下の表にまとめます。
| 脆弱性の種類 | 主な影響 | 対策の優先度 |
|---|---|---|
| XML署名ラッピング攻撃(XSW) | 任意アカウントへの認証バイパス | 高(最優先) |
| コメントインジェクション | 別ユーザーとしての認証成功 | 高 |
| リプレイ攻撃 | 傍受した認証情報の再利用 | 高 |
| XXEインジェクション | 内部情報漏洩・SSRF | 高 |
対策の核心は「SAMLライブラリを最新に保つ」「署名検証を必須化する」「有効期限とInResponseToを厳格に検証する」の3点です。クラウドIdPを使っている場合でも、SP側の実装と設定は自社責任であることを忘れないでください。
SSOの認証基盤は攻撃者にとって魅力的なターゲットです。定期的な設定確認とライブラリのアップデートを習慣にすることで、リスクを大幅に低減できます。
PR
体系的に学ぶ 安全なWebアプリケーションの作り方 第2版(徳丸浩/SBクリエイティブ)
SAMLを含む認証・認可の仕組みからSQLインジェクション・XSSまで、Webアプリケーションのセキュリティを体系的に解説した定番書。実装レベルの理解を深めたいエンジニア・情シス担当者におすすめです。
