前回は問題1のつもりが問題2も合わせて解いてしまったので、問題3. にチャレンジ。次の問題はCross-Site Request Forgery (XSRF) 。mixiのぼくはまちちゃん事件で有名になった手法。XSRF自体や、事件の経緯の詳細はリンクを参照のこと。また、jerlsbergのサイトにも、XSRFの説明が記載されている。
問題3. Cross-Site Request Forgery (XSRF)
調査
3問目は「 Find a way to get someone to delete one of their Jarlsberg snippets.」。XSRFを使って、ユーザーのsnippetsを消す方法を見つける。
はじめに、通常のsnippetsを消す際に、どのようなリクエストが発行されるかを調査する。すると、以下のようなリクエストが発行されることで、snippetsが削除されることがわかる。indexは、何番目のsnippetsを削除するかを指定するパラメータ。
http://127.0.0.1:8008/2032736562/deletesnippet?index=0
つまり、ログイン済みのユーザーに、(そのユーザーに気づかれること無く)上記のようなHTTPリクエストを発行させることができれば、この問題が解けたことになる。
脆弱性の確認
次のようなHTMLを準備する。
ポイントは、このHTMLをユーザーが閲覧すると、imgタグによって、snippetを削除するHTTPリクエストが発行されてしまうこと。
<html> <body> XSRFの確認 <img src="http://127.0.0.1:8008/2032736562/deletesnippet?index=0" style="display:none"> </body> </html>
脆弱性確認前のsnippetは以下のとおり、2件。
jerlsbergにログインした状態のまま、先ほど作成したHTMLをブラウザで表示する。
結果、1つめのsnippetの削除されてしまう。
対策
XSRFの場合、サーバーサイドから見ると、正規のユーザーからリクエストが発行されているため、ある意味では正しい処理を行っていることになる。つまり、正しく発行されたリクエストであるかどうかを見分けるための工夫が必要。例えば、以下のような対策がある。
- リファラーのチェック
- リファラーをチェックすることで、外部サイトからのリクエストでないことを確認する。
- トークンIDの発行
- 入力フォーム生成時に、hiddenでトークンIDを埋め込む(トークンIDは、攻撃者に推定されにくいものでなければならない)。リクエスト送信時には、トークンIDもサーバーに送信されるので、トークンIDをチェックすることで、正しいリクエストなのかどうかを確認することができる。実装例がjerlsbergのサイトにも記載されている。
フォームをGETではなくPOSTに変えるという対策もあるが、本質的な対応でないことに注意。攻撃者は、(例えばjavascriptを使って)ユーザーにPOSTのリクエストを発行させるようにすることも可能である。