記事の目的・背景
「OIDCのImplicitフローってIDトークンリプレイ攻撃を防ぎきれないのでは?」という疑念を抱いたので、その仮説を検証するのがこの記事の目的です。
結論
やはり「ImplicitフローってIDトークンリプレイ攻撃を防ぎきれないよね」ということがわかりました。
(異議があればコメントでご教示いただきたいです!よろしくお願いいたします!)
IDトークンリプレイ攻撃とは
攻撃者がクライアントアプリケーションに対して、別のコンテキストで発行されたIDトークンを渡す攻撃。
クライアントアプリケーションによってこのIDトークンが正当なものとみなされると、(クライアントアプリケーションの仕様によるが)攻撃者はクライアントアプリケーションのリソースに対してアクセスできるようになってしまう。
※明確な定義はない模様
OIDCのImplicitフローってどんなんだっけ
OIDCのImplicitフローは下のような感じです。OIDCの仕様書([ OpenID Connect Core 1.0 ] 3.2. Authentication using the Implicit Flow (日本語))をもとに書いてます。
(※骨組みはこちらの記事から拝借しました)
このフローのどこにIDトークンリプレイ攻撃のリスクがある?
リスクがあるのは、上の画像の赤丸の箇所です。
通常、下記の流れでIDトークンリプレイ攻撃を防ぐことができます。
2
でclientがnonceパラメータを生成しそれをAuthentication Requestに付与。またそのnonce値を記憶しておく。
14
でauthentication serverが引き渡すidトークンにそのnocneを含める
16
でnonceを検証する
しかし、例えばリプレイ攻撃で用いるidトークンに含まれるnonce値が123456
だったら、2
のタイミングでnonce値を生成したあとに、記憶領域のnonce値をその値で上書きしてしまえばどうでしょう。
あとは15
のタイミングでidトークンをすり替えてしまえばリプレイ攻撃が成立してしまいます。
「IDトークンのリプレイ攻撃を防ぎきれないのである」という仮説に対する確証
Open ID Connect Core 1.0の原文たる英語版の方でnonceは「String value used to associate a Client session with an ID Token, and to mitigate replay attacks.(クライアント・セッションと ID トークンを関連付け、リプレイ攻撃を軽減するために使用される文字列値。)」と表現されてました。
nonceというセキュリティメカニズムはあくまでも脅威の軽減措置であって、完全に脅威をなくすことはできないということです。
(少なくとも自分はそのように解釈しました。)
上記の点を踏まえても、やはり私の「IDトークンのリプレイ攻撃を防ぎきれないのである」という仮説は正しいのだと思います。
振り返ると...
今回検証した疑念の根本は「Open ID Connect Core 1.0 の仕様書によるとIDトークンリプレイの対策としてnonceがあるはずなのに、フローをたどってみると対策として成立してないじゃん」という思考でした。
しかし、「nonceはリプレイ対策である」というのは日本語訳版の仕様書の記述であり、今回の調査にあたり原文たる英語版を読んでみたところ「nonceはIDトークンリプレイ攻撃の緩和(mitigate)のためのものである」という旨が記述されていました。
何が言いたいかというと、やはり原文を読むのは大事だということです。
課題
この記事自体の課題
そもそも論、IDトークンリプレイ攻撃とは何かを私が勘違いしている可能性があります。
いろいろ調べてはみたものの定義しているドキュメントが見つからず、諸ドキュメントの書きっぷりから推測するしかありませんでした。
新たな疑問
今回この記事を書いていて、新たに二つの疑問が生じました。またどこかで下記二点について調査の上、執筆しようと思います。
Implicitフローにおいてはstateの検証とnonceの検証って結果として同じ役割を果たさないか?であればどっちか一つでよくないか?