Django 5.2.15以前の脆弱性と重大バグを解説――SQLインジェクション、キャッシュ漏えい、ASGIのDoSに注意

Django 5.2.15以前の脆弱性と重大バグを解説――SQLインジェクション、キャッシュ漏えい、ASGIのDoSに注意
目次

この記事は既に古くなっています。

Django 5.2.16の脆弱性4件とは?RCE・SSRF・DoS・XSSの影響と5.2.17への更新方法

https://kurutann.com/diary/detail/6240/



Django 5.2.15以前の脆弱性と重大バグを解説――SQLインジェクション、キャッシュ漏えい、ASGIのDoSに注意



2026年7月27日現在、Django 5.2系を利用する場合は、少なくともDjango 5.2.16へ更新する必要があります。

Django 5.2は長期サポート版、いわゆるLTSです。しかし、LTSであることは「古いパッチバージョンを使い続けても安全」という意味ではありません。

Django 5.2.0から5.2.15までには、SQLインジェクション、サービス拒否、共有キャッシュからの情報漏えい、セッション固定、管理画面の権限検証不備、暗号化されないメール送信など、複数の問題が確認されています。

特に、次の構成では影響を詳しく確認してください。

  • Django ORMへ動的な辞書を渡している

  • Gunicorn+UvicornやDaphneなどのASGI構成

  • Redisを共有キャッシュとして利用している

  • cache_page()UpdateCacheMiddlewareを利用している

  • Django Adminを業務管理画面として利用している

  • ファイルアップロード機能がある

  • SMTPのSTARTTLSでメールを送信している

  • PostGISやGeoDjangoを利用している

この記事では、Django 5.2.15以前に存在する主要な脆弱性とバグ、その確認方法、更新手順、動作確認、再発防止策を解説します。


結論・要点

結論は次のとおりです。

Django 5.2.15以前を使用している場合は、Django 5.2.16以上へ更新してください。

Django 5.2.16は、2026年7月7日に公開されました。Django公式は、5.2.15に存在する3件のLow評価のセキュリティ問題を修正したとしています。Django 5.2はLTSとして2028年4月まで延長サポートされますが、公式は同一系列の最新パッチを利用することを推奨しています。

今回、Django 5.2.0から5.2.15までの公式リリースノートを確認すると、Django 5.2.16までに33件の異なるCVEが修正されています。

ただし、すべての環境で33件すべてが攻撃可能になるわけではありません。

成立条件は、利用しているデータベース、OS、ASGI・WSGI構成、キャッシュ設定、メール設定、管理画面の使い方などによって異なります。

優先度の高い対応

優先度対応
最優先Django 5.2.16以上へ更新する
ユーザー入力をORMの**kwargsへ直接展開していないか確認する
ASGI環境のアップロード上限とHTTPヘッダー制限を確認する
Redis共有キャッシュに認証済みレスポンスを保存していないか確認する
Django Adminの権限、list_editable、Generic Inlineを確認する
STARTTLS失敗時のメール送信ログを確認する
Django更新後にデータ整合性とキャッシュ分離をテストする

この記事で分かること

この記事では、次の内容が分かります。

  • Django 5.2.15以前に存在する脆弱性

  • 自分のシステムが影響を受けるか判断する方法

  • SQLインジェクションが成立するコード例

  • ASGIやファイルアップロードに関するDoSの仕組み

  • Redis共有キャッシュから情報が漏れる条件

  • Django Adminの権限検証問題

  • 実務向けの更新手順

  • 更新後の動作確認方法

  • WAF、IPS、EDRで補助できる範囲

  • 今後同じ問題を見落とさないための運用方法


対象読者・前提環境

この記事は、次の読者を対象にしています。

  • Django 5.2を本番運用しているエンジニア

  • Djangoの脆弱性対応を担当するインフラ・セキュリティ担当者

  • Django Adminを業務システムとして利用している担当者

  • Redis、PostgreSQL、Gunicorn、Uvicornを利用している担当者

  • Docker環境でDjangoを運用している担当者

想定する構成例は次のとおりです。

Internet
   │
   ▼
Nginx/Cloudflare/ALB
   │
   ▼
Gunicorn+Uvicorn
   │
   ▼
Django 5.2
   ├─ PostgreSQL
   ├─ Redis
   ├─ SMTP
   └─ ファイルストレージ

Django 5.2はPython 3.10から3.14までをサポートしています。Python 3.14対応はDjango 5.2.8で追加されました。


Django 5.2.15以前で何が起きたのか

Django 5.2系列では、主に次の種類の問題が修正されました。

