top of page
IMG_0546.JPG

診断するとなんだかんだ検出されるシリーズ:CSRF:2025/02/12

  • 執筆者の写真: 晋次 宮田
    晋次 宮田
  • 2025年2月12日
  • 読了時間: 5分

1. 本当に“CSRFは下火”と考えてよいのか?


Laravel、Rails、DjangoなどのWebフレームワークには、CSRFトークン機能が標準搭載されています。さらに、VueやReactなどのフロントエンドでも、AxiosのX-CSRF-Tokenヘッダーを設定するだけで簡単にCSRF対策が可能です。

加えて、ブラウザ側もSameSite属性を強化し、外部サイトからのCookie送信を制限する動きが進んでいます。こうした流れから、「CSRFはもうあまり問題にならないのでは?」と考える人も増えてきていると感じています。


1-1. それでも残る危険な例

とはいえ、実際に脆弱性診断をしていると、一部の機能がCSRF対策から外れていたり、Cookieの設定がうまくいかずに脆弱性が残っているケースがまだ見受けられます。「jsonを使っているので大丈夫」という話もよく聞きますが、hackeroneでレポートされているようにフォーム送信でもJSONリクエストが通り、Cookieが自動送信されてユーザー権限で不正操作が出来るケースも報告されています。


2. 脆弱性診断でよく見る「不十分なCSRF対策」パターン


2-1. JWTをCookieに保存している

どんな状況か

JWT(JSON Web Token)でAPIアクセスを認証する設計にしているものの、ミスなのか、よく挙動を理解していないのか、JWTそのものをブラウザのCookieに保存しているケースが実際にあります。その場合、従来のセッションCookieと同様のCSRFリスクが復活してしまうことがあります。

  • Authorization: Bearer <JWT> ヘッダーを自前で付ける方式なら通常のCSRFリスクは下がりますが、Cookie保存だとブラウザが自動で送信するため、攻撃者が細工したページを踏ませるだけで勝手にJWT付きリクエストが実行される可能性があります。


具体例

js
コピーする編集する
// JWTをCookieに保存する例(HttpOnly, Secureなどを付けていてもCookie送信は自動)
document.cookie = `jwtToken=xxx.yyy.zzz; HttpOnly; Secure; SameSite=None;`
  • 一見セキュアに見えますが、Cookie経由でトークンを送るならCSRFトークン検証やSameSite属性の厳格化をしないと、不正リクエストが通ってしまうかもしれません。


対応のポイント

  • JWTをCookie保存する場合でも、CSRFトークンを使う、あるいはSameSite=Strict/Laxで攻撃を防ぎつつCookieの送信範囲を限定するなど、Cookieベースの対策をしっかり行う。

  • 可能なら、LocalStorageやSessionStorageなどで保持し、Authorization: Bearerヘッダーを自分で付与する方式に切り替えて、従来型のCSRFリスクを軽減する。ただしこの場合はXSSに注意が必要。

  • フレームワークのドキュメントを読んで挙動を確認する。(そんな暇ねーよと言われるかもしれませんが、、、)


2-2. Cookie設定とブラウザ仕様のミスマッチ


よくあるケース

  • クロスドメインやサブドメイン構成で運用するのに、SameSite=Strictを設定してしまい、意図した認証が機能しなくなる。

  • 逆にSameSite=None&Secure=falseになっていて、古いブラウザで想定外の挙動を起こす。


設定例(Laravel)

// config/session.php
'same_site' => 'none',
'secure' => false,
// ↑ HTTPS環境前提なのに secure=false のままなど

この状態だと環境やブラウザによってCookieが送られたり送られなかったりし、CSRF対策がうまく働かない場合があります。


対応のポイント

  • 本番環境でHTTPSを使うならsecure=trueが基本。

  • クロスドメインでCookieを扱うなら、SameSite属性を正しく設定し、実機やブラウザテストで挙動を確認する。

  • テスト環境と本番環境のCookie設定をできる限り揃えておく。


2-3. 重要操作前の二重チェックがない


どう危険?

  • 送金や購入などの大事な機能でも、CSRFトークンしか使っていないと、トークンが何らかの形で流出したり、XSSと組み合わされたりしたときに大きな被害が発生する。


具体策

  • 重要操作では、CSRFトークンに加え、パスワード再入力や多要素認証などで**「本当にユーザー本人が操作しているか」**を確認する。

  • ワンクリック詐欺を防ぐため、確認ダイアログや段階的な手続きを用意するのも有効。


3. まずは基本を振り返る:OWASP & IPAのガイドを参考に


3-1. OWASP CSRF Prevention Cheat Sheet

  • OWASP公式CSRF対策チートシートでは、

    • 同期トークン(ワンタイムトークン)

    • ダブルサブミットクッキー

    • SameSite属性 など、代表的な方法をわかりやすく解説してくれています。

  • 「従来手法」で対策できない攻撃手口が見つかったときはここに追記されることが多いので、定期的にチェックする価値があります。


3-2. IPA「安全なウェブサイトの作り方(改訂版)」

  • IPAのガイドラインは国内で標準的な参照資料。

  • CSRFだけでなく、XSSやSQLインジェクションなど他の脆弱性との複合リスクにも触れており、総合的な対策の重要性を説いています。


4. 余裕があれば、最新バイパス事例:PortSwiggerや

Snyk Blogをチェック


4-1. PortSwigger Research

  • PortSwigger Researchでは、Burp Suiteの開発元が最新の脆弱性情報を公開しています。

  • WebSocketService Workerなど、従来のCSRFトークン手法だけでは対策が難しい領域の攻撃事例が載ることも。

  • フレームワークの標準対策だけではカバーできないケースが参考になります。


4-2. Snyk Blog

  • Snyk Blogは、Node.jsやJavaScript関連の脆弱性情報が充実。

  • Vue/React/Nuxt/Next.jsなど、SPAを中心とした最新のCSRF事情や周辺ツールの動向を追いやすいです。


5. Livewireのような「CSRF対策を自動適用する仕組み」もおすすめ


5-1. LaravelのCSRFミドルウェアをフル活用

Livewireでは、LaravelのVerifyCsrfTokenミドルウェアを内部的に活用し、フレームワークがすべての通信にCSRFトークンを自動的に付与・検証します。

開発者がAjaxリクエストにトークンをつけ忘れるようなヒューマンエラーを起こしにくいため、動的なUIでも安定してCSRF対策を維持できます。


5-2. コンポーネント単位の状態管理

各コンポーネント固有のIDと状態をやり取りする仕組みにより、攻撃者が不正なデータを送り込むハードルが上がっています。

「Cookie認証を使う以上CSRFが心配」という場合でも、Livewireを使えばセキュアな通信フローをフレームワーク側がサポートしてくれるわけです。


まとめ

CSRFはリクエスト情報を見れば対策をしているかしていないかがすぐに判る脆弱性の一つです。「していない」と解ったら、あとは悪意を持って狙うかどうかの話になってしまいます。

言い方は悪いですが

  • 狙ったところで対してメリットのないサービス

という判断をされているケースも実際あると思います。なので、サービスがスケールする段階になったら、一度はチェックしておくことをおすすめします。迷ったらご連絡下さい。ハックします!(嘘)

 
 
bottom of page