Web アプリケーションの脆弱性、特に有名なものに3つあるが CSRF だけはピンと来なかった。色々調べて理解できたので具体的な例でまとめてみる。
- XSS
- SQL Injection
- CSRF
CSRF の脆弱性
CSRF (Cross-Site Request Forgeries)脆弱性があると、利用しているサイトのユーザーに攻撃者が望む操作をさせることができる。
例えば、Aさんはあるショッピングサイトを利用しているとする。Aさんがパスワードを変更する場合はパスワード変更画面にアクセスしてそこで新しいパスワードを入力し変更ボタンを押す。
実際に行われることを細かく書くと以下のようになる。
- Aさんのブラウザでパスワード変更画面を開く(すでにログイン済み)
- 新しいパスワードを入力し、[変更する] を押す
- ショッピングサイトのサーバーに 新しいパスワード とAさんのリクエストであることを認証するため session token (cookie)が送られる
- session token が正しいことを確認した上で、DB に保存されているパスワードを
cA3tB9FJSdZmに更新する 1

攻撃例

このパスワード変更画面に CSRF の脆弱性がある場合のことを考えてみる。
以下のような手順が成功すると、攻撃者がパスワードを任意の文字列に変更することができてしまう。
- 攻撃者は Aさんに攻撃用ページへのリンクと、クリックさせるような文章のメールを送る。
- 騙された Aさんがページを開く
- ページに設置されたスクリプトによって、ショッピングサイトへ「パスワードを "abc123" に変更する」リクエストが送信される。この時 Aさんのブラウザに保存された shop.jp の cookie が送信される。
- ショッピングサイトは session token を見て Aさんからの正規のリクエストだと判断しパスワード変更処理を行う
ここで [3] のスクリプトは以下のようなものである。ポイントはこのフォームが送信されるときに cookie (Aさんの持つ session token が含まれる)が勝手に送信されてしまうことだ。
ちなみに、Ajax(XMLHttpRequest)リクエストは行っていないので 同一オリジンポリシーによる制限は受けない。
<form name="form1" action="https://shop.jp/me/password/change/" method="POST"> <input type="hidden" name="password" value="abc123"> </form> <script>document.form1.submit()</script>
これにより、攻撃者は Aさんになりすましてリクエストを偽造することができる。攻撃者のサイト経由でショッピングサイトへのリクエストを偽造することから、Cross-Site Request Forgeries と呼ばれている。