×
サイバー攻撃について

確認する項目は次のとおりです。

  • Origin checking failed

  • Referer checking failed

  • CSRF cookie not set

  • CSRF token missing

  • CSRF token incorrect

  • 不自然な送信元IP

  • 特定URLへの集中

  • デプロイ直後の急増

CSRF 403の急増は攻撃だけでなく、フロントエンド更新、CDN設定、Cookie属性、Origin設定の不整合でも発生します。

原因をログだけで断定しないようにします。


23. 再発防止

23-1. 開発標準を決める

次のルールを開発標準へ入れます。

・GETでは状態を変更しない
・Cookie認証のunsafe methodにはCSRF検証を必須とする
・csrf_exemptには理由と代替認証を記載する
・外部Webhookには署名検証を実装する
・CORSの許可Originを限定する
・管理機能には再認証を追加する
・兄弟サブドメインを同じ信頼境界とみなさない

23-2. CIで危険コードを検出する

#!/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実装も止まります。

検出結果をセキュリティレビュー対象にする運用が現実的です。


23-3. セキュリティテストを自動化する

最低限、次のテストを用意します。

  • トークンなしPOSTは403

  • 誤ったトークンは403

  • 正しいトークンは成功

  • GETでは変更されない

  • 他人のリソースを更新できない

  • 不正Originは拒否

  • ログイン画面もCSRF保護

  • ログアウトはPOST

  • OAuthのstate不一致は拒否

  • WebSocketの不正Originは拒否


23-4. Djangoを更新する

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

注意事項

本番環境で直接アップグレードしないでください。

次の順番で進めます。

  1. DBバックアップ

  2. 現在の依存関係を保存

  3. 検証ブランチ作成

  4. テスト環境でアップグレード

  5. Djangoリリースノート確認

  6. 自動テスト

  7. CSRF・ログイン・管理画面テスト

  8. ステージング確認

  9. ロールバック手順作成

  10. 本番反映


24. 注意点・よくある誤解

誤解1:OWASP Top 10から消えたので対策不要

誤りです。

独立カテゴリから外れた理由の一つは、フレームワーク標準防御によって発生率が下がったためです。

標準防御を外せば、再び脆弱になります。


誤解2:SameSite=Laxなら完全に安全

誤りです。

GET更新、Same-Site攻撃、兄弟サブドメイン、クライアントサイドCSRFなどが残ります。


誤解3:POSTを使えば安全

誤りです。

外部サイトからHTMLフォームをPOSTできます。

トークン検証が必要です。


誤解4:JSON APIなら安全

条件付きです。

Content-Typeを厳格に確認し、Cookie認証ならCSRF対策を行い、CORSを正しく制限する必要があります。


誤解5:CORSを設定すればCSRFも防げる

誤りです。

CORSは主にレスポンスの読取りを制限します。

CSRFはレスポンスを読めなくても状態変更できる場合があります。


誤解6:CSRF CookieをHttpOnlyにすれば完璧

誤りです。

JavaScriptがトークンを読み取る構成では実装方法が変わります。

また、XSSがあればDOM内トークンの取得や正規オリジンからの送信が可能です。


誤解7:トークンはリクエストごとに必ず使い捨てるべき

必須ではありません。

リクエスト単位のワンタイムトークンは強力ですが、戻るボタン、複数タブ、再送信で問題が起きる場合があります。

セッション単位でも、十分な乱数、セッションへの関連付け、厳格な検証があれば有効です。


25. CSRF防御の将来

今後はCSRFトークンがなくなるというより、ブラウザとサーバーの複数シグナルを組み合わせる方向が進むと考えられます。

主な要素は次のとおりです。

  • SameSite Cookie

  • Origin検証

  • Fetch Metadata

  • Partitioned Cookie

  • サードパーティCookie制限

  • OAuth・OIDCの厳格化

  • WebAuthnによる重要操作確認

  • ブラウザ分離

  • APIの型とスキーマ検証

  • リスクベース認証

  • 操作単位の再認証

  • Passkeyによるトランザクション確認

ただし、ブラウザ側の制限が強くなっても、次の原則は変わりません。

Cookieを持っている
        ≠
利用者がその操作を意図した

サーバーは認証状態だけでなく、正規画面から開始された操作であること、現在のセッションに対応するトークンであること、必要に応じて利用者が重要操作を再確認したことを検証する必要があります。


26. まとめ

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対策まで含めて多層防御を構築することが重要です。


FAQ

Q1. Djangoでは{% csrf_token %}を入れるだけで安全ですか?

通常のDjangoフォームでは重要な基本対策です。

ただし、ミドルウェア、HTTPS、Cookie属性、Origin設定、GET設計、XSS対策も必要です。


Q2. GETリクエストにもCSRFトークンを付けるべきですか?

GETでは状態を変更しない設計にします。

検索や画面表示などの読取りだけに使う限り、通常はCSRFトークンを付けません。


Q3. SameSite=Strictにすればトークンは不要ですか?

不要にはなりません。

StrictでもSame-Siteの兄弟ドメインや正規サイト内のガジェットを利用した攻撃などを考慮する必要があります。


Q4. JWTを使えばCSRFはなくなりますか?

JWTそのものでは決まりません。

JWTをCookieへ保存して自動送信する場合はCSRF対策が必要です。

Authorizationヘッダーへ明示的に付ける場合は古典的CSRFに強くなりますが、XSS対策が重要になります。


Q5. Django REST FrameworkでもCSRFトークンは必要ですか?

SessionAuthenticationを使う場合は必要です。

Cookieを使わないBearer Token方式では典型的なCookie型CSRFは成立しにくくなりますが、トークン保存場所、CORS、XSSを別途確認します。


Q6. csrf_exemptはいつ使えますか?

外部Webhookなど、ブラウザのCookie認証を利用しないエンドポイントで使う場合があります。

その場合もHMAC署名、公開鍵署名、タイムスタンプ、リプレイ防止などの代替認証が必要です。


Q7. CSRFとSSRFは同じですか?

異なります。

CSRFは利用者のブラウザに偽のリクエストを送らせる攻撃です。

SSRFはサーバー自身に内部・外部の別URLへリクエストさせる攻撃です。


Q8. CSRFトークンが漏れたらどうなりますか?

有効なセッションに対応するトークンが攻撃者へ漏れると、防御を突破される可能性があります。

URL、ログ、外部フォーム、Refererへ漏らさず、XSS対策も行います。


Q9. Cloudflare WAFでCSRFを完全に防げますか?

困難です。

WAFはOrigin、Fetch Metadata、レート制限などの補助防御に使えますが、利用者の意図を確認するCSRFトークン検証はアプリケーション側で行います。


Q10. DjangoでCSRF 403が急増したら攻撃ですか?

攻撃とは限りません。

フロントエンド更新、Cookie属性変更、CloudflareやNginxのスキーム判定、CSRF_TRUSTED_ORIGINS不足などでも増加します。

エラーログ、Origin、Referer、URL、デプロイ時刻を照合して判断します。


参考情報