2024年3月2日土曜日

なぜSAMLの脆弱性は今でも報告されるのか。そしてOIDCやVCは大丈夫なのか

こんにちは、富士榮です。

故Craig Burtonが”SAML is Dead”という名言を放ってから永らく経つわけですが、まだまだ現役のSAMLには今でもたまに脆弱性のレポートが出てきます。

* SAML is Dead


昨日もSilver SAML Attackに関するレポートが出ていました。

(図は記事より)

非常にざっくり要約すると、以下のようなことが書かれています。

  • 例としてEntra IDを挙げている
  • Entra IDではSAML Responseへの署名を行う秘密鍵として外部で生成した鍵を利用することができる(BYOK)
  • この鍵が漏洩するなどして不正に利用されるとSAML Responseの偽造ができてしまう
  • 署名に使う鍵はIDシステムの内部で発行したものを使った方が良い
当たり前じゃん。秘密鍵が奪われているんだから。

と言いつつ、何でこう言うことが起きるのかをちゃんと見ていきたいと思います。

脆弱性の原因

SAMLに限らず、ではありますがこの手の仕組みの基本は「デジタル署名を施したデータ(SAML AssertionやOpenID Connectにおけるid_tokenなど)」をIdentity ProviderからRelying Partyからの要求等に応じて送出する、という仕組みになっています。
こうなってくると当然のことながらデジタル署名を確実に実施・検証する、そして先日から順番に読んでいるOAuth2.0 Security Best Current Practiceにも要所要所でててくる、送信元・送信先をいかに限定するか、やり取りの過程の中でCSRFなど攻撃者によるインジェクションをいかにして防ぐか、などがポイントになってきます。
  • 署名・検証の不備を防ぐ
  • 通信過程における攻撃者の関与を防ぐ
後者についてはOAuth2.0 Security Best Current Practiceで見ていくとして、今回は先のSAMLの件もあるのでデジタル署名について見ていきたいと思います。

デジタル署名の前提

デジタル署名を安全に行うための前提は言うまでもなく署名に使う鍵を安全に管理すること、につきます(もちろんアルゴリズムの安全性の話は言うまでもありません)。
今回挙げたケースは鍵を適切に管理できない状態が起きると危ないですよ、というレポートなので、改めて秘密鍵の管理の重要性を説いています。
(もちろん、安全に管理してくださいね、と言ったところで安全に管理できない人たちが多いのは理解していますが、管理方法について深掘りするのはここでは避けます)

なお、今回は鍵管理の話にフォーカスが置かれていましたが、実際の脆弱性はデジタル署名する対象となるデータの生成に依存することが多いと思います。いわゆる「正規化」の問題です。

実際過去に当ブログでも紹介したDuo SecurityのレポートはSAML Assertionを生成する際のXMLの正規化がポイントでした。

正規化の問題

SAMLにおけるXMLは非常に柔軟なデータ表現である一方で「どうやって同一性を担保するか」という問題を抱えています。
例を挙げると、
  • 空白値のトリミング
    • <attribute name="email">test@example.jp</attribute>
    • <attribute name="email"> test@example.jp </attribute>
    • を同一のものとして扱うか
  • コメントの取り扱い
    • <!-- これはコメントです -->
    • <attribute name="email">test@example.jp</attribute>
    • <attribute name="email">test@example.jp</attribute>
    • を同一のものとして扱うか

    と言う問題です。
    これらを解決するために行われるのが「正規化」です。

    XMLの正規化はW3CのCanonical XML Version 2.0で定義されています。

    実際に正規化をする際はこの仕様に従いXMLを処理していくことになるのですが、この過程においてバグが混入することがある、というのが問題の原因になっています。
    実際、先に挙げたDuoのレポートでは値の間にコメントがあった場合の処理に問題があり、別のユーザで認証され生成されたSAML Assertionを使って別のユーザになりすますことができてしまう、というものでした。


    OIDCやVCではどうなのか?

    こう考えるとJSONを使うOpenID Connectや、JSONやJSON-LDを使うVerifiable Credentialsはどうなのか?という疑問が湧いてきます。

    まずOpenID Connectですが署名付きJSONトークンにはRFC7515 JWS(JSON Web Signature)を使っています。

    崎村さんが経緯をブログで紹介されていますが、SAMLの正規化との戦いの経験から「JWSでは正規化を行わない」のがポイントの一つになっています。

    Verifiable Credentialsについてはどうなのか、というとIETFのSD-JWT VCをパターンではOpenID Connectと同じくJWSなので正規化は行いません。
    しかしながらW3C VCはJSON-LDも許容するのでこちらは考えないといけません。JSON-LDはRDF(Resource Description Framework)に基づくLinked Dataを表現するフォーマットですので、正規化をするには、
    を使っていく必要があります。
    しかしながらこの正規化で使われるアルゴリズムであるUniversal RDF Dataset Normalization Algorithm 2015(URDNA-2015)をJSON-LDに適用する際の注意点についてレポートが上がっていたりしますので、実装者はかなり気を遣う必要がります。
    実際、昨年のIIWでもJSON-LDのプロパティ名を変えても署名が崩れないというデモ(Linked Dataの性質を考えると当然の動きではありましたが)もありましたが、VCとして使うにはこのようなことが起きないように注意深くデータ構造を設計する必要があります。

    しかし、この辺りの議論を見ているとJWSが「正規化を行わない」という判断をしたのは非常に重要なことだったことがわかりますね。


    0 件のコメント: