本文へ
ハクソク

世界を動かす技術を、日本語で。

SAML: 悪いデザインのフラクタル

元記事: 原文(blog.trailofbits.com)

概要

  • SAML は学術界と企業ITで普及した認証プロトコル
  • 複雑性とXML依存 が最大の欠点
  • セキュリティ脆弱性 が解消されず、時代遅れに
  • SSO業界の発展 を支えたが、現代の要件に合わない
  • OpenID Connect (OIDC) など新世代プロトコルへの移行が推奨される

SAMLの誕生と普及

  • SAML(Security Assertion Markup Language) は2002年、OASISの技術委員会で策定
  • XMLベースの認証プロトコル として、学術界・企業IT部門で広く利用
  • Webサービスの普及 とともに、SSO(シングルサインオン)業界の基盤となった
  • 主要な認証プロバイダー (Ping Identity, OneLogin, Okta, Duo Securityなど)はSAMLを採用
  • 学術界発のプロジェクト (CAS, Shibboleth, ADFS, simpleSAMLphpなど)もSAMLをサポート

SAMLの致命的な欠陥

  • XML署名検証の複雑さ が最大の弱点
    • XML Signature Wrapping(XSW)攻撃など、脆弱性が多数報告
    • XML自体のセキュリティ問題(XXE, エンティティ拡張, DTD, XPath/XQueryインジェクション等)
  • カノニカライゼーション(C14N) の難しさ
    • XMLの表現が一致しないと署名検証が失敗
    • パーサ差異やラウンドトリップバグにより攻撃が可能
  • エンベロープ署名 の設計ミス
    • 署名要素がデータ内部に埋め込まれることで、改ざんやバイパスが容易
  • 「キッチンシンク」設計
    • 仕様が肥大化し、現場で使われるのはごく一部
    • ほとんどの実装が仕様の90%以上を無視
  • オシフィケーション(硬直化)
    • 時代遅れの設計思想
    • HTTP/TLSや現代的なWeb通信への適応が不十分
    • 柔軟性がバグの温床となり、保守性が低下

SAMLと現代プロトコルの比較

  • SAMLはXML依存、OIDCはJSON/JWTを活用
    • XMLはタグ・属性・名前空間など複雑で、実装・解析が難解
    • JSONはシンプルでセキュリティリスクが低い
  • OIDCはHTTP前提、SAMLはトランスポート非依存
    • OIDCはHTTPSにより暗号化・信頼性を担保
    • SAMLは柔軟性の裏返しで実装の標準化が難しい
  • OIDCはアジャイル的進化、SAMLはウォーターフォール的設計
    • OIDCは実用ニーズに応じて仕様が追加され拡張性が高い
    • SAMLは設計時点で全てを盛り込み、時代の変化に追従しづらい

SAMLの今後と推奨アクション

  • SAMLはもはや時代遅れ、新規導入は推奨されない
  • OpenID Connect (OIDC) や OAuth 2.0 など、現代の要件に合ったプロトコルへの移行が望ましい
  • 既存SAMLシステムの運用 は最小限にとどめ、セキュリティパッチの適用・監査を徹底
  • 新規開発・導入時はOIDC/JWTベース を標準とすることが推奨

まとめ

  • SAMLはSSO業界の発展に貢献 したが、 複雑性 と セキュリティ課題 により限界
  • OpenID Connectなど現代的なプロトコル への移行が、セキュリティ・運用性の両面から最適解

提供: ハクソク · 要約更新:

AIによる日本語要約です。内容は原文とあわせてご確認ください。

Hacker Newsの議論を読む

Hackerたちの意見

SAMLは、記事が言ってるよりもひどいよ。署名が実際に何をサインしてるのかを確認しなきゃいけない問題とかね。でも未来には期待してるよ。一般的なXMLパースみたいな多機能ライブラリに頼るんじゃなくて、SAMLのサブセットと上位約10社のダイアレクトだけをサポートすればいいと思う。極端なニッチプロバイダーは、その都度必要に応じて追加すればいいし、取引規模が大きければやる価値があるよね。

└

… 署名が実際に何をサインしてるのかを確認しなきゃいけない。つまり…署名をどうやって確認するつもりなの?署名を検証するためのデータが必要だよね。

└

よくテストされていて、きちんと書かれたライブラリで、(良い)SAMLのサブセットだけをサポートしている例って何かある?

「おお!マークアップ言語だ!マークアップ言語で何を解決できるかな!」っていう感じの産物だよね。認証は、ただの文書やデータストリームでマークアップが必要なわけじゃないのに。記事はこれをXMLに結びつけてるけど、確かにその時は何にでもハンマーのように使われてたと思う。でも、この問題はまだ解決してないと思う。OIDCはGoogleや他の企業のために多くの前提を持ってるし、tailscaleも「ラインを守ってる」って言ってるけど、GitHubアカウントみたいに他と違う扱いをしなきゃいけない時に亀裂が見えちゃうよね。私たちが欠けてるのは、プロバイダーに依存しない方法だと思う。自分が管理するバックエンドを使って、どこでもアカウントを作ってログインできるべきだよね。実現可能だけど、今のやり方では無理だね。

└

それが元々のOpenID(LiveJournalの時代のやつ)でしょ?「自分のアイデンティティをホストする」ってやつ。

└

OpenID Connectは、フェデレーテッドログインをサポートするための仕組みを、動的発見や動的登録の仕様の一部として持ってるんだ。でも、誰もそれを使ったり実装したりしないのが問題。小さなテック企業はフェデレーテッドログインを望んでないし、基本的にSSO税に頼ってエンタープライズ顧客をアップセルするのが好きなんだ。大手認証企業もフェデレーテッドログインが進むのを望んでない。競争相手が増えて、彼らの異常な利益率が脅かされるからね。ビジネス面が解決されるまでは、どんなに技術が改善されても何も変わらないと思う。OpenID Connectのいくつかの小さな相互運用性のギャップは、関係者が本気で取り組めば数ヶ月で修正できるはずだよ。