Django 5.2.15以前
   │
   ├─ ORM
   │   └─ SQLインジェクション
   │
   ├─ ASGI/HTTP
   │   ├─ メモリ枯渇
   │   ├─大量ヘッダーによるDoS
   │   └─ ヘッダー偽装
   │
   ├─ キャッシュ
   │   ├─ 個人情報の共有
   │   ├─ Authorization分離不足
   │   └─ セッション固定
   │
   ├─ Django Admin
   │   └─ 権限検証の不備
   │
   ├─ メール
   │   └─ STARTTLS失敗後の平文送信
   │
   └─ ファイル・文字列処理
       ├─ ディレクトリトラバーサル
       ├─ ファイル権限の不整合
       └─ 計算量を悪用したDoS

特に件数が多いのは、ORMへ動的な辞書を渡した場合のSQLインジェクションと、特殊な入力を大量に処理させるDoSです。


Django 5.2.15以前に存在する脆弱性一覧

Django 5.2.15で未修正だった脆弱性

Django 5.2.15には、Django 5.2.16で修正された3件の問題があります。

CVE-2026-48588:共有キャッシュからの非公開データ露出

UpdateCacheMiddlewareまたはcache_page()を利用している場合、Cookieによって内容が変わるレスポンスが共有キャッシュへ保存される可能性がありました。

問題となる条件は次のとおりです。

  1. リクエストに言語設定やテーマ設定など、無関係なCookieが付いている

  2. レスポンスがセッションCookieなどを新しく設定する

  3. レスポンスがRedisなどの共有キャッシュへ保存される

  4. 別の利用者へキャッシュ済みレスポンスが返される

たとえるなら、本来は個人ごとに渡す封筒を、共有の書類棚へ置いてしまう状態です。

CVE-2026-48588はDjango 5.2から5.2.15までが影響対象で、5.2.16で修正されています。Django Software FoundationによるCVSS v4.0評価は2.3、Lowです。

CVE-2026-53877:GDALRasterのヒープ領域読み過ぎ

GDALRasterへラスターファイルのバイト列を渡した場合、確保されたヒープ領域を約32バイト超えて読み取る可能性がありました。

結果として、隣接メモリの情報が露出したり、まれにセグメンテーションフォルトが発生したりする可能性があります。

影響するのは、GDALの仮想ファイルシステムに保存されるラスターデータです。GeoDjangoやラスターファイルを利用していないシステムでは、通常は直接関係しません。

CVE-2026-53878:DomainNameValidatorによる改行受け入れ

DomainNameValidatorが、ドメイン名に含まれる改行を受け入れる問題です。

検証済みの値を独自コードでHTTPヘッダーへ設定した場合、ヘッダーインジェクションにつながる可能性があります。

Django標準のHttpResponseはHTTPヘッダー内の改行を拒否します。そのため、通常のDjangoレスポンスだけで攻撃が成立するわけではありません。

次のような独自処理がある場合に確認が必要です。

validator = DomainNameValidator()
validator(user_input)

external_response.headers["X-Target-Domain"] = user_input

フォームのCharFieldは通常、改行を除去するため、問題は主にフォーム外でDomainNameValidatorを直接利用しているコードです。


Django 5.2.14までに存在した脆弱性

Django 5.2.15では、5件のLow評価の脆弱性が修正されました。

CVE内容主な成立条件
CVE-2026-6873署名Cookieのsalt名前空間衝突Cookie名とsaltの異なる組み合わせが同じ連結値になる
CVE-2026-7666STARTTLS失敗後の平文メール送信EMAIL_USE_TLS=True、TLS失敗、接続再利用
CVE-2026-8404Cache-Controlの大文字小文字処理不備手動でPrivateなどを設定
CVE-2026-35193Vary: Authorization不足Authorization付きレスポンスをキャッシュ
CVE-2026-48587Vary値の空白処理不備空白付きのVary: *をキャッシュ

STARTTLSの問題

CVE-2026-7666では、STARTTLSハンドシェイクに失敗した後、部分的に初期化されたSMTP接続が再利用され、暗号化されていない状態でメールが送信される可能性がありました。

次の設定が該当します。

EMAIL_USE_TLS = True

EMAIL_USE_SSL=Trueの接続は影響を受けません。

パスワードリセット、ワンタイムパスワード、管理者通知、問い合わせ内容などをメール送信しているシステムでは、優先して確認してください。

署名Cookieの互換性に関する注意

CVE-2026-6873の修正後も、互換性確保のため、古いDjangoで署名されたCookieはDjango 7.0まで受け入れられます。

問題となるCookie名とsaltの組み合わせを実際に利用していた場合は、次の設定で古い署名方式を即時拒否できます。

SIGNED_COOKIE_LEGACY_SALT_FALLBACK = False

この設定を変更すると、既存Cookieが無効になる可能性があります。

本番反映前に、ログインセッション、Remember Me、独自署名Cookieなどの影響を確認してください。


