対象:Djangoでアプリを運営している人。ここでは攻撃手順は扱わず、本番を固めるための実務リファレンス(優先度つきチェックリスト・領域別対策・自己検証)を示します。フレームワーク全体の考え方は フレームワーク別セキュリティの一覧 も参照。
優先度つきハードニング・チェックリスト
まずこの表を上から実施します。P0は前提、P1が最頻の事故源、P2は継続的な運用で守る項目です。
P0 ── 前提(まずこれ)
本番DEBUG=False+ALLOWED_HOSTS / SECRET_KEYを外部化 / pip依存CVE即パッチ
P1 ── 最頻の事故源
本番セキュリティ設定(SSL/HSTS/Cookie) / 認可(所有者スコープ)
P2 ── 継続的な運用
インジェクションと出力 / CSRF・セッション・管理画面 / SSRF・アップロード
| 優先 | 対策 | 具体(Django) |
|---|---|---|
| P0 | DEBUG/ALLOWED_HOSTS | 本番 DEBUG=False+ALLOWED_HOSTS を正しく。詳細エラーを外部に出さない |
| P0 | SECRET_KEY | コード/リポジトリに書かず環境から。漏洩時ローテーション |
| P0 | pip依存CVE | pip-audit / osv-scanner で監視・実稼働版で判定し即パッチ |
| P1 | 本番セキュリティ設定 | SECURE_SSL_REDIRECT・SECURE_HSTS_SECONDS・SESSION_COOKIE_SECURE・CSRF_COOKIE_SECURE・SECURE_CONTENT_TYPE_NOSNIFF |
| P1 | 認可を明示 | ログイン必須+権限+filter(user=request.user) 等で所有者スコープ |
| P2 | インジェクション/出力 | ORMでバインド。raw()/extra() の連結を避ける。mark_safe/` |
| P2 | CSRF/セッション/管理画面 | CSRF(既定)を無効化しない。管理画面(admin)の露出を絞る |
| P2 | SSRF/アップロード | サーバー側取得は許可先限定+内部IP遮断。アップロード検証+公開面外に保存 |
1. DEBUG と ALLOWED_HOSTS(P0)
- 本番では**
DEBUG=False**を確実に。有効だとエラー画面に設定・環境変数・スタックトレースが露出し、わざとエラーを起こされると読み取られる。 ALLOWED_HOSTSを正しく設定し、想定外ホストでの動作を防ぐ。詳細エラーの外部露出を止める。
2. SECRET_KEY(P0)
SECRET_KEYは署名Cookie・セッション・CSRFトークン・パスワードリセットの署名に使われる鍵。環境変数や秘密管理から読み込み、コード/リポジトリに書かない。- 漏洩したら速やかにローテーション。公開ディレクトリやDEBUG画面から露出させない(→ 公開ディレクトリに秘密を置かない)。
3. 依存(pip)のCVE(P0)
- pip-audit や osv-scanner で既知CVEを機械監視し、実稼働版で判定して即パッチ(→ 依存のCVE監視 / CVE対応の実務)。
- Django と Python をサポート対象バージョンに保ち、EOL版を放置しない。
4. 本番セキュリティ設定(P1)
Djangoは SecurityMiddleware 経由で多くの防御を設定できます。本番向けに次を設定します。
SECURE_SSL_REDIRECT(HTTPS強制)・SECURE_HSTS_SECONDS(+INCLUDE_SUBDOMAINS/PRELOAD)SESSION_COOKIE_SECURE/CSRF_COOKIE_SECURE(CookieをHTTPS限定に)SECURE_CONTENT_TYPE_NOSNIFF等manage.py check --deployで、これらの設定漏れを機械的に洗い出す。
5. 認可(P1・最多の事故源)
やりがち(危険)
- ログイン必須だが所有者スコープが無い
- クエリセットが全件で、IDでの絞り込みが無い
- 隠しただけのURL/推測しにくいIDに依存
- 一部ビューで権限チェックを通し忘れ
正しい
- ログイン必須+権限チェックを明示
- 取得も
filter(user=request.user)等で所有者に限定 - 取得・更新・削除のすべての経路で確認
- 認可は明示的に組み立て、既定任せにしない
用語は IDORとは。認証と認可は別物で、認可はデータに近い場所で確認します。
6. インジェクションと出力(P2)
- SQL:ORMはバインドする。
raw()/extra()や文字列連結でクエリを組まない(→ SQLインジェクションとは)。 - XSS:テンプレートは既定で自動エスケープ。
mark_safe/|safeにユーザー入力を渡さない(→ XSSとは)。 - デシリアライズ:信頼できない
pickleを読み込まない(コード実行に繋がり得る)。
7. CSRF・セッション・管理画面(P2)
- CSRF保護(既定)を無効化しない(→ CSRFとは)。
- 管理画面(admin)の露出を絞る(アクセス制限・URL変更・多要素認証)。クリックジャッキング対策(
X-Frame-Options既定)を活かす。 - セッションにも secure/httponly/samesite・ログイン時再生成を効かせる。
8. SSRF・アップロード・ヘッダ(P2)
- サーバーがユーザー指定URLを取得する処理は許可先を限定し、内部IP/メタデータへの到達を遮断する(→ SSRFとは)。
- アップロードは種別・サイズを検証し、公開面の外に保存する。
- 自サイトのヘッダは セキュリティヘッダ診断 で確認できる。
検証:自分のDjangoは固められているか
作ったら終わりではありません。点検して初めて完了です。以下は自分の環境に対する防御的な自己チェックです。
設定漏れを機械点検
python manage.py check --deploy を実行し、警告が解消されていることを確認。本番でDEBUGが露出しないか
認可が効くか
秘密と依存
SECRET_KEY がリポジトリに無いこと、pip-audit/osv がクリーンかを確認。当サイトの視点:標準機能が充実していても、設定と認可は自分の責任
Djangoは多くを既定で守りますが、本番の設定(DEBUG/SECRET_KEY/ALLOWED_HOSTS/SSL)と認可だけは、環境ごと・アプリごとに自分で正しく決める必要があります。当サイトが繰り返し見る事故も、凝った攻撃より「本番でデバッグが開いていた」「秘密が露出していた」「認可が無かった」という設定・運用の型が中心です。だから重点は、本番設定を正しくし、秘密を非公開に保ち、認可を明示すること。check --deploy を運用に組み込むのが近道です。
次に読む
- 一覧:フレームワーク別セキュリティ(一覧) / Laravelのセキュリティ対策(本番DEBUG・秘密露出が近い)
- 実務:脆弱性(CVE)対応の実務 / 依存のCVE監視 / 公開ディレクトリに秘密を置かない
- 用語:IDORとは / SQLインジェクション / XSS / CSRF / SSRF
- ツール:セキュリティヘッダ診断
出典と確認範囲
以下は上記の設定・影響範囲・対策を確認するための原典です。2026年10月23日に参照先を確認しました。各版・構成の条件は原典で確認してください。チェックリストの優先順位や教訓は当サイトの整理であり、記事全体の再検証や安全性の保証を意味しません。