対象: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
- ツール:セキュリティヘッダ診断
よくある質問
QDjangoで最初にやるべきセキュリティ対策は何ですか?
優先度P0の3つです。(1)本番で DEBUG=False を確実にし ALLOWED_HOSTS を正しく設定する、(2)SECRET_KEY をコード/リポジトリに書かず環境から読み込み漏洩時はローテーションする、(3)pip依存のCVEを機械監視し実稼働版で判定して即パッチ。次に本番セキュリティ設定(SSL/HSTS/Cookie)と認可へ進みます。manage.py check --deploy で設定漏れを機械点検できます。
Q本番で DEBUG=True のままだと何が危険ですか?
DEBUGが有効だと、エラー画面に設定値・環境変数・スタックトレースなど内部情報が詳しく表示され得ます。攻撃者はわざとエラーを起こして情報を引き出せます。本番では必ず DEBUG=False にし、ALLOWED_HOSTS を正しく設定してください。あわせて詳細エラーの外部露出を止め、静的/メディア配信も本番向けに見直します。
QSECRET_KEY はなぜ重要ですか?
SECRET_KEY は署名付きCookieやセッション、CSRFトークン、パスワードリセットなどの土台になる鍵です。漏えいするとこれらの偽造や改ざんに繋がり得ます。コードやリポジトリに書かず、環境変数や秘密管理から読み込み、万一漏れたら速やかにローテーションしてください。公開ディレクトリやDEBUG画面から露出させないことも重要です。
QDjangoの本番セキュリティ設定で見るべき項目は?
SecurityMiddleware 関連が中心です。SECURE_SSL_REDIRECT(HTTPS強制)、SECURE_HSTS_SECONDS(HSTS)、SESSION_COOKIE_SECURE / CSRF_COOKIE_SECURE(Cookieをsecureに)、SECURE_CONTENT_TYPE_NOSNIFF などを本番向けに設定します。manage.py check --deploy を実行すると、これらの設定漏れを機械的に洗い出せます。
Q依存パッケージ(pip)の脆弱性はどう管理しますか?
pip-audit や osv-scanner で既知CVEを機械監視し、『実稼働版』で判定して素早くパッチします。Django 本体と Python をサポート対象バージョンに保ち、EOL版を放置しないこと。依存の鮮度は、凝った攻撃より事故を分ける現実的な要因です。