Django 5.2.13までに存在した脆弱性

Django 5.2.14では、次の3件が修正されました。

CVE内容深刻度
CVE-2026-5766ASGIファイルアップロード上限の回避Low
CVE-2026-35192公開キャッシュページによるセッション固定Low
CVE-2026-6907Vary: *レスポンスの誤キャッシュLow

CVE-2026-5766:ファイルアップロードによるメモリ枯渇

Content-Lengthが存在しない、または実際より小さいASGIリクエストを送信することで、FILE_UPLOAD_MAX_MEMORY_SIZEを回避できる可能性がありました。

大容量ファイルがメモリへ読み込まれると、次の影響が考えられます。

  • Djangoワーカーのメモリ使用量増加

  • OOM Killerによるプロセス停止

  • レスポンス遅延

  • 同時接続処理能力の低下

  • VPS全体の不安定化

Django公式も、Django設定だけに依存せず、Webサーバー側でアップロード上限を設定することを求めています。

CVE-2026-35192:セッション固定

次の条件が重なる場合、公開キャッシュページを通じてセッションが盗まれる可能性がありました。

SESSION_SAVE_EVERY_REQUEST = True

加えて、レスポンスが共有キャッシュへ保存される構成が必要です。

Redisキャッシュを複数ユーザーで共有し、認証前後のページにcache_page()を適用している場合は特に確認してください。


Django 5.2.12までに存在した脆弱性

Django 5.2.13では、1件のModerateと4件のLowが修正されました。

CVE内容深刻度
CVE-2026-3902ASGIでのアンダースコア/ハイフンを利用したヘッダー偽装Low
CVE-2026-4277GenericInlineModelAdminの追加権限検証不備Low
CVE-2026-4292ModelAdmin.list_editableから新規インスタンス作成Low
CVE-2026-33033base64ファイルアップロードによるDoSModerate
CVE-2026-33034ASGIリクエスト本文のメモリ上限回避Low

CVE-2026-3902:ASGIヘッダー偽装

リバースプロキシが次のヘッダーを削除していたとします。

X-Authenticated-User

攻撃者が代わりに次のヘッダーを送信した場合、ASGIRequestの正規化によって同じ名前として扱われる可能性がありました。

X_Authenticated_User

Django 5.2.13以降は、アンダースコアを含むASGIヘッダーを無視します。

Nginxでは標準的にアンダースコア付きヘッダーを拒否する構成が多いものの、Django側の更新は必要です。

Django Adminの権限検証不備

CVE-2026-4277とCVE-2026-4292は、誰でも管理者権限を取得できる問題ではありません。

攻撃には、基本的にDjango Adminへログインできる制限付きユーザーが必要です。

ただし、部署別・顧客別に細かく権限を分離している業務システムでは重要です。

攻撃者が細工したPOSTデータを送信すると、本来は追加権限を持たないモデルのインスタンスを作成できる可能性がありました。


Django 5.2.11までに存在した脆弱性

Django 5.2.12では、次の2件が修正されました。

CVE内容深刻度
CVE-2026-25673Windows上のURLFieldによるDoSModerate
CVE-2026-25674新規ファイル・ディレクトリの権限不整合Low

CVE-2026-25674では、ファイルストレージとファイルベースキャッシュが、ディレクトリ作成時にプロセス全体のumaskを一時変更していました。

マルチスレッド環境では、別スレッドによるファイル作成にも一時的なumaskが適用され、意図しないアクセス権でファイルが作成される可能性がありました。

修正版では、ディレクトリ作成後にchmod()を利用して権限を適用します。


Django 5.2.10までに存在した脆弱性

Django 5.2.11では、Highが3件、Moderateが2件、Lowが1件修正されました。

CVE内容深刻度
CVE-2025-13473mod_wsgi認証の応答時間差によるユーザー列挙Low
CVE-2025-14550ASGIの重複ヘッダー処理によるDoSModerate
CVE-2026-1207PostGISラスタールックアップのSQLインジェクションHigh
CVE-2026-1285TruncatorのHTML処理によるDoSModerate
CVE-2026-1287制御文字を含む列エイリアスからのSQLインジェクションHigh
CVE-2026-1312order_by()FilteredRelationによるSQLインジェクションHigh

重複HTTPヘッダーによるDoS

CVE-2025-14550では、同じ名前のHTTPヘッダーを大量に送ることで、ASGIRequest内部の文字列連結処理が非常に重くなる可能性がありました。

処理時間が入力サイズに比例せず、急激に増える「超線形」の処理となるため、少数のリクエストでもCPU負荷が高くなる可能性があります。

PostGIS限定のSQLインジェクション

CVE-2026-1207は、PostGISのラスターフィールドを利用している環境が対象です。

