CSRF とは
CSRF は Cross-Site Request Forgery の略です。日本語ではクロスサイトリクエストフォージェリと呼ばれます。
簡単に言うと、ログイン済みユーザーのブラウザに、意図しないリクエストを送らせる攻撃です。
Cookie認証では、ブラウザがCookieを自動送信します。この性質が便利である一方、CSRFの前提にもなります。
攻撃のイメージ
ユーザーが bank.example.com にログイン済みだとします。ブラウザにはセッションCookieがあります。
攻撃者は別サイト attacker.example に、次のようなフォームを置きます。
<form action="https://bank.example.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker" />
<input type="hidden" name="amount" value="10000" />
</form>
<script>
document.forms[0].submit();
</script>
ユーザーが攻撃者サイトを開くと、ブラウザは bank.example.com へPOSTします。このとき、条件次第で bank.example.com のCookieが送られる可能性があります。
サーバ側が追加対策をしていないと、本人の送金リクエストとして処理してしまいます。
Cookie 自動送信が関係する
CSRFの根本には、Cookieの自動送信があります。
POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: session_id=abc123
攻撃者はCookieの中身を知りません。それでも、ブラウザがCookieを付けて送るため、認証済みリクエストに見えることがあります。
ポイント: CSRF は「Cookieを盗む攻撃」ではありません。「Cookieが自動で付くことを利用して、本人に見えるリクエストを送らせる攻撃」です。
XSS との違い
XSS と CSRF は混同されがちですが、性質が違います。
| 攻撃 | 起きる場所 | 何を狙うか |
|---|---|---|
| XSS | 正規サイト上で攻撃者JSが動く | 情報窃取、操作、改ざん |
| CSRF | 別サイトから正規サイトへリクエストを送らせる | 意図しない状態変更 |
XSSは攻撃者のJavaScriptが正規サイト上で動きます。CSRFは、ユーザーのブラウザに別サイトからリクエストを送らせます。
SameSite による軽減
SameSite Cookie 属性は、クロスサイトリクエストでCookieを送るかを制御します。
Set-Cookie: session_id=abc123; SameSite=Lax; Secure; HttpOnly
| 値 | 特徴 |
|---|---|
Strict | クロスサイトではほぼ送らない |
Lax | 一部のトップレベルGETでは送るが、多くのPOSTでは送らない |
None | クロスサイトでも送る。Secure 必須 |
多くの通常サービスでは SameSite=Lax が現実的な初期値になります。ただし、これだけで完全に守れるわけではありません。
CSRF トークン
CSRF対策の代表がCSRFトークンです。
サーバはフォームにランダムなトークンを埋め込みます。
<input type="hidden" name="csrf_token" value="random_value_123" />
POST時にこの値を検証します。
if (req.body.csrf_token !== session.csrfToken) {
return res.status(403).send("Invalid CSRF token");
}
攻撃者サイトからは、正規サイトのCSRFトークンを読めないため、正しい値を付けにくくなります。
Origin / Referer 検証
状態変更リクエストでは、Origin や Referer ヘッダーを確認する対策もあります。
const origin = req.headers.origin;
if (origin !== "https://app.example.com") {
return res.status(403).send("Invalid origin");
}
ただし、これだけに依存するのではなく、SameSiteやCSRFトークンと組み合わせるのが基本です。
やってはいけない設計
CSRFに弱い典型例は、GETで状態変更するAPIです。
GET /delete-account?id=123
GETは本来、安全な読み取りに使うメソッドです。退会、削除、送金、メール変更などの状態変更は、POST、PUT、PATCH、DELETEなどで実装し、CSRF対策を行います。
注意: SameSite=Lax でも、トップレベルGETナビゲーションではCookieが送られる場面があります。副作用のあるGETは避けてください。
まとめ
CSRFは、Cookieが自動送信される性質を利用して、ログイン済みユーザーに意図しないリクエストを送らせる攻撃です。
対策は複数重ねます。
- 状態変更をGETで行わない
SameSite=LaxまたはStrictを検討する- CSRFトークンを使う
Origin/Refererを検証する- 重要操作では再認証を求める
Cookie認証では、CSRF対策をセットで考える必要があります。
参考リソース
- 公式ドキュメント - CSRF とは何か - Cookie が自動送信されることの副作用 を確認するための一次情報