何が起きるか
OAuthやSAMLの連携では、外部から返る本人情報やアクセス権を、信頼する発行元、受取サービス、利用者が開始した操作へ結び付けて検証します。この対応が欠けると、正規の情報を使っていても別人としてログインさせる場合があります。
アカウント連携の説明用に、認可コードをURLで返す方式を考えます。攻撃者は自分の外部アカウントで連携を許可し、コードを含むサイトの戻り先URLを、まだ使用されていない状態で入手します。そのURLを被害者に開かせると、被害者のブラウザがコードをサイトへ送ります。サイトが連携開始時の記録と照合せず、現在ログイン中の被害者へ対応付けると、攻撃者の外部アカウントが被害者のサイト内アカウントへ登録されます。次のログインでこの対応を使う構成なら、攻撃者は自分の外部アカウントで被害者の情報を読めるおそれがあります。
SAMLでは、署名を検証する処理と、ログイン対象を選ぶ処理が、同じXML内の別々の本人情報を選ぶ問題があります。例えば、有効な署名で保護されたユーザーIDとは別に、攻撃者が変更できるユーザーIDを置ける構成です。検証器が前者を確認しても、ログイン処理が後者を採用すれば、署名を偽造せず別人のセッションを発行させるおそれがあります。
正常ならどう動くか
OAuthの認可コード方式では、連携アプリが利用者のブラウザを外部サービスの認可画面へ移動させます。利用者がAPI利用を許可すると、外部サービスは短時間有効な認可コードを付けた戻り先URLへブラウザを戻します。サーバー型の連携アプリでは、アプリのサーバーが受け取ったコードを外部サービスの認可サーバーへ送り、アクセストークンへ交換します。そのトークンをAPIへ提示して、許可された情報を取得します。
連携開始時には予測困難なstateをアプリのセッションへ保存し、認可要求にも入れます。戻った応答のstateと照合すれば、別の利用者が開始した応答を取り込むことを防げます。ログインにOpenID Connectを使う場合は、認証結果であるIDトークンの署名、発行元、受取先、有効期限や要求との対応を検証し、発行元とユーザーIDの組からサイト内の利用者を決めます。APIへのアクセス権を示すアクセストークンだけで、任意のサイトの本人確認を行うものではありません。
SAMLでは、組織などが運営する認証サービスであるIdPで利用者がログインします。IdPは本人情報に秘密鍵で署名し、ブラウザ経由で連携先サービスへ渡します。サービスは設定済みのIdPの公開鍵で、情報がその鍵に対応する署名者によって署名され、署名対象が改変されていないことを確認します。発行元、受取先、期限、開始したログイン要求との対応も確かめ、検証した情報内のユーザーIDを採用します。
不備と攻撃が成立する流れ
アカウント連携では、攻撃者の認可コードを含む戻り先URLを被害者が開き、サイトが開始時のセッションやstateと照合しないと、攻撃者の外部アカウントを被害者へ登録する場合があります。別の問題として、連携アプリが認可要求のredirect_uriへ指定する戻り先を、認可サーバーが登録済みURLと厳密に比較しない欠陥があります。攻撃者がこの値を自分のサーバーのURLへ変えた要求を利用者に許可させられると、コードなどを含む応答が攻撃者へ送られるおそれがあります。
SAMLの例では、XML内に複数の本人情報があり、検証器が署名対象のユーザーIDを確認しても、ログイン処理が別のユーザーIDを採用すると問題になります。攻撃者が採用側の情報を書き換えられれば、有効な署名を残したまま別人としてログインさせる場合があります。OAuthの操作対応とSAMLの署名対象の不一致は、異なる不備です。
起こり得る被害と条件
誤った連携の例では、攻撃者の外部アカウントが被害者のサイト内アカウントと対応付けられます。サービスがその対応で次のログインを許可すると、攻撃者は自分の外部アカウントで認証して被害者のデータを読めるおそれがあります。
漏えいの例では、攻撃者のサーバーへ届いたアクセストークンを攻撃者がAPIの認証情報として提示します。連絡先の読み取りを許すトークンなら、APIから被害者の連絡先を取得できるおそれがあります。認可コードは、それをトークンへ交換するための一時的な値です。コードだけを盗んでも、交換時にアプリの認証情報やPKCEの秘密の検証値が必要なら、攻撃者はその条件を満たさずトークンを取得できません。
SAMLのなりすましでは、改変したユーザーIDが本人情報として採用され、そのIDの利用者向けのセッションが発行されます。攻撃者がそのセッションで秘密の文書APIへ接続できれば、他人の文書をHTTPレスポンスで入手します。有効な署名付き応答が必要かなどの条件は個別の欠陥によって異なります。
防ぎ方と、防げる理由
OAuthの戻り先URLは登録した値に限定し、認可応答を攻撃者のサーバーへ送らないようにします。stateを使う方式では、連携開始時に予測困難な値をサーバーのセッションへ保存して認可要求にも入れ、戻った応答のstateと照合します。別の操作で作った応答を現在の利用者へ対応付けることを防ぐためです。
PKCEを使うサーバー型の連携アプリでは、アプリのサーバーが開始時に秘密の検証値を生成・保存し、そこから計算したハッシュ値を認可要求へ入れます。認可サーバーはそのハッシュ値をコードと結び付けます。ブラウザ経由でコードを受け取ったアプリは、トークンへの交換時に保存しておいた元の検証値を送ります。認可サーバーが同じハッシュ値になるか確認するため、コードだけを盗んだ相手は交換できません。ブラウザ内で動くアプリなどでは、検証値を管理して交換する主体もそのアプリになります。
SAMLでは、保守されたライブラリが検証して返した署名対象のデータからユーザーIDを採用し、XMLを別に読み直して未検証の要素を選ばないようにします。設定したIdPの鍵、発行元、受取先、期限、開始した要求との対応も確認し、別サービスや別の要求向けの署名付き情報を受け付けません。
よくある誤解
アクセストークンは委任されたアクセス権を示すもので、任意のサービスで本人確認に使える証明ではありません。また、XMLのどこかに有効な署名があるだけでは、ログインに使うユーザーIDがその署名で保護されているとは限りません。
実装の確認点
検証する発行元・鍵・受取先を連携設定から追い、実際に採用するユーザーIDまで確認します。複数組織や複数IdPで設定が混ざらないか、他の操作の応答や使用済み応答を再利用できないかも調べます。
出典・確認範囲
- [1] Web Security Academy: OAuth・SAML連携の不備PortSwigger / 確認日 2026-10-29
- [2] SAML Security Cheat SheetOWASP / 確認日 2026-10-29