ユーザー入力をバンド番号として直接指定した場合、SQLインジェクションが成立する可能性がありました。

GeoDjangoをインストールしているだけではなく、PostGISのラスタールックアップを実際に利用しているかを確認してください。


Django 5.2.9までに存在した脆弱性

Django 5.2.10は、セキュリティリリースではありません。しかし、PostgreSQL環境でデータ損失につながる重要な不具合を修正しています。

QuerySet.bulk_create()max_lengthを超えたデータを保存した場合、エラーにならず、文字列が暗黙に切り詰められる可能性がありました。

これは攻撃を目的とした脆弱性ではありませんが、次のようなデータを扱う場合は重大です。

  • 顧客番号

  • メールアドレス

  • 決済識別子

  • APIキー

  • 外部サービスのID

  • ハッシュ値

  • 監査用のイベントID

保存済みデータがすでに切り詰められていないか、更新後に確認してください。


Django 5.2.8までに存在した脆弱性

Django 5.2.9では、次の2件が修正されました。

CVE内容深刻度
CVE-2025-13372PostgreSQL上のFilteredRelation列エイリアスによるSQLインジェクションHigh
CVE-2025-64460XMLデシリアライザーの二次時間処理によるDoSModerate

XMLデシリアライザーの問題は、多数の不正なネスト要素を含むXMLを読み込ませることで成立します。

XML形式のfixtureや外部XMLインポート機能を、信頼できない利用者へ公開している場合に確認が必要です。


Django 5.2.7までに存在した脆弱性

Django 5.2.8では、次の2件が修正されました。

CVE内容深刻度
CVE-2025-64458Windows上のリダイレクト処理によるDoSModerate
CVE-2025-64459_connector引数を利用したSQLインジェクションHigh

CVE-2025-64459は、次のような実装が危険です。

filters = request.data
queryset = Customer.objects.filter(**filters)

ユーザーが次のような内部用キーワードを含む辞書を送信できる場合、SQL生成へ影響を与える可能性がありました。

{
  "_connector": "不正な入力"
}

最新版へ更新しても、ユーザー入力を無制限に**kwargsへ展開する設計は避けるべきです。

安全な実装例は次のとおりです。

ALLOWED_FILTERS = {
    "status",
    "created_at__gte",
    "created_at__lte",
    "customer_no",
}

raw_filters = request.data
safe_filters = {
    key: value
    for key, value in raw_filters.items()
    if key in ALLOWED_FILTERS
}

queryset = Customer.objects.filter(**safe_filters)

Django 5.2.6までに存在した脆弱性

Django 5.2.7では、次の2件が修正されました。

CVE内容深刻度
CVE-2025-59681MySQL・MariaDBの列エイリアスによるSQLインジェクションHigh
CVE-2025-59682archive.extract()の部分的ディレクトリトラバーサルLow

CVE-2025-59682は、次の機能にも関係します。

python manage.py startapp --template
python manage.py startproject --template

外部から取得したテンプレートアーカイブを利用するCI/CDや、自動プロジェクト生成サービスでは注意が必要です。

本番Webリクエストから直接startappを実行していない一般的な環境では、攻撃面は限定的です。


Django 5.2.5までに存在した脆弱性

Django 5.2.6では、CVE-2025-57833が修正されました。

FilteredRelationの列エイリアスへ、細工した辞書を**kwargsとして渡すことで、SQLインジェクションが成立する可能性がありました。Django公式の深刻度はHighです。


Django 5.2.0から5.2.5までの重要バグ

Django 5.2.4と5.2.5では、主に通常の不具合が修正されました。

特に実務影響が考えられる問題は次のとおりです。

修正版不具合
5.2.5外部キーを含むPostgreSQLのbulk_create()でUNNEST戦略が利用できない
5.2.5複合主キーを利用したフィルターやManyToManyでクラッシュ
5.2.4Acceptヘッダーの優先順位を誤る
5.2.4JSONのnullをSQLのNULLとして扱う
5.2.3bulk_update()がSQL NULLをJSON nullへ変換
5.2.2OuterRefを使った集計処理がクラッシュ
5.2.2Django AdminのEnter送信をボタンが妨害
5.2.1file_move_safe()で古いファイル内容が末尾に残る
5.2.1nullable外部キーのprefetchで不要なSQLが増える

これらは、データ破損、誤った検索結果、500エラー、パフォーマンス劣化につながる可能性があります。

file_move_safe()のデータ破損

Django 5.2.0では、allow_overwrite=Trueで大きなファイルを小さなファイルに上書きした場合、以前のファイルの末尾が残る可能性がありました。

たとえば、10KBのファイルを5KBのファイルで上書きしても、ファイル自体が5KBへ切り詰められず、古いデータが残る状態です。

