仕事で「フレームワークで使ってる CSRF 対策用トークンがセッション ID を基にいろいろ組み合わせた文字列のハッシュなんだけれども、なんでセッション ID 直接使わないんだよう」的な話が出たので、なんでだろうなーと考えつつ理由について検討してみたので以下に一部晒してみます(社内向けに書いたものなのでいろいろ雑だったりするのはごめんね):
推測ですが、セッション ID が GET パラメータとかに含まれたりする可能性を避けたかったんじゃないかなあとか思います(フォームは GET でも使われうることを想定している)。 GET パラメータにセッション ID のような種類の情報は含めるべきではありません。 あと、セッション ID が盗まれた場合でも CSRF 攻撃を受けないようにするという意図もありそうな気がします。攻撃者がセッション ID を知っている状況で CSRF 攻撃を選択する状況について検討してみます。 たとえば、前回のアクセスからユーザの User-Agent の値が変化していないかどうかのチェックをおこなうようなアプリケーション(ニコニコ動画や、 OpenPNE 2.14 なんかがそうですね)の場合、セッション ID だけを入手したところで攻撃者がなりすませない可能性がありますし、せっかく入手したセッション ID が無効化されてしまうかもしれません。そのあたりを警戒して攻撃者が CSRF 攻撃に切り替えるということもまあ考えられないこともないですね。 あと、少なくとも日本では、セッションハイジャック攻撃は明確に違法行為(攻撃を仕掛けただけで違法)ですが、 CSRF 攻撃はそうとは言い切れない(被害の状況によって偽計業務妨害などで引っかかる可能性はもちろんあるが)ところがあるかと思います。このあたりのリスクを回避するために、 CSRF を選択するというのもありえそうな気がします。 それからセッションハイジャック攻撃に対する CSRF 攻撃のアドバンテージとしては、やはり、被害者自身にリクエストを強制させることができるというところがあるかと思います。攻撃者が自ら行動を起こすわけではない(いわゆる能動的攻撃ではない)ため、被害を受けたときのアクセスログなどを調査したとしても、攻撃者の痕跡はそこには残りません。そのため、攻撃をおこなったのが自分であることを隠したいがために CSRF 攻撃を選択するということもあるでしょう。 ……ということで、まあ、セッション ID と CSRF 対策用トークンを別の値にするということにはそれなりの優位性は存在すると思います。ただ、それでも個人的にはセッション ID で充分だと思いますが。
CSRF 攻撃が明確に違法行為じゃないとか書いてますが、このあたりはあまり自信ないですねー。最近の刑法改正とかで引っかかるようになったりするのかなあ。