Shikata Ga Nai

Private? There is no such things.

CSRFトークンの仕組み(続編):リクエスト構造と送信方法の違い

Hello there, ('ω')ノ

✅ フォーム送信時のリクエスト例

以下は、CSRFトークンを正しく含んだリクエストの構造です:

POST /my-account/change-email HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded

csrf=50FaWgdOhi9M9wyna8taR1k3ODOR8d6u&email=example@normal-website.com
  • csrf パラメータには、サーバーが生成・発行した一意かつ予測不能な値が含まれています
  • このトークンが正しくセッションと一致していることをサーバーが検証します

✅ CSRFトークンの効果

  • 攻撃者はこのトークンの正確な値を知ることができない
  • よって、トークンなし or 不正な値のリクエストはサーバー側で拒否される
  • これにより、悪意あるクロスサイトからのリクエストを確実に防止できます

🔄 トークン送信の方法はいくつかある

1️⃣ フォーム内の hidden フィールド(最も一般的)

<input type="hidden" name="csrf" value="...">

→ フォーム送信時に自動的に含まれる(POSTリクエスト)


2️⃣ HTTPヘッダーに含める方式(特にJavaScriptベースのSPAで多い)

X-CSRF-Token: 50FaWgdOhi9M9wyna8taR1k3ODOR8d6u
  • 通常はJavaScriptがCookieやHTMLからトークンを取得し、Ajaxのカスタムヘッダーに追加して送信
  • CSRFトークンをCookieに保存するSPAなどでは、この方式が主流

⚠️ トークンの送信方法はセキュリティに大きな影響を与える

送信方法 安全性と特徴
hiddenフィールド 最も広く使われる/フォーム専用/自動で送信される
HTTPヘッダー JavaScript制御が必要/SPA向け/柔軟だが複雑化しやすい
URLパラメータ 原則非推奨/Refererやログで漏洩のリスクあり

✅ 攻撃者がトークンを取得できない理由

  • Same-Origin Policyにより、攻撃者のページから被害者のHTMLやJavaScriptにはアクセスできない
  • つまり、HTML内やCookieに含まれるCSRFトークンの値を読み取る手段がない
  • 攻撃者が作ったCSRFリクエストは、不正なトークン付き or トークンなし → 即座に拒否

✅ まとめ

CSRFトークンは、リクエストが信頼できる正規のユーザーからの操作かどうかをサーバーが検証するための「鍵」です。

  • 攻撃者が再現・予測できない値を含めることで、CSRF攻撃を根本から防ぎます。
  • どの方法でトークンを送るかによって、設計の堅牢性が大きく左右されるため、実装方法にも注意が必要です。

Best regards, (^^ゞ