Django 5.2.1で修正されています。


Django 5.2.0と5.2.1に存在した初期の脆弱性

CVE-2025-32873:strip_tagsによるDoS

strip_tags()やテンプレートのstriptagsフィルターへ、大量の閉じられていないHTMLタグを与えると、処理が非常に遅くなる可能性がありました。

Django 5.2.1では、異常に多くの閉じられていないタグを検出した場合、SuspiciousOperationを送出するよう修正されました。

CVE-2025-48432:ログインジェクション

リクエストパスに改行やANSIエスケープシーケンスを含めることで、Djangoのログ表示を偽装できる可能性がありました。

想定される影響は次のとおりです。

  • 偽のエラーログを挿入する

  • ログ行を分割する

  • ターミナル表示を変更する

  • SIEMやログ解析ツールの判定を妨害する

Django 5.2.2で最初の修正が行われ、Django 5.2.3で対策が補完されました。


自分のシステムに関係するか

影響確認表

利用機能関連する主な問題確認優先度
Redis共有キャッシュCVE-2026-48588など
cache_page()キャッシュ漏えい、セッション固定
UpdateCacheMiddlewareキャッシュ漏えい
Gunicorn+UvicornASGI DoS、ヘッダー偽装
Django Channels/DaphneASGI DoS、ヘッダー偽装
動的なORMフィルター複数のSQLインジェクション
PostgreSQLFilteredRelation、bulk_createの問題
MySQL/MariaDB列エイリアスSQLインジェクション
PostGISラスターSQLインジェクション
Django Admin権限検証不備
SMTP STARTTLS平文メール送信
WindowsサーバーURL・リダイレクトDoS
XMLインポートXMLデシリアライズDoS
GeoDjango/GDALヒープ領域読み過ぎ
startapp --templateディレクトリトラバーサル低~中

確認方法

Djangoのバージョンを確認する

目的: 実際に稼働しているDjangoのバージョンを確認する
実行場所: Djangoの仮想環境、またはDjangoコンテナ内

python -m django --version

正常例:

5.2.16

更新が必要な例:

5.2.15

結果の判断:

5.2.15以前 → 更新が必要
5.2.16以上 → 今回取り上げた問題は修正済み

複数のPython環境がある場合は、次のコマンドも確認します。

python -m pip show Django
python -m pip freeze | grep -i '^django=='

コード内の危険な利用箇所を検索する

目的: 今回の脆弱性に関係するAPIや設定の利用箇所を探す
実行場所: Djangoプロジェクトのルートディレクトリ

rg -n \
  "cache_page|UpdateCacheMiddleware|SESSION_SAVE_EVERY_REQUEST|EMAIL_USE_TLS|FilteredRelation|list_editable|GenericInlineModelAdmin|GDALRaster|DomainNameValidator|strip_tags|striptags|archive\.extract|XMLDeserializer|bulk_create|annotate\(\*\*|alias\(\*\*|aggregate\(\*\*|filter\(\*\*|exclude\(\*\*|order_by" \
  .

正常例:

settings.py:120:EMAIL_USE_TLS = True
app/views.py:32:@cache_page(300)

異常の可能性がある例:

app/views.py:85:queryset = Customer.objects.filter(**request.data)

結果の判断:

  • 検索結果があるだけでは脆弱とは断定できない

  • ユーザー入力がそのまま渡されていないか確認する

  • 認証済みレスポンスを共有キャッシュへ保存していないか確認する

  • 管理画面権限がモデル単位で適切に分離されているか確認する


キャッシュ設定を確認する

次の設定を確認します。

MIDDLEWARE = [
    # UpdateCacheMiddlewareが含まれていないか
]

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
    }
}

SESSION_SAVE_EVERY_REQUEST = False

特に次のコードを、ログイン画面、マイページ、管理画面、APIレスポンスへ適用していないか確認してください。

@cache_page(300)
def my_page(request):
    ...

認証状態やCookieによって内容が変わるレスポンスは、原則として共有キャッシュへ保存しない設計が安全です。


SMTP設定を確認する

EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
EMAIL_HOST = "smtp.example.com"
EMAIL_PORT = 587

ログで次のような事象を確認します。

STARTTLS extension not supported
TLS handshake failed
SMTPServerDisconnected
SSLError

TLSエラー後にもメール送信成功ログが残っていた場合は、送信経路を詳しく調査してください。


対処方法

Django 5.2.16へ更新する

更新前に、次のバックアップを取得してください。

  • requirements.txtまたはロックファイル

  • Dockerイメージの現在タグ

  • データベース

  • メディアファイル

  • 環境変数と設定ファイル

  • Redisをセッション保存先として利用している場合はセッション影響の確認

