SAML:悪しき設計のフラクタル
SAML: A Fractal of Bad Design (blog.trailofbits.com)
要約
SAMLは、その複雑さとXML基盤に起因する多くのセキュリティ上の欠陥により、現代の認証プロトコルとしては時代遅れであると論じられています。学術界と企業IT部門で広く採用されてきたSAMLですが、XML署名ラッパー攻撃などの脆弱性が存在し、OpenID Connect(OIDC)のようなよりモダンでシンプルな代替手段への移行が推奨されています。
全文翻訳
SAML: 悪しき設計のフラクタル
学術界で生まれ、企業のIT部門で育てられたSAML(Security Assertion Markup Language)認証プロトコルは、これらの組織で引き続き定番となっています。しかし、もはや引退の時期です。2000年代後半のソフトウェア・アズ・ア・サービス(SaaS)企業の台頭に伴い、IT部門は多くの新しいWebサービスへのユーザー認証方法を必要としていました。SAMLと、勃興しつつあったシングルサインオン(SSO)業界がこのニーズを満たしました。しかし、SAMLはその複雑さの重みに押しつぶされつつあります。今こそ、それを非推奨にし、OpenID Connect(OIDC)のようなモダンな代替手段へ移行すべき時です。この記事では、SAMLの委員会による設計の起源、学術的および企業環境での昇進、セキュリティ研究コミュニティによるゆっくりとした解体、そして新しいプロトコルを支持する(期待される)非推奨について探求します。
[画像: “SAML 101”]
SAML 101
SAMLのたちの悪いところは、理解するのはほとんど単純明快なのに、砂と骨粉と灰の上に築かれていることです。それは機能します…XML署名検証が信頼できると仮定するならば。しかし、XML署名検証は深く呪われており、あまりにも複雑なため、ほとんどの運用されているSAML実装は、誰も読まない厄介なCコードベースであるlibxmlsecをラップしています。
— Thomas Ptacek, 2023
SAMLとSSO業界の誕生
Wikipediaによると、「SAMLはセキュリティアサーションのためのXMLベースのマークアップ言語です。」これは2002年にOASIS(Organization for the Advancement of Structured Information Standards)のSecurity Services Technical Committee(SSTC)によって作成されました。現代の基準では、良いスタートとは言えません。XMLは、いくつかの評価できる側面があるにもかかわらず、JSONのような新しい代替手段と比較して非常に複雑ですが、これについては後でもっと掘り下げます。さらに、小委員会の委員会が会議を開くというのは、「キッチンシンク」的なプロトコル設計(例:ウォーターフォールモデル、ビッグデザインアップフロントなど)のレシピです。そして案の定、私たちは4つもの!XMLベースのセキュリティプロトコルを1つに詰め込んでしまいました:
…以下の知的財産がSSTCに寄贈されました:
- NetegrityからのSecurity Services Markup Language(S2ML)
- SecurantからのAuthXML
- VeriSignからのXML Trust Assertion Service Specification(X-TASS)
- JamcrackerからのInformation Technology Markup Language(ITML)
しかし、このようなプロトコルへの欲求は否定できませんでした。インターネットが90年代のWeb 1.0から2000年代初頭のWeb 2.0へと移行するにつれて、ユーザーと組織は多くの新しいWebサービスに簡単に認証する方法を必要としていました。学術界がこの運動の最大の推進力でしたが、唯一の推進力ではありませんでした:2002年のイェール大学のCentral Authentication Service(CAS)、2003年のInternet2(私の母校を含む研究大学のコンソーシアム)によるShibboleth IdP、2003年のMicrosoftによるADFS、そして2007年頃の学術界と密接な関係を持つノルウェーの国営企業UninettによるsimpleSAMLphp。これらの認証プロジェクトはすべて、最終的に何らかの形でSAMLをサポートしました。その前のARPANETのように、大学はインターネット開発の最前線にあり、Webサービスの最初の消費者でした。このプロトコルの可用性と初期の学術的な検証基盤という基盤が確立されると、商業産業はそれを引き継ぎ、数十億ドル規模の産業へと発展させました。
SSO、ID、認証プロバイダー業界も2000年代初頭に始まりましたが、数年後に本格化しました:Ping Identity(2002年)、OneLogin(2009年)、Okta(2009年)、Duo Security(2010年)。これらの企業は、Duoが2015年に最初のSSO製品を導入した(私が物語に関わるようになった時期です)ことを除けば、基本的にSAMLプロトコル上に構築されていました。私はDuoの最初のオンプレミスAccess Gateway製品(DAG)で作業しており、それはsimpleSAMLphp、そして明らかにSAMLプロトコル上に構築されていました。そこで私はSAMLプロトコルに精通し、その長い仕様書を何年もかけて消化しました。Kelby LudwigがXMLコメントバイパスを発見したとき、私はそこにいました。しかし、さまざまな攻撃とSAMLの欠陥については後で触れます。SSOおよび認証プロバイダー業界は隆盛を極め、その多くがSAMLプロトコル上に構築されていたと言えば十分でしょう。
甲羅のひび割れ
XML署名ラッパー(XSW)攻撃は、SAMLの踵に突き刺さった比喩的な矢です。署名ラッパー(2005年、2008年、2009年)とSAML(2008年)の両方に関する初期のセキュリティ研究はありましたが、私はそれらすべての大黒柱を「On Breaking SAML: Be Whoever You Want to Be」(2012年)だと考えています。それは理論を実践に対してテストし、XSW攻撃をチェックする自動化された方法をもたらしました。DAGを実装する際の私たちの北極星でした。simpleSAMLphpをビルディングブロックとして選択した理由です。PHPは、特に当時、セキュリティ実績で特に知られていたわけではありませんでしたが、simpleSAMLphpはその点で際立っていました。simpleSAMLphpは、誰もその意味を本当によく理解していなかった時期に、XSWに対して回復力がありました:
[画像: simpleSAMLphp’s security track record (credit: On Breaking SAML)]
simpleSAMLphpのセキュリティ実績(出典:On Breaking SAML)
2012年のこの論文で前面に出されていたにもかかわらず、XSWは今日でも存在しています。バグクラスを知っているなら、なぜ修正できないのでしょうか?しかし、SAMLの欠陥に入る前に、まずそれが構築された不安定な地面、つまりXMLを考慮する必要があります。
XMLは、セキュリティ実績(またはその欠如)に関して決して楽観的ではありません。これらのバグクラスは90年代の開発者にはより馴染み深かったかもしれませんが、それでも今日のXMLに存在します:XXE、エンティティ展開(「ビリオンラフ」)、DTD取得(SSRF)、XPath/XQuery/XInclude/XSLT/CDATAインジェクションなど。SAMLライブラリは、実際のSAML機能に到達する前に、これらのバグクラスすべてを処理する必要があります。
セキュリティバグクラスに加えて、JSONのようなものと比較した場合のXMLの単純な複雑さもあります。XMLには、タグ、要素、属性、コメント、名前空間、マークアップ対コンテンツ、スキーマ、CDATA、DOCTYPEなどがあります。JSONには、基本的にキー、値、オブジェクト、リストがあります。複雑さは一般的にセキュリティと相反しており、これが私がSAMLを悪しき設計のフラクタルと考える理由の1つです。
SAMLはプロトコル設計について学ぶための十分な機会を提供します。このセクションでは、認証プロトコルとしてのSAMLの長期的な存続可能性を致命的だと私が考える5つの欠陥について説明します。これらの欠陥は、新しい認証プロトコルを設計する際にも使用できます。つまり、欠陥を回避するか、その逆を取り入れてプロトコルに組み込もうと試みることができます。
XML上に構築
前述のように、SAMLはXML上に構築されており、XMLは複雑ですが、それは委員会のせいではありません。XMLは当時彼らが持っていたものであり、人々が使用していたものでした。JSONは2001年に「発見」されましたが、これはSAML委員会が会議を開いていた頃であり、実験的な新しいフォーマットを中心に認証プロトコルを設計する可能性は低いです。特にJavaScriptを対象としている場合、そしてあなたが多くのJavaを書いている場合。
XMLとJSON、またはSAMLとJWT/OIDCの定量的な複雑さの測定(例:仕様/RFCの単語数、仕様/RFCの正規表現の単語数など)を設計することは可能ですが、それはブログ記事または論文全体を必要とするでしょう。トピックに沿って進むために、ここではそれを控えます。XMLはJSONのようなものよりも大幅に複雑であると言えば十分です。
正規化(Canonicalization)
正規化(C14N)とは、XMLのワイルドな混乱を取り込み、そのハッシュを計算し、一貫した結果を得たい場合に行うことです。言い換えれば、SPとIdPが一貫したXMLデータの表現に合意できない場合、バイトが一致せず、署名が一致せず、認証が失敗します。しかし、これは言うは易く行うは難しです。
正規化のバグにより、2018年にKelbyのXMLコメントバイパスが可能になりました:
[画像: XML canonicalization (credit: Identity Theft)]
XML正規化(出典:Identity Theft)
正規化は、多くの場合、パーサーの差分または「ラウンドトリップ」バグの前兆となります。これは、ほとんどの最新のSAML攻撃が使用するものです:
- Goの標準ライブラリにおけるXMLラウンドトリップ脆弱性の協調開示(2020年)
- Web全体でのXML実装の保護(2021年)
- GitHub EnterpriseでのSAML認証バイパスのためのlibxml2の癖の悪用(2025年)
- 誰でもサインイン:パーサーの差分によるSAML SSO認証のバイパス(2025年)
- SAMLルーレット:ハッカーが常に勝つ(2025年)
- 壊れやすいロック:SAML認証の新しいバイパス(2025年)
包み込む署名(Enveloped signatures)
包み込む署名の懸念は、正規化の遠くないいとこです。要するに、署名を署名しているデータペイロードに挿入しようとしている場合、それは悪い結果になるでしょう。この点でJWTとSAMLを比較対照してみましょう:
[画像: JWT versus SAML signatures (credit: jwt.io and samltool.io)]
JWT対SAML署名(出典:jwt.ioおよびsamltool.io)
上記のJWTの例では、青い署名はJSONペイロードから切り離されており、ピリオド(「.」)でJWT内に区切られています。SAMLの例では、Signature要素はAssertion要素内に挿入(「包み込まれて」)います。問題は、データを変更している場合に、バイト単位で正規化等価な表現を得ることが非常に難しいということです!さらに、XMLのような複雑なフォーマットと複雑な正規化ルールがある場合はなおさらです。
「キッチンシンク」設計
この設計上の欠陥は、基本的に「必要ないものは必要ない」(YAGNI)に転化します。これは完全に公平な特徴付けではありません。なぜなら、現実世界で使用されているSAML仕様の部分は過去20年間で変化してきたからです(残念ながら、SOAPとアーティファクトバインディング)。しかし、事実として、現代のSAML実装の99%は非常に類似したデータ形状と仕様のサブセットを使用しています。今日一般的に遭遇するSAML認証のほとんどは、仕様の90%を回避しているでしょう。これは、ほとんど使用されない機能に対してかなりの複雑さを加えています。
もし私が新しいものにSAMLサポートを追加するなら、すべての標準的なSAMLチェックを超えて、Okta、Onelogin、Google、またはShibが生成するものと同じ形状を持たないメッセージを拒否することも検討するでしょう。
— Thomas Ptacek, 2021
硬直化(Ossification)
SAMLは異なる時代のために設計され、異なる時代に対応してきましたが、必要な更新を受けていません。これらの懸念は、一般的に理論的なものよりも実践的な意味合いを持ちます。硬直化(ossification)と私が呼ぶものは、大まかに以下のものとして列挙できます:
- OIDCはHTTPを想定していますが、SAMLはトランスポートに依存しません。 確かにSAML HTTPバインディングは存在し、最も一般的に使用されていますが、必須ではありません。これはSAMLにある程度の柔軟性を与えますが、その柔軟性は明確に定義され、どこかに実装され、バグを含む可能性があることも意味します。SAMLは、HTTP + TLSがまだWebサービス通信の主要なバックボーンではなかった時代に登場し、この現代の状況と和解していません。HTTPSにより、OIDCは暗号化された信頼性の高い通信をトランスポート層に委ねることができます。
- OIDCは一般的に接続されたネットワークトポロジーを想定していますが、SAMLはそうではありません。 最も一般的なOIDCフロー(認可コード)は、OpenID Provider(OP)とRelying Party(RP)が直接通信できることを想定しています(OIDC OP/RP == SAML IdP/SP)。確かに、OIDCのフォームポストによるインプリシットフローは存在しますが、今日それを見ることは非常にまれです。さらに、SAMLには直接通信のためのアーティファクトバインディングがありますが、それも非常にまれです。要点は、OPとRPが直接通信できる場合、認証および認可の決定を行うために必要なすべての情報を含む認証応答ペイロードにかかる圧力を軽減することです。これにより、ペイロードサイズと複雑さが軽減されます。代わりに、OIDC OPとRPはバックチャネルで情報を交換できます。
- OIDCは長年にわたって有機的に成長しましたが、SAMLは大部分が事前に設計されました。 OIDCは、将来のすべてのニーズを予測して事前に構築するのではなく、特定のニーズを解決するために作成された数十の仕様とRFCを網羅しています。これは、最初のセクションで説明したアジャイル開発手法とウォーターフォール開発手法に似ています。以下の非網羅的なタイムラインを検討してください:
- OpenID Connect 1.0仕様発行(2014年)
- JOSEスタックがRFC 7515-7519を通じてJW{S,E,K,A,T}のために最終化(2015年)
- PKCEがRFC 7636を通じて発行(2015年)
- モバイル/ネイティブアプリ向けのPKCEがRFC 8252を通じて発行(2017年)
- IoTデバイス向けのデバイス認可グラントがRFC 8628を通じて発行(2019年)
- MFAワークフローのための証明書所有権証明(DPoP)がRFC 9449を通じて発行(2023年)
- SPA向けのPKCEがRFC 10017を通じて発行(2026年)
歴史的状況も興味深いと思います。例えば、SAMLはVPNとネットワークセグメンテーションの時代に成熟しました。そのため、上記のポイント(2)が挙げられます。IdPまたはSPが企業のファイアウォール内にあり、もう一方の端と直接通信できない場合、ロールアウト全体が停止し、そのベンダーは販売契約を失いました。SAMLはこの状況をシームレスに考慮する必要がありました。GoogleのBeyondCorpモデルとゼロトラストアーキテクチャは、2014年にこの概念を覆しました。さらに、SAMLはモバイル、SPA、IoT革命を予期できず、これらの技術が2000年代後半に登場したときに対処法がありませんでした。SAMLは依然として企業環境で広く採用されていますが、これらのマクロな出来事は、プロトコルの長くゆっくりとした衰退の始まりを助けました。アジリティと疎結合は、絶えず変化するIT環境での迅速な適応を可能にします。
すべての道はOIDCへ続く
完璧なプロトコルはありませんが、解決策という点ではすべての道はOIDCへ続いています。私が知る限り、SAMLが有利だった唯一のデプロイメントシナリオは、SPとIdPが直接通信できないネットワークでした。OIDCのフォームポストによるインプリシットフローは、同じ要素をすべて提供します。これは、業界で利用可能な最もクリーンな移行計画の1つです。
では、サービスプロバイダー(つまりSP)として、SAMLなしでSSOエコシステムに統合したい場合、どうすればよいでしょうか?OIDCをサポートしてください。SAMLを放棄してください。Fly.ioとTailscaleはすでにそれを行っているようです:
私たちはこれまでOIDCのラインを維持することに成功してきました。Tailscaleも同様です。Tailscaleがそのラインを維持できるなら、彼らが誰に販売しているかを考えると、ほとんどの組織ができると思います。本当に、SAMLを行うことを避けてください。ベンダーとして、あなたはしばしば、実際のSSO統合を全く行わない企業と競合していることを覚えておいてください。
— Thomas Ptacek, 2024
では、IDまたは認証プロバイダー(つまりIdP)として、SAMLから移行したい場合、どうすればよいでしょうか?さて、顧客数によっては、これは本当に長い道のりかもしれません。しかし、象をどうやって食べるか知っていますか?一度に一口ずつです。これは業界でよく知られた道です:非推奨計画を開発し、顧客に伝え、新しい顧客のSAML統合へのオンボーディングを停止し、既存のSAML顧客に同等のOIDC構成を提供し、終了日を設定し、作業に取り掛かります。
SAMLは25年間の良いキャリアを過ごしました。SSO業界を誕生させ、数え切れないほどの認証を保護し、数十のWebサービスへの認証のUXを改善し、数十億ドルの経済的影響を生み出しました。SAMLプロトコルの作成者には感謝すべきです。それは、テクノロジー業界の非常にダイナミックな期間におけるプロトコル設計と進化の素晴らしいケーススタディを提供してくれました。
セキュリティトピックの歴史的分析についてさらに読むには、「Marshal madness: A brief history of Ruby deserialization exploits」をご覧ください。
プロトコル設計監査に興味がある場合、または認証システムのレビューを希望する場合は、お問い合わせください。