この記事は既に古くなっています。
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によって内容が変わるレスポンスが共有キャッシュへ保存される可能性がありました。
問題となる条件は次のとおりです。
リクエストに言語設定やテーマ設定など、無関係なCookieが付いている
レスポンスがセッションCookieなどを新しく設定する
レスポンスがRedisなどの共有キャッシュへ保存される
別の利用者へキャッシュ済みレスポンスが返される
たとえるなら、本来は個人ごとに渡す封筒を、共有の書類棚へ置いてしまう状態です。
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-7666 | STARTTLS失敗後の平文メール送信 | EMAIL_USE_TLS=True、TLS失敗、接続再利用 |
| CVE-2026-8404 | Cache-Controlの大文字小文字処理不備 | 手動でPrivateなどを設定 |
| CVE-2026-35193 | Vary: Authorization不足 | Authorization付きレスポンスをキャッシュ |
| CVE-2026-48587 | Vary値の空白処理不備 | 空白付きの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-5766 | ASGIファイルアップロード上限の回避 | Low |
| CVE-2026-35192 | 公開キャッシュページによるセッション固定 | Low |
| CVE-2026-6907 | Vary: *レスポンスの誤キャッシュ | 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-3902 | ASGIでのアンダースコア/ハイフンを利用したヘッダー偽装 | Low |
| CVE-2026-4277 | GenericInlineModelAdminの追加権限検証不備 | Low |
| CVE-2026-4292 | ModelAdmin.list_editableから新規インスタンス作成 | Low |
| CVE-2026-33033 | base64ファイルアップロードによるDoS | Moderate |
| CVE-2026-33034 | ASGIリクエスト本文のメモリ上限回避 | 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-25673 | Windows上のURLFieldによるDoS | Moderate |
| 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-13473 | mod_wsgi認証の応答時間差によるユーザー列挙 | Low |
| CVE-2025-14550 | ASGIの重複ヘッダー処理によるDoS | Moderate |
| CVE-2026-1207 | PostGISラスタールックアップのSQLインジェクション | High |
| CVE-2026-1285 | TruncatorのHTML処理によるDoS | Moderate |
| CVE-2026-1287 | 制御文字を含む列エイリアスからのSQLインジェクション | High |
| CVE-2026-1312 | order_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-13372 | PostgreSQL上のFilteredRelation列エイリアスによるSQLインジェクション | High |
| CVE-2025-64460 | XMLデシリアライザーの二次時間処理によるDoS | Moderate |
XMLデシリアライザーの問題は、多数の不正なネスト要素を含むXMLを読み込ませることで成立します。
XML形式のfixtureや外部XMLインポート機能を、信頼できない利用者へ公開している場合に確認が必要です。
Django 5.2.7までに存在した脆弱性
Django 5.2.8では、次の2件が修正されました。
| CVE | 内容 | 深刻度 |
|---|---|---|
| CVE-2025-64458 | Windows上のリダイレクト処理によるDoS | Moderate |
| 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-59681 | MySQL・MariaDBの列エイリアスによるSQLインジェクション | High |
| CVE-2025-59682 | archive.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.4 | Acceptヘッダーの優先順位を誤る |
| 5.2.4 | JSONのnullをSQLのNULLとして扱う |
| 5.2.3 | bulk_update()がSQL NULLをJSON nullへ変換 |
| 5.2.2 | OuterRefを使った集計処理がクラッシュ |
| 5.2.2 | Django AdminのEnter送信をボタンが妨害 |
| 5.2.1 | file_move_safe()で古いファイル内容が末尾に残る |
| 5.2.1 | nullable外部キーの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+Uvicorn | ASGI DoS、ヘッダー偽装 | 高 |
| Django Channels/Daphne | ASGI DoS、ヘッダー偽装 | 高 |
| 動的なORMフィルター | 複数のSQLインジェクション | 高 |
| PostgreSQL | FilteredRelation、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機能
キャッシュ分離テスト
次の手順で、利用者間の情報混在がないことを確認します。
ユーザーAでログインする
テーマCookieや言語Cookieを設定する
キャッシュ対象ページへアクセスする
ユーザーBまたは未ログインブラウザで同じページへアクセスする
ユーザーAの名前、Cookie、個人情報が表示されないことを確認する
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インジェクションは、細工した辞書、列エイリアス、FilteredRelation、order_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以降へ更新し、利用中の依存関係と回帰テストも確認してください。
コメント(0件)
まだコメントはありません。最初のコメントを投稿してください!