pip環境

目的: Django 5.2.16へ更新する
実行場所: 仮想環境内

python -m pip install --upgrade "Django==5.2.16"

依存関係を記録します。

python -m pip freeze > requirements.lock.txt

正常例:

Successfully installed Django-5.2.16

異常例:

ERROR: Cannot install Django==5.2.16 because these package versions have conflicting dependencies

異常時の判断:

  • Django REST Framework

  • django-filter

  • django-allauth

  • Channels

  • CMSパッケージ

  • 独自認証パッケージ

などの対応バージョンを確認します。


requirements.txtの推奨指定

完全固定する場合:

Django==5.2.16

5.2系のセキュリティパッチを許可する場合:

Django>=5.2.16,<5.3

本番環境では、ビルド時に意図しない更新が発生しないよう、最終的なロックファイルを保持する方法が安全です。


Docker環境

目的: Django更新済みの新しいコンテナイメージを作成する
実行場所: compose.yamlまたはdocker-compose.ymlのあるディレクトリ

docker compose build --pull web

起動前確認:

docker compose run --rm web python -m django --version
docker compose run --rm web python manage.py check
docker compose run --rm web python manage.py test

反映:

docker compose up -d --no-deps web

正常例:

System check identified no issues

異常例:

SystemCheckError
ImportError
ModuleNotFoundError

異常がある場合、新しいコンテナを本番トラフィックへ接続しないでください。

以前のイメージタグを保持し、すぐにロールバックできる状態にします。


Nginxによる補助対策

ASGIのアップロード上限回避やDoSに対しては、Django更新に加え、Nginx側でも制限します。

以下は一例です。実際の値は、サービスのファイルサイズや通信要件に合わせて調整してください。

server {
    client_max_body_size 20m;
    client_body_timeout 15s;
    client_header_timeout 15s;

    large_client_header_buffers 4 8k;

    underscores_in_headers off;

    location / {
        proxy_pass http://django_upstream;
    }
}

設定確認:

sudo nginx -t

正常例:

syntax is ok
test is successful

反映:

sudo systemctl reload nginx

注意点:

  • client_max_body_sizeを小さくしすぎると正規ユーザーのアップロードが失敗する

  • WebSocket通信へ短すぎるタイムアウトを適用しない

  • 管理画面と一般公開APIで上限を分ける方法も有効

  • CloudflareやALB側の上限も確認する


動作確認

Djangoのシステムチェック

python manage.py check
python manage.py check --deploy

check --deployでは、HTTPS、Cookie、HSTS、DEBUGなど、本番向け設定に関する警告も確認できます。


マイグレーション差分の確認

python manage.py makemigrations --check --dry-run

正常例:

No changes detected

意図しない例:

Migrations for 'accounts':
  accounts/migrations/...

Djangoのパッチ更新だけで、無関係なモデル変更が発生していないか確認します。


自動テスト

python manage.py test

pytestを利用している場合:

pytest -q

警告も確認する場合:

python -Wa manage.py test

特にテストすべき機能は次のとおりです。

  • ログイン、ログアウト

  • パスワードリセット

  • メール送信

  • ファイルアップロード

  • Django Adminの追加・編集権限

  • APIの動的フィルター

  • Redisキャッシュ

  • セッション

  • WebSocket接続

  • bulk_create()を利用するバッチ

  • XMLインポート

  • GeoDjango機能


キャッシュ分離テスト

次の手順で、利用者間の情報混在がないことを確認します。

  1. ユーザーAでログインする

  2. テーマCookieや言語Cookieを設定する

  3. キャッシュ対象ページへアクセスする

  4. ユーザーBまたは未ログインブラウザで同じページへアクセスする

  5. ユーザーAの名前、Cookie、個人情報が表示されないことを確認する

  6. Redisのキャッシュキーがユーザー状態に応じて分離されているか確認する

個人情報が表示された場合は、キャッシュを無効化して原因を調査してください。


データ切り詰めの確認

Django 5.2.9以前でPostgreSQLのbulk_create()を利用していた場合は、対象カラムを確認します。

例:

SELECT
    id,
    customer_no,
    LENGTH(customer_no) AS current_length
FROM customer
WHERE LENGTH(customer_no) >= 20;

目的:

  • max_length付近のデータを抽出する

  • 外部システムの元データと照合する

  • 途中で切り詰められたデータがないか確認する

本番データを直接更新する前に、必ずバックアップを取得してください。


WAF・IPS・EDRによる補助対策

WAF

WAFは次の攻撃に対して補助的に利用できます。

  • 大量リクエストのレート制限

  • 異常に大きなリクエスト本文

  • 大量の重複HTTPヘッダー

  • 一般的なSQLインジェクション文字列

  • 不自然なmultipartリクエスト

