確認する項目は次のとおりです。
Origin checking failed
Referer checking failed
CSRF cookie not set
CSRF token missing
CSRF token incorrect
不自然な送信元IP
特定URLへの集中
デプロイ直後の急増
CSRF 403の急増は攻撃だけでなく、フロントエンド更新、CDN設定、Cookie属性、Origin設定の不整合でも発生します。
原因をログだけで断定しないようにします。
次のルールを開発標準へ入れます。
・GETでは状態を変更しない
・Cookie認証のunsafe methodにはCSRF検証を必須とする
・csrf_exemptには理由と代替認証を記載する
・外部Webhookには署名検証を実装する
・CORSの許可Originを限定する
・管理機能には再認証を追加する
・兄弟サブドメインを同じ信頼境界とみなさない
#!/usr/bin/env bash
set -euo pipefail
if grep -RIn \
--exclude-dir=.git \
--exclude-dir=.venv \
--exclude-dir=node_modules \
'@csrf_exempt' .; then
echo "csrf_exemptが見つかりました。代替認証をレビューしてください。"
fi
python manage.py check --deploy
python manage.py test
csrf_exemptが存在するだけでビルドを必ず失敗させると、正当なWebhook実装も止まります。
検出結果をセキュリティレビュー対象にする運用が現実的です。
最低限、次のテストを用意します。
トークンなしPOSTは403
誤ったトークンは403
正しいトークンは成功
GETでは変更されない
他人のリソースを更新できない
不正Originは拒否
ログイン画面もCSRF保護
ログアウトはPOST
OAuthのstate不一致は拒否
WebSocketの不正Originは拒否
2026年7月29日時点では、Django 5.2 LTSまたは6.0系のセキュリティサポート中リリースを利用します。
バージョンを確認します。
python -m django --version
python -m pip show Django
依存関係を確認します。
python -m pip list --outdated
python -m pip check
本番環境で直接アップグレードしないでください。
次の順番で進めます。
DBバックアップ
現在の依存関係を保存
検証ブランチ作成
テスト環境でアップグレード
Djangoリリースノート確認
自動テスト
CSRF・ログイン・管理画面テスト
ステージング確認
ロールバック手順作成
本番反映
誤りです。
独立カテゴリから外れた理由の一つは、フレームワーク標準防御によって発生率が下がったためです。
標準防御を外せば、再び脆弱になります。
誤りです。
GET更新、Same-Site攻撃、兄弟サブドメイン、クライアントサイドCSRFなどが残ります。
誤りです。
外部サイトからHTMLフォームをPOSTできます。
トークン検証が必要です。
条件付きです。
Content-Typeを厳格に確認し、Cookie認証ならCSRF対策を行い、CORSを正しく制限する必要があります。
誤りです。
CORSは主にレスポンスの読取りを制限します。
CSRFはレスポンスを読めなくても状態変更できる場合があります。
誤りです。
JavaScriptがトークンを読み取る構成では実装方法が変わります。
また、XSSがあればDOM内トークンの取得や正規オリジンからの送信が可能です。
必須ではありません。
リクエスト単位のワンタイムトークンは強力ですが、戻るボタン、複数タブ、再送信で問題が起きる場合があります。
セッション単位でも、十分な乱数、セッションへの関連付け、厳格な検証があれば有効です。
今後はCSRFトークンがなくなるというより、ブラウザとサーバーの複数シグナルを組み合わせる方向が進むと考えられます。
主な要素は次のとおりです。
SameSite Cookie
Origin検証
Fetch Metadata
Partitioned Cookie
サードパーティCookie制限
OAuth・OIDCの厳格化
WebAuthnによる重要操作確認
ブラウザ分離
APIの型とスキーマ検証
リスクベース認証
操作単位の再認証
Passkeyによるトランザクション確認
ただし、ブラウザ側の制限が強くなっても、次の原則は変わりません。
Cookieを持っている
≠
利用者がその操作を意図した
サーバーは認証状態だけでなく、正規画面から開始された操作であること、現在のセッションに対応するトークンであること、必要に応じて利用者が重要操作を再確認したことを検証する必要があります。
CSRFは、ログイン中のブラウザが認証Cookieを自動送信する性質を悪用し、利用者の意図しない操作を実行させる攻撃です。
主要フレームワークの標準防御やSameSite Cookieによって、単純なフォーム型CSRFは以前より成功しにくくなりました。
しかし、CSRFが完全に解決したわけではありません。
現代では次の攻撃面を確認する必要があります。
GETによる状態変更
不完全なトークン検証
ログインCSRF
JSON・API・SPA
OAuth・OpenID Connect
WebSocket
Client-Side CSRF
Same-Siteの兄弟サブドメイン
CORS誤設定
csrf_exemptの誤用
Djangoでは、次の構成を基本にします。
CsrfViewMiddleware
+
{% csrf_token %}
+
X-CSRFToken
+
Secure Cookie
+
SameSite
+
Origin・Referer検証
+
GETで状態変更しない
+
重要操作の再認証
Django標準機能を無効化せず、テスト、ログ監視、サブドメイン管理、XSS対策まで含めて多層防御を構築することが重要です。
{% csrf_token %}を入れるだけで安全ですか?通常のDjangoフォームでは重要な基本対策です。
ただし、ミドルウェア、HTTPS、Cookie属性、Origin設定、GET設計、XSS対策も必要です。
GETでは状態を変更しない設計にします。
検索や画面表示などの読取りだけに使う限り、通常はCSRFトークンを付けません。
SameSite=Strictにすればトークンは不要ですか?不要にはなりません。
StrictでもSame-Siteの兄弟ドメインや正規サイト内のガジェットを利用した攻撃などを考慮する必要があります。
JWTそのものでは決まりません。
JWTをCookieへ保存して自動送信する場合はCSRF対策が必要です。
Authorizationヘッダーへ明示的に付ける場合は古典的CSRFに強くなりますが、XSS対策が重要になります。
SessionAuthenticationを使う場合は必要です。
Cookieを使わないBearer Token方式では典型的なCookie型CSRFは成立しにくくなりますが、トークン保存場所、CORS、XSSを別途確認します。
csrf_exemptはいつ使えますか?外部Webhookなど、ブラウザのCookie認証を利用しないエンドポイントで使う場合があります。
その場合もHMAC署名、公開鍵署名、タイムスタンプ、リプレイ防止などの代替認証が必要です。
異なります。
CSRFは利用者のブラウザに偽のリクエストを送らせる攻撃です。
SSRFはサーバー自身に内部・外部の別URLへリクエストさせる攻撃です。
有効なセッションに対応するトークンが攻撃者へ漏れると、防御を突破される可能性があります。
URL、ログ、外部フォーム、Refererへ漏らさず、XSS対策も行います。
困難です。
WAFはOrigin、Fetch Metadata、レート制限などの補助防御に使えますが、利用者の意図を確認するCSRFトークン検証はアプリケーション側で行います。
攻撃とは限りません。
フロントエンド更新、Cookie属性変更、CloudflareやNginxのスキーム判定、CSRF_TRUSTED_ORIGINS不足などでも増加します。
エラーログ、Origin、Referer、URL、デプロイ時刻を照合して判断します。