└

自分が管理するバックエンドを使って、どこでもアカウントを作ってログインできるべきだ。実現可能だけど、今のやり方では無理だね。IndieAuthは存在してるけど、広くサポートされてないんだよね。

└

記事が指摘してるように、SAMLがJSONを使ってないことを批判するのはちょっと不公平だよね。だって当時、JSONなんてほとんど存在してなかったし。構造化データのシリアライズされた表現が必要だったら、必要以上に機能が豊富でもXMLを使うのがエンジニア的には理にかなってたと思う。代替案はASN.1か、自分でゼロからフォーマットを作ることだったけど、それが本当に良いとは言えないよね。(自分でフォーマットを作るのがXML特有のセキュリティ問題に対して脆弱じゃないって理由で賛成することもできるけど、その問題が当時は十分に理解されてなかったと思う。もし理解されてたら、特定の問題を引き起こす機能を無効にした準標準的な安全なXMLのバリアントが考案されてたかも。)XMLは、セキュリティに関わるミス機能がなくても、マークアップ言語が必要ない大多数のユースケースにはJSONや他の非マークアップ言語のシリアライズフォーマットより劣ってると思うけど、これは大した問題じゃない、基本的にはただの構文の問題だよね。

└

本当の問題は、eXtensible Markup Languageを使っておきながら、すでにその言語のコア機能である内側の拡張性の構文を自分たちで作り出したことだよ!名前の最初の単語なんだから!「JSONを使う」みたいなもので、実際には自分たちが作ったオブジェクト表記を通じて間接的にオブジェクトをエンコードしてる感じ…それが構造化されてるんだ。

└

原則的にはそれができるよ。ほとんどの非エンタープライズツールはそれをサポートしてないけど、単にIdPが欲しいわけじゃなくて、アンチスパムや評判管理、アカウント回復のアウトソーシング、大量ユーザー作成の制限を行うIdPが欲しいんだよね。誰でもいつでも自分が誰かを証明できるなら、ユーザー名とパスワードだけで済ませられるのに。

└

認証って、ただの文書やデータストリームじゃないんだよね。ここでちょっと混乱しちゃった。KerberosやOAuth(特にJWT)を使った経験からだけど、JSONのことを言ってるんだ。もし「マークアップ」って言うのが「XMLはダメ」って意味なら、それには同意するよ。Kerberosには「マークアップ」みたいなものがあって、主題に関する便利なメタデータを運ぶための型付きの穴があるんだ。特に「authorization-data」って呼ばれるものね。でも、a) KDCに便利なサイトローカルの情報を含めさせるのは本当に面倒くさいし、b) Kerberizedサービスがその認可データにアクセスできるようにするのは驚くほど難しい!(b)は意外だよ。しばらくその問題に取り組んでたけど、Kerberosに関してはたくさんの作業をしてきた。でもAPIはたくさんの作業が必要で、CだけじゃなくてJavaやPythonなど、いろんなことが絡んでくるから、最後の部分は橋渡しに大量の作業が必要なんだ。結局、アプリケーションがデコードしなきゃいけない{何らかのデータ型ID, それに応じてエンコードされたデータ}の山ができちゃう。だから、次のことをしなきゃいけない: - サイトローカルのauthzデータの構文/エンコーディングを指定する - KDC側のコードを書く(できればプラグインだけで) - RFC 6680を実装する - いろんな言語のバインディングを含める - アプリで使うためのauthzデータデコーダーを実装する - そのアプリでデコーダーを使う これが終わらないんだ。で、JSONと比べてみると、署名やMACの検証、トークンの復号が終わったら、今度はクレーム用のJSONテキストが手に入る。トークン発行者にサイトローカルのクレームを注入するのは簡単だし、アプリで使うのももっと簡単(JWTバリデーターがあればね、そうじゃなきゃ署名の検証を忘れると簡単すぎるけど!)。JWTはこれをうまくやった。Kerberosは間違えた。Kerberosを擁護するなら、これは80年代中頃から後半にかけてのもので、GSS-APIは90年代初頭から中頃にかけてのものだから、30年以上、40年以上前の話なんだ。すべてJSONやXMLが登場する前のことだけど、2026年の今、Kerberosは擁護できない。Kerberosはまだ必要だけど、便利なアプリケーションプロトコルやその実装のための仕様がたくさんあるし、Active Directoryのためにも必要なんだ。このことから学んだのは、GSS-APIが00年代中頃にはgss_accept_sec_context()のバージョンを成長させて、JSONテキストを出力する必要があったってこと。あの頃に戻ってそれを作りたかったな。だから、認証コンテキストのメタデータ、特に認可に役立つメタデータは「マークアップ」言語、特にJSONで表現できるし、すべきだと思う。

私のお気に入りのSAMLの恐怖話は、以前はxmlsigのC実装がデフォルトで、指定された公開鍵で署名をチェックするだけじゃなくて、以下のこともしてたってこと。- 攻撃者が制御する文書に指定されたパスワードを使ってHMACでチェックする。- ウェブPKIを使って署名をチェックする(だから攻撃者は自分のドメインのTLSキーでSAML文書に署名しても、常に有効と見なされる)。正直、SAMLを使ってるサイトが常にハッキングされてないのが不思議だよ。ひどい基準よりもひどい実装の方が問題だね。

Hacker Newsで議論の続きを見る

同じ出典の記事