ただし、今回のSQLインジェクションは、ORMの列エイリアスや辞書展開を経由します。

一般的なUNION SELECT型の攻撃文字列が現れない可能性があるため、WAFだけで確実に防げるとは限りません。

IPS

IPSでは次の検知が考えられます。

  • 同一IPからの大量アップロード

  • 異常なContent-Length

  • 重複ヘッダーの大量送信

  • 不自然なbase64 multipart

  • 異常なURL長

  • 管理画面への不自然なPOST

しかし、正規のHTTP形式を利用する攻撃では、誤検知を避けながら完全に遮断することは困難です。

EDR

EDRでは次の事象を補助的に確認できます。

  • Djangoワーカーのメモリ急増

  • CPU使用率の急上昇

  • セグメンテーションフォルト

  • 予期しないファイル権限変更

  • SMTPの平文通信

  • 不自然な管理画面操作

  • Webプロセスからの異常なファイルアクセス

補助対策の限界

問題WAF・IPS・EDRの有効性
SQLインジェクション一部検知可能だがパッチが必須
キャッシュ漏えい外部装置では検知が難しい
セッション固定アプリ内部の修正が必要
STARTTLS平文送信ネットワーク監視で発見できる場合がある
Admin権限不備監査ログで補助可能
ASGI DoSサイズ制限・レート制限が有効
GDALメモリ読み過ぎEDRでクラッシュを検知できる場合がある

WAFやIPSは、Django本体を更新しないための代替策ではありません。


悪用状況

今回確認したDjango公式のセキュリティ告知には、これらの問題が実際の攻撃で広く悪用されているという記載はありません。

ただし、悪用報告が記載されていないことは、攻撃が存在しないことを意味しません。

特に次の問題は、公開後に再現方法を分析されやすいため、優先して更新する必要があります。

  • SQLインジェクション

  • キャッシュからの情報露出

  • セッション固定

  • ASGIリクエストによるDoS

  • Django Adminの権限検証不備

Django公式は各セキュリティリリースで、対象ユーザーに対して速やかな更新を推奨しています。


再発防止

1. Djangoのパッチバージョンを監視する

Djangoのバージョンを、メジャー・マイナーだけで管理しないでください。

悪い管理例:

Django 5.2を利用中

望ましい管理例:

Django 5.2.16
最終確認日:2026-07-27
次回確認日:毎月第1営業日

2. DependabotやRenovateを導入する

GitHubを利用している場合は、Djangoの新しいパッチリリースをPull Requestとして通知できます。

Dependabot例:

version: 2

updates:
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5

自動マージする場合でも、最低限次のテストを必須にします。

  • manage.py check

  • 単体テスト

  • APIテスト

  • Django Adminテスト

  • キャッシュ分離テスト

  • ファイルアップロードテスト


3. ORMへユーザー入力を直接渡さない

禁止例:

queryset.filter(**request.data)
queryset.annotate(**request.data)
queryset.alias(**request.data)
queryset.aggregate(**request.data)

推奨例:

ALLOWED_SORT_FIELDS = {
    "created_at",
    "-created_at",
    "customer_no",
    "-customer_no",
}

sort = request.GET.get("sort", "-created_at")

if sort not in ALLOWED_SORT_FIELDS:
    sort = "-created_at"

queryset = queryset.order_by(sort)

フィールド名、演算子、並び順をすべてホワイトリスト方式で管理します。


4. 認証済みページを共有キャッシュしない

キャッシュを利用する場合は、次の単位を分離します。

  • ログイン状態

  • ユーザーID

  • テナントID

  • 権限

  • 言語

  • APIのAuthorization

  • セッションCookie

公開コンテンツと個人向けコンテンツを、同じキャッシュキー設計で扱わないでください。


5. ASGIの防御を多層化する

Internet
   │
   ▼
Cloudflare/WAF
   │  レート制限
   ▼
Nginx
   │  本文・ヘッダーサイズ制限
   ▼
ASGI Server
   │  同時実行数・タイムアウト
   ▼
Django
      DATA_UPLOAD_MAX_MEMORY_SIZE
      FILE_UPLOAD_MAX_MEMORY_SIZE

Djangoの設定だけでなく、エッジ、リバースプロキシ、ASGIサーバー、アプリケーションの各層に制限を設けます。


6. Django Adminを一般利用者と分離する

推奨事項は次のとおりです。

  • 管理画面をVPN、ZTNA、IP制限の内側へ置く

  • MFAを導入する

  • モデルごとに追加・変更・削除・閲覧権限を分ける

  • 管理操作を監査ログへ保存する

  • 一般利用者向けドメインと管理画面を分離する

  • list_editableやInlineを利用する画面へ権限テストを追加する


