目次
こんにちは、ともです。
現在、Webプログラミングを初めて10ヶ月ほどの僕ですが、安全なアプリケーションの開発するために少しでも知識を増やしていきたいと思って独学中です。
今回はCSRFという脆弱性について触れ、その対策方法について解説します。
この記事ではCSRFというものについて解説をし、PHPでCSRF対策をするという内容です。
- セキュリティについて学び始めた初心者なので、あまり良い説明ではないかもしれませんがよろしくお願いします。
クロスサイトリクエストフォージェリ(CSRF)とは
クロスサイトリクエストフォージェリ(cross-site request forgeries)【CSRF】というWebアプリケーションの脆弱性があります。
cross-site | サイトをまたいで |
---|---|
request | リクエストを送る |
forgeries | 偽装 |
「サイトをまたいで偽装したリクエストを送る」という直訳から分かるように、意図しないリクエストを他のサイトから送られてしまう脆弱性であることが分かります。
話を単純化するために次の2つのサイトを考え、そのサイトの内容を次のようにします。
- あなたが作成したサイト
- あなたが作成したサイトを攻撃するために作られたサイト
- あなたが作成したサイトは、掲示板サイトである
図解してみる
正常な処理の流れとはどういうものでしょうか。それを下の図にまとめました。
正常な処理の流れ

正常な処理とは、あなたが作成したサイトで投稿処理が行われるという事ですね。
では、『意図しないリクエストを他のサイトから送られてしまう』とはどういう状況でしょか。
予期せぬ処理の流れ
予期せぬ他のサイトからリクエストが送られる状況を下の図にまとめました。

悪い人があなたのサイトを攻撃するための掲示板攻撃サイトを作成します。
攻撃サイトへ迷い込んだユーザは、普通の掲示板サイトだと思い投稿しました。(①)
しかし、そのサイトはあなたのサイトへ投稿処理のリクエストを出すサイトですので、あなたのサイトへ投稿リクエストが走りました。(②)
あなたのサイトに他サイトからの投稿リクエストを許可しないという対策が存在しない場合、登録処理を行うクエリが実行されてしまいます。(③)
上記が、クロスサイトリクエストフォージェリという別サイトからリクエストを許してしまうという脆弱性となります。
対策方法
対策方法としては、
あなたのサイトからのリクエストのみを許可するように、照合する機能を実装すると良いです。
その照合方法には、
ページに仕込んだCSRFトークンと、セッションに格納したトークンとを照合することにより実現できます。
この照合により、なぜあなたのサイトからのリクエストかどうかの判定が行えるのか図解してみました。
正常に照合される場合

少しコードも書いてみました。処理の流れに①から⑥の番号を振ってみました。
あなたのサーバから受け取ったページであることを示すためにCSRFトークン付与します。CSRFトークンの生成方法は色々あるため割愛します。
つまり、CSRFトークンが付与されたページからのリクエストかどうかを判定すれば、あなたのサイトからのリクエストかどうかが分かります。
このトークンを比較する処理を実装した場合、攻撃サイトからのリクエストはどうなるのか図解してみます。
攻撃サイトからのリクエストの場合

攻撃者のサーバからはトークンを付与したページを攻撃サイトに設けることができません。(①〜③)
ですので、あなたが作成したサイトのサーバ側でトークンを照合が失敗しリダイレクトすることになります。(④〜⑥)
CSRFトークンを持たないページからの投稿処理のリクエストは失敗に終わっていることが分かると思います。
まとめ
クロスサイトリクエストフォージェリ(CSRF)について理解をまとめ、対策方法についても概念的にまとめました。
CSRFトークンの生成の仕方にはどのようなものがあるのか等理解できましたら、ブログにまとめたいと思います。