「ソースを見る」で見た hidden の値と実際に POST される値が違う
調査依頼。CSRF 対策のために次の機能を入れた。
- 更新機能の前の機能でランダム値 (トークン) を払い出す。
- トークンをセッションに保存。hidden にも埋め込む。
- 更新機能では、セッションに入ったトークンと hidden で送られた値を比較し、同じなら更新処理を実行する。
ところが、この機能が Firefox ではうまく動かない。調べてみると Firefox の場合、「ソースを見る」で HTML のソースに書かれたフォームの hidden の値と、実際に POST したときに送られる値が違っている。
LiveHttpHeaders を使ってすぐわかったのは、トークンを払い出す機能を 2 回 GET していること。IE や Netscape では 1 回しか GET していない。これは現象ともあっている。すなわち、1 回目のアクセスでトークン 1 を、2 回目のアクセスでトークン 2 を得、
「ソースを見る」で見たときはトークン 2 が見えていてサーバ側で保存しているトークンと一致するが、実際に送信されるのがトークン 1 になるのでエラーになる。
あとは、なぜ 2 回 GET が飛ぶかを特定すること。最初から JavaScript が怪しいと思っていたので、JavaScript を Off にしてみると確かに 1 回しか飛ばなくなる。Firebug で調べてみたら、script の中に HTML 文書がまるごと入っている。いろいろリンクされている JavaScript ファイルを調べていたが、ようやく発見した原因は次の script タグだった。
<script language="javascript" src=""></script>
つまり、src="" となっていると、相対パスで自分自身を指していると解釈し、自分自身を再度リクエストするらしい。
この現象を使うとなんか変なモノが作れそうな予感。