CSRFを言葉でなく意味を理解する、コーディングして実証
今回はCSRFです
CSRFとは何かしらのデータの投稿する時に意図したページからの投稿なのかどうかをチェックするセキュリティの仕組みです
step1 投稿ページにトークンをinput type="hidden"などのフォームに設置
step2 同じトークンをセッションに保存
step3 POSTで投稿した時にPOSTのパラメータのトークンとセッションのトークンが 一致しているか確認
step4 一致したら、処理を続行、しなければ処理を中断
といった流れになります。
なぜそういった対策をしないといけないかというと
- 投稿ボタンを連打されると二重に登録される可能性がある
- 別のSNSなどから意図せず投稿されてしてしまう可能性がある
などです。
なのでそういったセキュリティの観点からほとんどのフレームワークでも用意されています。
Laravelなどのフレームワークでは有効期限が2時間ってなってますが、それはどういうことかというと確認ページなどを開いたまま違うことで2時間が過ぎ、POSTすると時間オーバーでリフレッシュからって事になります。
ユーザビリティがその分下がってしまうので、CSRFトークンの期限は不要かと思います。
サーバー的にずっとトークンデータをずっと保持するとデータ容量をいっぱいに使ってしまう可能性があるので、その点で期限を決めてもいいかと思いますが、1日もしくはそれ以上の日数ぐらいでもいいかと思います。
そこでクイズというか疑問が湧いてきました。
Laravelのセッションの種類には
- file
- cookie
- database
- apc
- memcached
- redis
- dynamodb
などがありこの中でCSRFが実現できなくなるセッションの種類がありますどれだと思いますか?
正解はcookieです。
なぜなら、cookieは保存先がサーバーにはなくブラウザにあるためCSRFの実装をすると一旦ブラウザにレスポンスしないと反映されない分2重に登録されてしまうという事を防ぎきれないです。
なので論理的に考えるだけではなくて、実際に検証してみました。
まずはじめにfileをセッションにしてPOSTの連打してみました
2回目からCSRFのセキュリティが効いて419エラーが出ている所が確認できました
次にCookieをセッションにしてPOSTするボタンを連打してみました。
4回目から419とCSRFのセキュリティが効いてますが、2,3回目はPOSTできてしまっています。
cookieのレスポンスがブラウザに反映される前にこの3回分のPOSTがされているからだと思います
今回CSRFの説明しましたが、ただ単にcookieをセッションにするとCSRFの機能の一部が無効になるという事だけを説明したかったわけではなく
CSRFとは何か?
を理解し
セッションとは何か?
を理解していればこのような不具合が発生すると人から教えられなくても気づける事です。
今回このように具体的な例でCSRFの仕組みの理解を説明しましたが、意外とエンジニア歴何年もあるベテランエンジニアでも基本的な言葉は知っていても原理的な仕組みの理解をしている人は自分の経験上多くなかったので、CSRFを一例として取り上げました。
以前の動画でも紹介しましたがプログラミング・エンジニアに必要な知識量はそこまで多くなく、現場に入って2〜3週間で習得できる場合がほとんどです。
しかし、原理的な仕組みの理解をしなければ、今回のように
CookieセッションのCSRFは不可能
という結果の知識を大量に覚えていかないといけません。
知識の暗記だけではなく、仕組みの理解をして知識と知識の掛け算ができるエンジニアになれるように心がけてみてもいいかもしれません
登録日:
更新日: