よくあるSAMLの脆弱性とその修正方法
Sam Sanoop
2023年12月19日
0 分で読めますSecurity Assertion Markup Language(SAML)は、セキュアなID・アクセス管理を実現するうえで重要な役割を果たすXMLベースのフレームワークです。IDプロバイダー、サービスプロバイダー、ユーザーなど、デジタルエコシステム内のさまざまなエンティティ間をつなぐ信頼できる仲介役として機能します。SAMLの主な目的は、シングルサインオン(SSO)を実現することです。SSOでは、ユーザーは1組の認証情報を使って複数のアプリケーションやサービスにシームレスかつ効率的にアクセスできます。従来のユーザー名とパスワードによる認証と比べて多くの利点がある一方、次の要因によってはSAMLに脆弱性が生じることがあります。
開発者が使用するSAMLライブラリ
開発者が使用するSAML設定
この記事では、よくあるSAMLの脆弱性と、具体例を交えた修正方法を簡潔に解説します。
よくあるSAMLの脆弱性
署名の検証とメッセージ署名
XMLアサーションの検証は、XML改ざん攻撃の防止に役立ちます。SAMLアサーション内のXMLメッセージが本物であることを確認します。XML署名ラッピングは、XML署名の処理方法の弱点を悪用する脆弱性で、データの悪意ある改ざんにつながる可能性があります。
以下の例(VulnerableSAMLApp)では、一般ユーザーとして認証すると、認証後にユーザープロフィールに次の情報が表示されます。

SAMLリクエストを変更し、グループメンバーシップを管理者に変更することで、このユーザーの権限を昇格できてしまいます。


このような問題を修正するには、次の対応が必要です。
アサーションには署名が必要です。アサーション属性に署名が追加され、信頼できる証明書を使って署名されます。
署名がアサーションを含むメッセージ全体のデータと一致することを確認するため、アサーションの値を検証する必要があります。
最新のSAMLライブラリの多くには、メッセージの署名と検証を有効にする設定があります。samlifyでの設定例はこちらをご覧ください。https://github.com/tngan/samlify/blob/master/docs/sp-configuration.md
暗号化の強度不足
SAML認証では、機密データの安全性と機密性を確保するために、SAMLメッセージの一部を暗号化することが重要です。具体的には、ユーザーとその属性に関する情報を含むSAMLアサーションを暗号化する必要があります。これらのアサーションは、ユーザーのIDと権限を確認するために、IDプロバイダー(IdP)とサービスプロバイダー(SP)の間でやり取りされます。
メッセージの有効期限
SAMLメッセージは、デフォルトではリプレイ攻撃に対して脆弱な場合があります。リプレイ攻撃とは、傍受した有効なSAMLメッセージを不正に再利用し、シングルサインオン(SSO)やシングルログアウト(SLO)などの正規のSAML操作になりすます攻撃です。「NotBefore」と「NotOnOrAfter」を使うことで、このような攻撃を防止できます。
NotBefore(属性):この属性は、SAMLアサーションが有効とみなされる最も早い時刻を定義します。つまり、指定された「NotBefore」の時刻より前に、認証や認可にアサーションを使用してはなりません。特に時間に依存する処理では重要となる、アサーションの早すぎる使用を防ぎます。「NotBefore」の時刻より前は、通常アサーションは無効とみなされます。
NotOnOrAfter(属性):この属性は、SAMLアサーションが有効である最終時刻を指定します。「NotOnOrAfter」の時刻を過ぎた後は、認証や認可にアサーションを使用してはなりません。この時間制限により、傍受されたり悪意を持って取得されたりした古いアサーションの悪用を防止できます。
オープンリダイレクト
SAMLは本質的に非同期プロトコルです。SP起点のサインインを開始すると、まずSAML認証リクエストが作成され、IDプロバイダー(IdP)に送信されます。この時点で、サービスプロバイダーはリクエストに関する情報を保持しません。そのため、IdPからSAMLレスポンスを受け取っても、サービスプロバイダーは認証リクエストのきっかけとなった元のディープリンクを把握できません。この問題に対処するため、SAMLには「RelayState」という重要なパラメーターが用意されています。
RelayStateはHTTPパラメーターとして機能し、SAMLリクエストとSAMLレスポンスの両方に含めることができます。SP起点のサインインフローでは、SPはRelayStateパラメーターを使って、SAMLリクエストに追加情報を埋め込めます。これにより、非同期処理の間に重要なコンテキストやデータが失われるのを防ぎます。ただし、このRelayStateパラメーターは、攻撃者に悪用されてオープンリダイレクト攻撃につながる可能性があります。
オープンリダイレクト攻撃を防ぐには、リダイレクトする前にRelayStateの値が信頼できるURLであることを確認してください。以下は、python3-samlライブラリのメンテナーが提供する例です。

まとめ
この記事では、よくあるSAMLの脆弱性とその修正方法をいくつか例を挙げて解説しました。ただし、使用しているSAMLライブラリやIDプロバイダーによって修正方法が異なる場合や、修正できない場合もあります。脆弱性を効果的に防ぐ方法を確認するため、各ライブラリやサードパーティープロバイダーのドキュメントを確認してください。
最後に、SAMLはセキュアなID・アクセス管理のフレームワークを提供しますが、XMLを使わないOpenID Connect(OIDC)もSAMLに代わる有力な選択肢です。OIDCはOAuth 2.0とJWTの上に構築された最新のIDレイヤーです。XMLベースのアサーションの代わりにJSON Web Token(JWT)を使ってID情報を伝達するため、最新のWebアプリケーションやモバイルアプリケーションに適しています。OIDCを使えば統合プロセスを簡素化でき、ユーザープロフィール情報の取得などの機能も利用できます。そのため、XMLセキュリティを扱いたくない開発者にとって魅力的な選択肢です。この記事で紹介した攻撃の多くはOIDCには当てはまりません。OIDCは検討に値する代替手段であり、採用することでSAMLに伴う複雑さの一部を軽減できる可能性があります。



