セッションIDをCSRFトークンに使うべきでない理由

malaさんも2年程前に書かれているのですが、未だに国内のCSRF対策の解説で「セッションIDをCSRFトークンとして使う」というアイデアが披露されていて辟易します。

喩え話は好きでないですが、「複数のサイトで同じパスワードを使っていたら一箇所から漏洩し、パスワードリスト攻撃を受けた」というのを彷彿します。セッションIDとCSRFトークンは単純に別の値にした方がいいです。

さてこのエントリの本題はここからで、CSRFトークンよりもむしろセッションIDの方です。最近は443番ポートへクロスサイトでリクエストを大量に送らせてそれをキャプチャし、すべてのリクエストに共通して含まれてくるCookie中のセッションIDを解読するBEAST/CRIME系の攻撃が知られるようになりました。

これらは基本的にはTLS/SSLの問題でありそれぞれ個別に対策が存在しているものの、基本的には「セッションIDがずっと同じ値である」という部分、HTTP特有の仕組みを攻撃対象としています。(攻撃対象がBasic認証などの場合はこの限りではないです)

これを受けて「何千もリクエストが勝手に送られている間、セッションIDがずっと同じなのって間抜けだよね?」と考えるのがまともな感覚だと思うのですが、いかがでしょうか。つまりセッションIDがずっと同じであるという実装の常識をそろそろ変えていくべきだと思います。あくまで保険的な対策となると思いますが、今後登場するかもしれないBEAST/CRIMEの発展形を防ぐ可能性が高いと考えます。

一部、セッション固定により「ログインしたタイミングでセッションIDを変える」ということは良く知られており実践されていますが、そもそもセッションIDはコロコロ変えるべきなのです。

さて話はCSRFトークンに戻りますが、セッションIDの値をそのままCSRFトークンとして使ってしまっていると、上記のように「セッションIDを頻繁に変更する」ということができなくなってしまいます。なのでセッションIDの値をCSRFトークンにするのはやめましょう。

「…やめましょう」とか書きましたが、別の件(CSRFトークン インタビューズ)でシェアの高いいくつかのフレームワークについて調べてみたところ、そもそもセッションIDの値をそのままCSRFトークンにしているものをひとつも見つけることができませんでした。もし見つけたら教えてください。

なんか、ガラパゴス的な議論をしていたようで脱力します。

Leave a comment