注意点・よくある誤解

「Lowだから更新しなくてよい」は誤り

Django公式のLow評価は、すべての環境で危険性が低いことを保証するものではありません。

たとえば、キャッシュ漏えいは成立条件が限定されるためLowと評価されていても、成立した場合はユーザー情報が別ユーザーへ表示される可能性があります。

自社環境の構成を加味して判断してください。

LTSなら古いパッチでも安全ではない

LTSは、一定期間セキュリティ修正が提供されるという意味です。

修正を受け取るには、最新パッチへ更新する必要があります。

ORMを使えばSQLインジェクションは絶対に起きないわけではない

通常の値をDjango ORMへ渡す場合、DjangoはSQLパラメータを適切に処理します。

一方、列名、エイリアス、演算子、並び順など、SQL構造に影響する入力をユーザーへ自由に指定させると危険です。

WAFを導入すれば更新不要ではない

WAFは攻撃を外側で検査します。

キャッシュキーの作り方、Django Admin内部の権限判定、SMTP接続再利用など、アプリケーション内部の問題はWAFだけでは修正できません。


FAQ

Django 5.2.15は今すぐ停止すべきですか

直ちにシステムを停止する必要があるとは限りません。

ただし、Django 5.2.16へのパッチ更新を速やかに計画してください。

Redis共有キャッシュ、cache_page()、GDALRaster、独自のドメイン検証を利用している場合は、優先度を上げます。

Django 5.2.16へ更新すると大きな互換性問題が起きますか

5.2.15から5.2.16は同じ5.2系列のパッチ更新です。

通常は機能更新より影響が小さい更新です。

ただし、セキュリティ上必要な挙動変更が含まれる可能性があるため、テスト環境で確認してから本番反映してください。

Django 6.0へ上げる必要がありますか

今回の脆弱性対応だけが目的であれば、Django 5.2.16へ更新する方法があります。

Django 5.2は2028年4月まで延長サポートされるLTSです。

Redisを使っているだけで情報漏えいしますか

Redisを使っているだけでは成立しません。

共有キャッシュへ、Cookie、Authorization、セッションなどによって内容が変わるレスポンスを保存する構成が関係します。

SQLインジェクションはユーザー入力をORMへ渡していなければ関係ありませんか

今回の複数のSQLインジェクションは、細工した辞書、列エイリアス、FilteredRelationorder_by()、PostGISのバンド番号などが主な成立条件です。

フィールド名やORM構造が固定されており、ユーザー入力が値としてのみ渡される設計では、影響は限定されます。

Djangoを更新すればNginxの制限は不要ですか

不要にはなりません。

Django公式も、大容量アップロード対策をWebサーバー側へ設定することを前提としています。


まとめ

Django 5.2.15以前には、複数のセキュリティ問題とデータ整合性に関わる不具合があります。

特に重要なのは次の問題です。

  • 動的な辞書展開によるSQLインジェクション

  • ASGIリクエストによるメモリ・CPU枯渇

  • Redis共有キャッシュからの情報露出

  • セッション固定

  • Django Adminの権限検証不備

  • STARTTLS失敗後の平文メール送信

  • PostgreSQLのbulk_create()によるデータ切り詰め

  • ファイル上書き時に古い内容が残るデータ破損

推奨対応は次のとおりです。

1. Django 5.2.16以上へ更新
2. ORMへの動的辞書展開を確認
3. Redisキャッシュの分離を確認
4. Nginxで本文・ヘッダー上限を設定
5. Django Adminの権限を再テスト
6. メール、アップロード、WebSocketを動作確認
7. 自動的な依存関係監視を導入

Django 5.2はLTSですが、安全に利用するには最新パッチを継続して適用する必要があります。

「Django 5.2を使っている」だけではなく、正確なパッチバージョンと最終確認日を管理することが重要です。


参考情報

  • Django 5.2.1から5.2.16までの公式リリースノート

  • Django 5.2.16セキュリティリリース

  • Django 5.2.15セキュリティリリース

  • Django 5.2.14セキュリティリリース

  • Django 5.2.13セキュリティリリース

  • Django 5.2.12セキュリティリリース

  • Django 5.2.11セキュリティリリース

  • Django 5.2のサポート期間



出典・最終確認(2026年7月31日)

Django security releases issued: 6.0.7 and 5.2.16

Django公式が2026年7月7日に公開したセキュリティリリースに基づきます。5.2系は5.2.16以降へ更新し、利用中の依存関係と回帰テストも確認してください。

読んだ内容を10問練習と実技で確認

記事で理解した用語を、StudyQuestの演習とクラウド実技ラボで定着させます。

10問練習 実技ラボ

コメント(0件)

まだコメントはありません。最初のコメントを投稿してください!

コメントを投稿