CSRF保護 は何をしますか?
ルール
- すべてのクッキーに
SameSite=Lax を設定する — これにより、デフォルトでほとんどのCSRF攻撃をブロックします
- 機密性の高い操作(アカウント削除、パスワード変更)には
SameSite=Strict を使用する
- カスタムAPIにはダブルサブミットクッキーパターンを実装する:クッキー内のCSRFトークン + リクエストヘッダー
- 状態変更を行うすべてのHTMLフォームにCSRFトークンを含める
- 状態変更リクエストでは
Origin ヘッダーと Referer ヘッダーを検証し、多層防御とする
- Next.js Server Actions および SvelteKit form actions はCSRFを自動的に処理する — これらを活用する
- SPAの場合:カスタムヘッダー(
X-CSRF-Token)でCSRFトークンを送信する — ブラウザはクロスオリジンのカスタムヘッダーをデフォルトでブロックする
import crypto from "crypto";
function generateCsrfToken(res) {
const token = crypto.randomBytes(32).toString("hex");
res.cookie("csrf_token", token, { httpOnly: false, sameSite: "strict", secure: true });
return token;
}
function verifyCsrf(req) {
const cookieToken = req.cookies.csrf_token;
const headerToken = req.headers["x-csrf-token"];
if (!cookieToken || cookieToken !== headerToken) {
throw new Error("CSRF validation failed");
}
}
避けるべきこと
- CSRF保護なしでクッキーベースの認証だけに頼る — どのサイトでもあなたのエンドポイントにフォームを送信できてしまいます
- ローテーションしないCSRFトークン — ひとつのトークンが漏洩すると、将来のすべてのリクエストが危険にさらされます
- 状態を変更するGETリクエスト — CSRF保護はPOST/PUT/DELETEでのみ機能します。なぜならGETリクエストはSameSite=Laxをバイパスするからです
- 「ただのAPIだから」といってCSRF保護を無効にする — クッキーが関与している場合、CSRFは適用されます