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

初回確認:2026年8月5日
対象環境:Django 5.2.16 LTS
修正版:Django 5.2.17 LTS
2026年8月4日、Django Software Foundationは、4件のセキュリティ問題を修正したDjango 5.2.17とDjango 6.0.8を公開しました。
Django 5.2.16には、GeoDjangoを経由したサーバー側ファイル書込み・SSRF、メモリ消費型DoS、GeometryCollectionによるプロセスクラッシュ、Django Adminの格納型XSSが存在します。
Django公式は、Django 5.2.16の利用者に対してDjango 5.2.17への更新を推奨しています。Django 5.2.17では、Highが1件、Moderateが2件、Lowが1件修正されています。
なお、GBHackersの記事では「RCE、SSRF、DoS、XSSを実行できる」と報じられています。脆弱性の内容はDjango公式情報とおおむね一致していますが、RCEやSSRFはすべてのDjangoサイトで無条件に成立するものではありません。GeoDjango、GDAL、空間フィールド、管理画面の権限など、複数の成立条件があります。
この記事の要点
Django 5.2.16は4件のセキュリティ問題の影響を受けるためDjango 5.2.17へ更新する必要がある。
CVE-2026-15307はGeoDjangoの空間検索を通じてサーバー側ファイル書込みやSSRFを引き起こす可能性がある。
CVE-2026-15307のファイル書込みは環境と書込み先の条件がそろった場合にRCEへ発展する可能性がある。
CVE-2026-15337は長大な言語コードを大量に処理させることでDjangoワーカーのメモリを消費させる。
CVE-2026-15830は深く入れ子になったGeometryCollectionによってGEOSをクラッシュさせる可能性がある。
CVE-2026-15920は不正なURLField値をDjango Adminでクリックした管理者に格納型XSSを発生させる可能性がある。
GeoDjangoを利用していない環境でもCVE-2026-15337とCVE-2026-15920の確認は必要である。
Cloudflare WAFやIPSは脆弱性の悪用を軽減できるがDjango 5.2.17への更新の代わりにはならない。
Django 5.2 LTSは長期サポート版だが古いパッチバージョンが自動的に安全になるわけではない。
結論:Django 5.2.16から5.2.17へ更新する
現在Django 5.2.16 LTSを利用している場合は、Django 5.2.17 LTSへ更新してください。
Django 5.2.17は、2026年8月4日に公開された同じ5.2系列のセキュリティパッチです。Django公式は、同一系列の最新パッチへ更新する質問に対する答えは常に「Yes」であると説明しています。
Django 5.2 LTSの延長サポートは2028年4月まで続きますが、サポートされるのはDjango 5.2系列の最新パッチです。古いDjango 5.2.16を使い続けることが保証されているわけではありません。
今回の対応優先度は次のとおりです。
| 優先度 | 対応 |
|---|---|
| 最優先 | Django 5.2.16から5.2.17へ更新する |
| 高 | GeoDjango、PostGIS、GDALの使用状況を確認する |
| 高 | Django Adminに登録した空間フィールドの権限を確認する |
| 高 | 外部入力を空間検索へ直接渡していないか確認する |
| 中 | set_language()の公開状況を確認する |
| 中 | URLFieldへ検証を通さず値を保存していないか確認する |
| 中 | Djangoコンテナの外向き通信とファイル書込み権限を制限する |
| 継続 | WAF、IPS、EDRで悪用の兆候を監視する |
関連記事
この記事は、次の記事の続報です。
関連記事:Django 5.2.15以前の脆弱性を解説|SQLインジェクション・キャッシュ漏えい・ASGI DoSの対策
関連記事では、2026年7月27日時点の修正版としてDjango 5.2.16を案内しています。しかし、2026年8月4日にDjango 5.2.17が公開されたため、現在の最低更新先はDjango 5.2.17へ変更されています。
Django 5.2.16までに修正されたSQLインジェクション、共有キャッシュ、ASGI、メール、管理画面などの問題は関連記事を参照してください。今回の記事では、Django 5.2.16に残っていた4件へ焦点を当てます。
この記事で分かること
この記事では、次の内容が分かります。
Django 5.2.16で新たに修正対象となった4件の脆弱性
RCEやSSRFが成立する具体的な条件
GeoDjangoを使っていない環境への影響
現在のDjango環境を確認する方法
Docker Compose環境でDjango 5.2.17へ更新する方法
更新後に確認すべき管理画面、GIS、認証、WebSocketの動作
Cloudflare WAF、IPS、EDRで補助できる範囲
同じ問題を見落とさないための再発防止策
対象読者・前提環境
この記事は、次の読者を対象としています。
Django 5.2を本番環境で運用しているエンジニア
Django Adminを業務管理画面として利用している担当者
GeoDjango、PostGIS、GDALを利用している担当者
Docker ComposeでDjangoを運用している担当者
Cloudflare、Nginx、Gunicorn、Uvicornを利用している担当者
Webアプリケーションの脆弱性対応を担当する人
想定する構成は次のとおりです。
Internet
│
▼
Cloudflare
│
▼
Nginx
│
▼
Gunicorn + Uvicorn
│
▼
Django 5.2.16
├─ PostgreSQL
├─ Redis
├─ Django Admin
├─ ファイルストレージ
└─ GeoDjango/GDAL(使用時)
Djangoサービス名、PostgreSQLサービス名、ディレクトリ名は環境によって異なります。以降の例ではDjangoサービスをdjango、PostgreSQLサービスをpostgresとしています。
Django 5.2.16で何が起きたのか
Django 5.2.17では、Django 5.2.16に存在した次の4件が修正されました。
| CVE | 内容 | Django評価 | 主な影響 |
|---|---|---|---|
| CVE-2026-15307 | 空間検索によるファイル書込みとリクエスト送信 | High | ファイル書込み、SSRF、条件付きRCE |
| CVE-2026-15337 | 長大な言語コードによるキャッシュ消費 | Low | メモリ消費、DoS |
| CVE-2026-15830 | 入れ子のGeometryCollection | Moderate | GEOSのクラッシュ、DoS |
| CVE-2026-15920 | AdminのURLField表示処理 | Moderate | 格納型XSS |
全体像は次のとおりです。
Django 5.2.16
│
├─ GeoDjangoの空間検索
│ ├─ ファイルへ書込み
│ └─ 外部・内部URLへ接続
│
├─ 言語コードの確認
│ └─ 長大な値をキャッシュしてメモリ消費
│
├─ GEOSGeometry
│ └─ 深い入れ子でプロセスをクラッシュ
│
└─ Django Admin
└─ 不正なURLFieldをクリック可能なリンクとして表示
CVE-2026-15307:GeoDjangoのファイル書込み・SSRF・条件付きRCE
何が問題なのか
CVE-2026-15307は、今回修正された4件の中で最も深刻度が高い問題です。
GeoDjangoの空間検索では、ラスターを表す文字列や辞書がGDALRasterへ渡される場合がありました。
GDALは、地理情報や画像データをさまざまな形式で読み書きするためのライブラリです。たとえるなら、さまざまな地図や画像形式を開ける多機能な変換ソフトです。
正式には、GDALは地理空間データを読み書きするためのライブラリであり、ローカルファイルだけでなく、対応するドライバーや仮想ファイルシステムを通じてネットワーク上のデータを扱う機能も持ちます。GeoDjangoはGDALの一部機能をPythonから扱えるようにしています。
問題があるDjango 5.2.16では、細工した値が空間検索へ渡された場合、GDALの処理によって次の動作が発生する可能性がありました。
攻撃者が細工した検索値を送信
│
▼
GeoDjangoの空間検索
│
▼
GDALRasterとして解釈
│
├─ ファイル系の処理
│ └─ Django実行ユーザーの権限でファイル作成
│
└─ ネットワーク系の処理
└─ Django実行ユーザーの権限でURLへ接続
Django公式は、利用するラスタードライバーによっては、サーバー上へのファイル書込みや、Djangoプロセスからのネットワークリクエストが発生すると説明しています。
ファイル書込み先や、その後のアプリケーション動作によっては、リモートコード実行へ発展する可能性があります。
RCEは無条件に成立するのか
無条件には成立しません。
今回の問題は、ファイルを書き込んだ時点で必ずコードが実行される脆弱性ではありません。
サーバー側ファイル書込み
│
▼
Pythonや別プロセスが読み込む場所へ書き込める
│
▼
書き込んだファイルが設定・コードとして読み込まれる
│
▼
条件がそろった場合にコード実行
代表的な成立条件は次のとおりです。
GeoDjangoを使用している
空間フィールドを持つモデルがある
GDALまたはラスタードライバーを使用している
攻撃者の入力が空間検索へ到達する
Djangoプロセスに対象パスへの書込み権限がある
書き込まれたファイルが後から実行または読み込まれる
Django Admin経由の代表的な攻撃経路では、次の権限も必要です。
Django Adminへログインできるstaffユーザー
空間フィールドを持つ登録済みモデルの閲覧権限
Django公式は、Adminの変更一覧にある検索条件がModelAdmin.lookup_allowed()を通じて利用できるため、空間フィールドを含むモデルの閲覧権限を持つstaffユーザーから到達可能だったと説明しています。
SSRFとは
SSRFは、攻撃者がWebサーバーを代理として別のURLへ接続させる攻撃です。
たとえるなら、外部の人が社内の受付担当者へ「この社内資料を取ってきてください」と依頼し、外部から直接入れない場所へ受付担当者を行かせる状態です。
正式にはServer-Side Request Forgeryと呼ばれ、サーバーから内部ネットワーク、管理API、クラウドメタデータ、外部サービスなどへ意図しないリクエストを送信させます。
今回の脆弱性では、通信元はDjangoプロセスです。そのため、外部から直接接続できないURLでも、Djangoコンテナから接続可能であれば影響を受ける可能性があります。
Django 5.2.17での修正
Django 5.2.17では、空間検索で次の値が拒否されます。
dict有効な
GEOSGeometryではない文字列シリアライズされた辞書など、ジオメトリではない文字列
この変更はセキュリティ上必要な後方互換性のない変更です。
従来、辞書や文字列を空間検索値として渡していたアプリケーションでは、更新後にエラーが発生する可能性があります。信頼できるラスターを使用する場合は、入力を検証したうえで、アプリケーション側が明示的に適切なオブジェクトへ変換する必要があります。
CVE-2026-15337:長大な言語コードによるメモリDoS
何が問題なのか
Djangoには、指定された言語コードが有効かどうかを確認するcheck_for_language()があります。
問題があるDjango 5.2.16では、非常に長い言語コードを多数送信すると、それぞれの値がインメモリキャッシュのキーとして保存されました。
長大で異なる言語コードを繰り返し送信
│
▼
check_for_language()
│
▼
各文字列がキャッシュキーとして保存
│
▼
Djangoワーカーのメモリ使用量が増加
言語コードは、django.views.i18n.set_language()へ送信されたPOSTデータから到達します。
ただし、set_language()はデフォルトで公開されていません。また、リクエストサイズはDATA_UPLOAD_MAX_MEMORY_SIZEで制限され、キャッシュの登録数にも上限があります。
このため、Djangoの評価はLowです。
Django 5.2.17での修正
Django 5.2.17では、500文字を超える言語コードをキャッシュへ渡す前に拒否します。
影響を受けやすい環境
次の構成では確認が必要です。
django.conf.urls.i18nをURL設定へ追加しているset_language()を独自URLへ登録している誰でも言語変更リクエストを送信できる
NginxやCloudflareでリクエスト頻度を制限していない
メモリ容量が小さいVPSで複数のDjangoワーカーを動かしている
GeoDjangoを利用していない環境でも、この脆弱性は関係します。
CVE-2026-15830:GeometryCollectionによるプロセスクラッシュ
何が問題なのか
GeoDjangoのGEOSGeometryは、WKTやWKBなどの形式で記述された図形を解析します。
GeometryCollectionは、複数の図形をまとめる入れ物です。
たとえるなら、箱の中へ別の箱を入れ、その箱の中へさらに箱を入れ続けられる構造です。
GEOMETRYCOLLECTION(
GEOMETRYCOLLECTION(
GEOMETRYCOLLECTION(
...
)
)
)
問題があるDjango 5.2.16では、非常に深く入れ子になったGEOMETRYCOLLECTIONを解析すると、背後のGEOSライブラリで再帰処理が続き、セグメンテーションフォルトが発生する可能性がありました。
セグメンテーションフォルトが発生すると、処理中のDjangoワーカープロセスが異常終了する可能性があります。リクエストを繰り返されると、サービス拒否につながります。
影響する入力
Django公式は、次の経路が影響を受けると説明しています。
WKT形式
WKB形式
空間フィールドに対する検索
GeometryFieldフォームフィールド
GeoJSONはGDALで解析されるため、この問題の対象外です。
Django 5.2.17での修正
Django 5.2.17では、次の上限が追加されました。
| 入力形式 | 上限 |
|---|---|
| WKT | GeometryCollectionの深さ198 |
| WKB | GeometryCollectionの総数198 |
必要な場合は、新しく追加されたmax_geom_collections引数で上限を調整できます。
上限を大きくすると再びリソース消費が増える可能性があります。実際に198を超える正当なデータが必要か確認してから変更してください。
CVE-2026-15920:Django AdminのURLFieldによる格納型XSS
何が問題なのか
Django Adminは、モデルのURLFieldを変更一覧や読み取り専用フィールドへ表示するとき、クリック可能なリンクへ変換します。
問題があるDjango 5.2.16では、保存されているURLのスキームが安全かどうかを表示時に再検証していませんでした。
不正なURLがデータベースへ保存されると、Django Admin上でもリンクとして表示される可能性がありました。
外部データや独自APIから不正URLを保存
│
▼
Django AdminがURLFieldをリンクとして表示
│
▼
管理者がリンクをクリック
│
▼
管理者のブラウザー上でスクリプトが実行される可能性
これは格納型XSSです。
たとえるなら、危険な命令を書いた紙を共有棚へ保存し、後から管理者がその紙を開いたときに命令が実行される状態です。
正式にはStored Cross-Site Scriptingと呼ばれ、不正な入力がデータベースなどへ保存され、別の利用者が表示または操作したときにスクリプトが実行される問題です。
Django公式は、URLFieldの値が安全なURLとして検証されないままリンクへ変換されていたと説明しています。
通常のフォームを使っていれば安全なのか
通常のModelFormやDjango Adminの編集フォームでは、URLFieldのバリデーションが実行されます。
しかし、次の処理ではフォーム検証を通らない場合があります。
QuerySet.update()bulk_create()CSVからの一括取込み
外部APIからの自動同期
スクレイピング結果の直接保存
独自のデシリアライズ処理
SQLを使った直接更新
バリデーションを省略した管理コマンド
したがって、フォームがあることだけを理由に、データベース内のすべてのURLが安全であるとは判断できません。
攻撃成立条件
代表的な成立条件は次のとおりです。
危険なURLField値をデータベースへ保存できる
対象のURLFieldがDjango Adminに表示される
管理者が表示されたリンクをクリックする
保存されただけで即座にコードが実行されるとは限りません。代表的な攻撃では、管理者のクリックが必要です。
Django 5.2.17での修正
Django 5.2.17では、URLFieldをリンクへ変換する前にURLValidatorで検証します。
検証に失敗したURLは、クリック可能なリンクではなく通常のテキストとして表示されます。
Django 5.2.16環境への影響を判断する
現在の環境がDjango 5.2.16であるため、バージョン上は今回の4件の修正対象です。
ただし、実際に攻撃経路へ到達できるかどうかは機能ごとに異なります。
| 環境・機能 | 関係する脆弱性 | 判断 |
|---|---|---|
| Django 5.2.16 | 全4件 | 更新が必要 |
| GeoDjangoを未使用 | CVE-2026-15307、CVE-2026-15830 | 通常は直接到達しない |
| PostGISを使用 | GIS関連2件 | モデルと検索処理を確認 |
| GDALRasterを使用 | CVE-2026-15307 | 優先確認 |
| Django Adminを使用 | CVE-2026-15920 | URLFieldを確認 |
| 空間モデルをAdminへ登録 | CVE-2026-15307 | staff権限を確認 |
set_language()を未登録 | CVE-2026-15337 | 代表的経路は到達しない |
| 外部データをURLFieldへ保存 | CVE-2026-15920 | 検証処理を確認 |
| AdminをVPN内へ制限 | GIS・XSS | リスクは下がるが更新は必要 |
| コンテナがrootで動作 | CVE-2026-15307 | ファイル書込み時の影響が拡大 |
| 外向き通信を無制限に許可 | CVE-2026-15307 | SSRFの到達範囲が広がる |
確認方法
1. Djangoのバージョンを確認する
目的
稼働中のDjangoが5.2.16か、修正版の5.2.17かを確認します。
実行場所
Djangoコンテナを起動しているDockerホストで実行します。
コマンド
docker compose exec django python -m django --version
インストール元も確認する場合は次を実行します。
docker compose exec django python -m pip show Django
正常例
5.2.17
対応が必要な例
5.2.16
判断方法
5.2.17:今回の4件は修正済み5.2.16以下:更新が必要6.0.7以下:6.0.8以上への更新が必要開発版やRC版:本番利用方針を再確認する
2. GeoDjangoを利用しているか確認する
目的
CVE-2026-15307とCVE-2026-15830の攻撃経路が存在するか確認します。
実行場所
Dockerホストで実行します。
コマンド
docker compose exec django python manage.py shell -c \
'from django.conf import settings; print("django.contrib.gis" in settings.INSTALLED_APPS)'
正常例
GeoDjangoを使用していない場合です。
False
要確認例
True
判断方法
Trueの場合は、GeoDjango関連のモデル、フォーム、API、管理画面を詳しく確認します。
ただし、Falseでもアプリケーションコードから一部のGISクラスを直接インポートしている可能性があります。続けてコード検索を行います。
grep -RInE \
'django\.contrib\.gis|GeometryField|RasterField|GEOSGeometry|GDALRaster' \
--include='*.py' \
--exclude-dir=.git \
--exclude-dir=.venv \
--exclude-dir=venv \
.
正常例
何も表示されない場合は、アプリケーションコードでGIS機能を利用していない可能性が高いと判断できます。
要確認例
./maps/models.py:18: location = models.GeometryField()
./maps/views.py:42: GEOSGeometry(request.data["geometry"])
表示された場合は、外部入力が検証されず空間検索やGEOSGeometryへ渡されていないか確認します。
3. 空間フィールドを持つモデルを確認する
目的
実際に登録されているGISフィールドを一覧化します。
実行場所
Djangoコンテナ内で実行します。
コマンド
docker compose exec django python manage.py shell <<'PY'
from django.apps import apps
for model in apps.get_models():
for field in model._meta.get_fields():
module = field.__class__.__module__
if module.startswith("django.contrib.gis"):
print(
f"{model._meta.label}.{field.name}: "
f"{field.__class__.__name__}"
)
PY
正常例
GeoDjangoを使っていない場合は何も表示されません。
要確認例
maps.MapArea.geometry: PolygonField
maps.RasterLayer.image: RasterField
判断方法
表示されたモデルについて、次を確認します。
Django Adminへ登録されているか
staffユーザーに閲覧権限が付与されているか
URLクエリから動的な検索条件を受け取っているか
APIの値をそのまま
filter()へ渡していないかWKTやWKBの入力上限を設けているか
4. 言語切替ビューを確認する
目的
CVE-2026-15337の代表的な入力経路であるset_language()が公開されているか確認します。
実行場所
Djangoプロジェクトのソースコードがあるディレクトリで実行します。
コマンド
grep -RInE \
'set_language|django\.views\.i18n|django\.conf\.urls\.i18n' \
--include='*.py' \
--exclude-dir=.git \
.
正常例
多言語切替を使用していない環境では、結果が表示されません。
要確認例
config/urls.py:24:path("i18n/", include("django.conf.urls.i18n"))
判断方法
URL設定が見つかった場合は、次を確認します。
外部からPOSTできるか
CloudflareやNginxでレート制限しているか
リクエストボディ上限が設定されているか
本当に言語切替機能が必要か
Django 5.2.17へ更新すれば500文字を超える言語コードは早期に拒否されますが、不要なエンドポイントを公開しない設計も重要です。
5. URLFieldを持つモデルを確認する
目的
CVE-2026-15920の影響を受ける可能性があるモデルを一覧化します。
実行場所
Djangoコンテナ内で実行します。
コマンド
docker compose exec django python manage.py shell <<'PY'
from django.apps import apps
from django.db.models import URLField
for model in apps.get_models():
for field in model._meta.get_fields():
if isinstance(field, URLField):
print(f"{model._meta.label}.{field.name}")
PY
正常例
URLFieldが存在しない場合は何も表示されません。
要確認例
diary.Reference.url
accounts.Profile.website
security.ThreatSource.source_url
判断方法
表示されたモデルについて、次を確認します。
Django Adminへ登録されているか
外部APIやCSVから値を取り込んでいるか
フォームやシリアライザーの検証を通しているか
update()やbulk_create()で直接保存していないか管理者がリンクをクリックする運用になっているか
6. バリデーションを迂回しやすい保存処理を検索する
目的
URLFieldや空間入力が検証を通らず保存される経路を確認します。
実行場所
プロジェクトのソースコードがあるディレクトリで実行します。
コマンド
grep -RInE \
'bulk_create|bulk_update|\.update\(|raw\(|cursor\.execute|deserialize' \
--include='*.py' \
--exclude-dir=.git \
--exclude-dir=.venv \
.
正常例
検索結果があっても、固定値だけを扱っている場合や、事前検証を実施している場合は問題ありません。
要確認例
Reference.objects.filter(pk=reference_id).update(
url=request.data["url"]
)
判断方法
利用者や外部サービスから受け取った値を直接保存している場合は、明示的な検証を追加します。
URLの場合は、例えばURLValidatorを保存前に実行します。
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
validate_url = URLValidator(
schemes=["https"],
)
def validate_external_url(value: str) -> str:
try:
validate_url(value)
except ValidationError as exc:
raise ValueError("許可されていないURLです。") from exc
return value
https以外が必要な場合は、必要性を確認して許可するスキームを限定してください。
Django 5.2.17への更新方法
更新前の注意事項
Django 5.2.16から5.2.17は同じ5.2系列のパッチ更新です。
ただし、CVE-2026-15307の修正では、空間検索へ辞書や不正な文字列を渡す処理が拒否されます。この動作に依存したコードがある場合は、更新後にエラーになる可能性があります。
本番更新前に、次を準備してください。
PostgreSQLのバックアップ
ユーザーアップロードファイルのバックアップ
現在稼働中のDockerイメージタグ
現在の
requirements.txtまたはロックファイルロールバック手順
ステージング環境でのテスト結果
1. 現在の依存関係を保存する
目的
更新前の状態を記録し、問題発生時に差分を確認できるようにします。
実行場所
Dockerホストで実行します。
コマンド
docker compose exec django python -m pip freeze \
> requirements-before-django-5.2.17.txt
正常例
test -s requirements-before-django-5.2.17.txt \
&& echo "依存関係を保存しました"
依存関係を保存しました
異常例
ファイルが空の場合、対象コンテナ名やPython環境が正しいか確認します。
2. PostgreSQLをバックアップする
目的
更新中に予期しない問題が起きた場合にデータを復元できるようにします。
実行場所
Dockerホストで実行します。
コマンド例
環境に合わせてデータベース名とユーザー名を変更してください。
mkdir -p backups
docker compose exec -T postgres \
pg_dump \
-U app_user \
-d app_database \
-Fc \
> "backups/django-update-$(date +%Y%m%d-%H%M%S).dump"
正常確認
ls -lh backups/
バックアップファイルのサイズが0バイトでないことを確認します。
注意
バックアップを作成しただけでは復元可能とは断定できません。
可能であれば、検証用PostgreSQLへリストアして、次のコマンドが成功することを確認してください。
pg_restore --list backups/対象ファイル.dump | head
3. Djangoのバージョン指定を変更する
requirements.txtを使用している場合は、次のように変更します。
Django==5.2.17
範囲指定を使用する場合は、意図しないDjango 6系列への更新を防ぎます。
Django>=5.2.17,<5.3
本番環境では、再現性を高めるため、ロックファイルまたは完全なバージョン固定を推奨します。
pip install -U Djangoだけを実行すると、設定によっては別のリリース系列へ更新される可能性があります。LTS系列を維持する場合は更新先を明示してください。
4. Dockerイメージを再ビルドする
目的
実行中コンテナへ直接インストールするのではなく、修正版を含む再現可能なイメージを作成します。
実行場所
Dockerホストで実行します。
コマンド
docker compose build django
キャッシュの影響を除外して完全に再構築する場合は次を実行します。
docker compose build --no-cache django
正常例
ビルドの最後でエラーが発生せず、イメージが作成されます。
異常例
Could not find a version that satisfies the requirement
この場合は、Pythonバージョン、パッケージインデックス、プロキシ設定、依存関係の競合を確認します。
5. 新しいイメージのDjangoバージョンを確認する
目的
本番へ反映する前に、新しいイメージへDjango 5.2.17が入っていることを確認します。
コマンド
docker compose run --rm django python -m django --version
正常例
5.2.17
異常例
5.2.16
5.2.16のままの場合は、次を確認します。
Dockerfileが正しい
requirements.txtをコピーしているか古いロックファイルが優先されていないか
マルチステージビルドで古い仮想環境をコピーしていないか
Docker BuildKitのキャッシュが残っていないか
6. Djangoのシステムチェックを実行する
目的
設定やアプリ登録に明らかな問題がないか確認します。
コマンド
docker compose run --rm django python manage.py check
本番向け設定も確認します。
docker compose run --rm django \
python manage.py check --deploy
正常例
System check identified no issues (0 silenced).
注意
check --deployは、HTTPSやCookie設定などについて警告を出す場合があります。
警告を無視するのではなく、現在のCloudflare、Nginx、TLS終端構成を踏まえて、一つずつ妥当性を確認してください。Django公式も、本番環境ではDEBUG=False、適切なALLOWED_HOSTS、データベースとキャッシュへの接続制限、バックアップなどを求めています。
7. マイグレーション差分を確認する
目的
意図しないモデル変更が混入していないことを確認します。
コマンド
docker compose run --rm django \
python manage.py makemigrations --check --dry-run
適用予定のマイグレーションも確認します。
docker compose run --rm django \
python manage.py migrate --plan
正常例
No changes detected
または、事前に把握しているマイグレーションだけが表示されます。
異常例
今回のDjango更新と無関係な多数のモデル差分が表示された場合は、そのまま本番へ反映しないでください。
8. テストを警告付きで実行する
Django公式は、更新時に非推奨警告を表示してテストする方法として-Waを案内しています。
コマンド
docker compose run --rm django \
python -Wa manage.py test
pytestを使用している場合は次のように実行します。
docker compose run --rm django \
env PYTHONWARNINGS=always \
pytest --capture=no
正常例
テストがすべて成功する
新しい例外が発生しない
空間検索の既存機能が動作する
Adminの一覧画面が表示できる
異常例
空間検索で次のような処理に依存していた場合、Django 5.2.17でエラーになる可能性があります。
Model.objects.filter(
raster_field__intersects={
"driver": "GTiff",
"source": "...",
}
)
辞書や文字列を利用する必要がある場合は、信頼できる入力かを検証し、Django 5.2.17の公式ドキュメントに従って明示的に適切なGISオブジェクトへ変換します。
9. 本番へ反映する
事前テストに成功した後で、新しいコンテナを起動します。
docker compose up -d --no-deps django
Nginxなどもイメージや設定が変更されている場合は、対象サービスを含めて起動します。
docker compose up -d
起動状態の確認
docker compose ps
ログ確認
docker compose logs --tail=200 django
エラーを追跡する場合は次を実行します。
docker compose logs -f django
更新後の動作確認
基本的な確認項目
| 確認対象 | 正常条件 |
|---|---|
| トップページ | HTTP 200で表示される |
| ログイン | 正常に認証できる |
| ログアウト | セッションが終了する |
| Django Admin | 一覧・詳細・編集画面が表示される |
| URLField | 正常なHTTPSリンクだけがリンク表示される |
| API | 主要エンドポイントが期待したJSONを返す |
| Redis | キャッシュとセッションが正常に動作する |
| WebSocket | 接続、再接続、メッセージ送信が成功する |
| ファイルアップロード | サイズ上限内のファイルを保存できる |
| メール | パスワードリセットや通知が届く |
| GIS | 地図検索、空間検索、保存、表示が成功する |
HTTPヘルスチェック
目的
更新後に外部からWebサイトへ接続できるか確認します。
コマンド
curl -fsS -o /dev/null \
-w 'HTTP=%{http_code} TIME=%{time_total}\n' \
https://kurutann.com/
正常例
HTTP=200 TIME=0.245
異常例
HTTP=502
502の場合は、NginxからDjangoコンテナへの接続、Gunicornの起動状態、ソケットまたはポート設定を確認します。
Djangoバージョンの最終確認
docker compose exec django python -m django --version
5.2.17
本番コンテナ内で5.2.17が確認できるまで、更新完了とは判断しないでください。
管理画面の確認
ステージング環境で、次を確認します。
URLFieldを持つモデルの変更一覧を開く
正常なHTTPS URLがリンクとして表示されることを確認する
検証に失敗する値がリンクにならないことを確認する
空間フィールドを持つモデルの絞り込みを確認する
制限付きstaffユーザーの権限を確認する
本番データへ危険なURLを登録して試験しないでください。
専用のテストデータとステージング環境を使用してください。
GIS機能の確認
GeoDjangoを使用している場合は、次を確認します。
WKTの登録
WKBの登録
GeoJSONの登録
空間検索
距離検索
範囲検索
Django Adminのフィルター
GISフォームの入力
ラスターデータの読込み
外部ストレージからの読込み
Django 5.2.17では、空間検索へ渡せる入力型が厳しくなっています。
更新後にGIS機能だけ失敗する場合は、セキュリティ修正によって不正または曖昧な入力が拒否されている可能性があります。検証を無効化するのではなく、入力形式を明示的に変換してください。
すぐに更新できない場合の暫定対策
Django 5.2.17への更新が第一選択です。
暫定対策だけで安全になったとは判断しないでください。
GeoDjango関連
空間フィールドを持つモデルをDjango Adminから一時的に外す
対象モデルのview権限を必要最小限へ変更する
管理画面をWireGuardや社内VPNからのみ許可する
未信頼入力を空間検索へ渡さない
WKT、WKB、リクエストボディのサイズを制限する
Djangoコンテナを非rootで実行する
ルートファイルシステムを可能な範囲でread-onlyにする
Djangoコンテナの外向き通信を必要な宛先だけに制限する
言語切替関連
使用していない
set_language()をURL設定から外す言語切替URLへレート制限を設定する
Nginxのリクエストボディ上限を設定する
Cloudflareで異常なPOST頻度を制限する
URLField関連
外部データ保存時に
URLValidatorを実行するURLスキームを
httpsへ限定する管理画面で不明なリンクをクリックしない
バリデーションを通さない一括登録処理を停止する
URLFieldを読み取り専用テキストとして独自表示する
WAF・IPS・EDRによる補助対策
補助できる範囲
| 脆弱性 | WAF・IPSで可能な補助 | 限界 |
|---|---|---|
| CVE-2026-15307 | 異常な空間検索値、管理画面への不審なクエリを検知 | 正当な形式との区別が難しく、符号化された入力を見逃す可能性がある |
| CVE-2026-15337 | 長大なPOST、同一URLへの高頻度アクセスを制限 | 低頻度で分散されたリクエストには弱い |
| CVE-2026-15830 | 大量のGEOMETRYCOLLECTIONを含むWKTを検知 | WKBなどのバイナリ形式は単純な文字列検査が難しい |
| CVE-2026-15920 | 不審なURLスキームを入力時に遮断 | データベースへ既に保存された値や管理者の操作までは完全に防げない |
EDR・コンテナ監視で見るべき兆候
CVE-2026-15307対策では、Djangoプロセスの振る舞いを監視します。
通常使わないディレクトリへのファイル作成
Pythonパッケージディレクトリへの書込み
テンプレートディレクトリへの書込み
/tmpへの不審な実行ファイル作成Djangoコンテナから内部IPへの突然の接続
クラウドメタデータ相当アドレスへの接続
通常利用しない外部ドメインへのアクセス
Djangoワーカー直後の子プロセス生成
GEOS関連のセグメンテーションフォルト
Djangoワーカーの異常なメモリ増加
Cloudflare WAF、IPS、EDRは多層防御として有効です。
ただし、今回の4件はDjango内部の処理に問題があります。WAFルールへ追加しただけで修正済みとは判断せず、Django 5.2.17への更新を完了させてください。
再発防止
1. Django 5.2系列の最新パッチを継続的に追跡する
Django 5.2 LTSは2028年4月までサポートされます。
ただし、Django 5.2.16を固定したまま2028年まで安全に使えるという意味ではありません。セキュリティ修正版が公開されるたびに、同じ5.2系列の最新パッチへ更新する必要があります。
2. パッチ更新の社内基準を決める
実務上の目安として、次の対応期限を決めておくと判断が遅れにくくなります。
| 深刻度 | 推奨する社内目標 |
|---|---|
| Critical | 原則24時間以内 |
| High | 24~48時間以内 |
| Moderate | 3営業日以内 |
| Low | 次回定期メンテナンスまで |
| 悪用確認済み | 深刻度にかかわらず緊急対応 |
これはDjango公式の期限ではなく、運用ルールの一例です。システムの重要度、公開範囲、メンテナンス可能時間に合わせて調整してください。
3. CIで依存関係を検査する
CIへ次の処理を追加します。
python -m pip checkテストスイート
python -Wa manage.py testpython manage.py checkpython manage.py check --deploy依存関係の脆弱性スキャン
SBOMの生成
コンテナイメージの脆弱性スキャン
4. GeoDjangoを別のリスク領域として管理する
GeoDjangoを使用する場合は、通常のORM入力とは別に次を管理します。
WKT、WKB、GeoJSONの最大サイズ
GeometryCollectionの最大数
GDALドライバー
GDAL仮想ファイルシステム
ファイル書込み先
外向きネットワークアクセス
Django Adminの権限
空間検索へ渡せる入力型
5. URLFieldへ保存する値を入口で検証する
表示時のエスケープだけに依存しないでください。
外部入力
│
▼
スキームと形式を検証
│
▼
許可されたURLだけを保存
│
▼
表示時にも再検証
入力時と表示時の両方で検証することで、一方の処理が迂回された場合にも影響を小さくできます。
6. Django Adminを一般公開しない
可能な場合は、次を組み合わせます。
VPNまたはWireGuard
IP制限
多要素認証
staff権限の定期棚卸し
モデル単位の最小権限
管理画面操作ログ
管理画面URLへのレート制限
不要なモデルをAdminへ登録しない
注意点・よくある誤解
「LTSだから5.2.16のままでも安全」は誤り
LTSは、対象系列へ長期間セキュリティ修正が提供される仕組みです。
古いパッチバージョンが自動的に修正される仕組みではありません。
「RCEと書かれているので全Djangoサイトが即侵害される」は誤り
今回のRCEは、GeoDjango経由のファイル書込みが特定の条件下でコード実行へ発展する可能性を示しています。
GeoDjangoを利用していない一般的なDjangoサイトで、トップページへアクセスするだけでRCEが成立する問題ではありません。
「GeoDjangoを使っていないから更新不要」は誤り
GeoDjangoを使っていなくても、次の2件が関係します。
CVE-2026-15337
CVE-2026-15920
さらに、セキュリティパッチは既知の問題をまとめて解消するため、Django 5.2.17への更新は必要です。
「AdminをVPN内に置けば修正不要」は誤り
VPNは攻撃可能な利用者を減らしますが、次の問題は残ります。
内部アカウントの侵害
権限設定の誤り
外部APIからの不正データ保存
独自の空間検索API
管理者による不正リンクのクリック
「Cloudflare WAFがあるから更新不要」は誤り
WAFはHTTPリクエストを検査できますが、Django内部の型変換、GDALドライバー、GEOSの再帰処理、保存済みURLの表示処理を完全には再現できません。
WAFは緩和策であり、修正版への更新が本対応です。
悪用状況について
Django公式の2026年8月4日の告知には、実環境での悪用が確認されたという記載はありません。
ただし、公式告知に悪用の記載がないことは、世界中で悪用が一切行われていないことを証明するものではありません。
2026年8月5日時点では、次のように区別する必要があります。
確認できる事実
Django 5.2.16は4件の修正対象である
Django 5.2.17が公開されている
CVE-2026-15307はHigh評価である
ファイル書込み、SSRF、条件付きRCEの可能性がある
Django公式は速やかな更新を推奨している
確認できないこと
kurutann.comが実際に攻撃を受けたか
公開されていない攻撃で悪用されているか
すべてのGDAL構成で同じ方法のRCEが成立するか
WAFだけで全攻撃パターンを遮断できるか
不明な点を推測で断定せず、バージョン更新、コード確認、ログ確認を組み合わせて判断してください。
まとめ
Django 5.2.16には、次の4件のセキュリティ問題があります。
GeoDjangoの空間検索によるファイル書込み・SSRF・条件付きRCE
長大な言語コードによるメモリDoS
入れ子のGeometryCollectionによるGEOSクラッシュ
Django AdminのURLFieldによる格納型XSS
現在Django 5.2.16 LTSを利用している場合は、Django 5.2.17 LTSへ更新してください。
GeoDjangoを使用していない場合、CVE-2026-15307とCVE-2026-15830の代表的な攻撃経路は存在しない可能性があります。しかし、残る2件への対応と、将来の安全な運用のためにパッチ更新は必要です。
更新後は、バージョン表示だけで完了とせず、Django Admin、URLField、GIS、API、認証、Redis、WebSocket、ファイルアップロードまで動作確認してください。
Cloudflare WAF、IPS、EDR、コンテナ制限、外向き通信制限は重要な補助対策です。しかし、脆弱なDjango本体を修正するものではありません。
FAQ
Django 5.2.16は今回の脆弱性の影響を受けますか
はい。
Django 5.2.17の公式リリースノートは、Django 5.2.16に存在するHigh 1件、Moderate 2件、Low 1件を修正したと明記しています。
Django 5.2.17へ更新すればDjango 6へ移行する必要はありませんか
今回の4件への対応だけであれば、Django 5.2.17への更新で対応できます。
Django 5.2はLTSであり、2028年4月まで延長サポートされる予定です。
GeoDjangoを使っていなければRCEの影響はありませんか
CVE-2026-15307の代表的な攻撃経路はGeoDjangoの空間検索です。
django.contrib.gis、空間フィールド、GDALRaster、独自GIS処理を使用していない場合、通常は直接到達しません。
ただし、コード検索とインストール済み機能の確認を行ってから判断してください。
Django Adminを無効にしていればCVE-2026-15307は安全ですか
Django Admin経由の代表的な経路は閉じられます。
しかし、独自APIや検索画面が未信頼入力を空間検索へ渡している場合は、別の経路から到達する可能性があります。
CVE-2026-15920はリンクを表示しただけで発動しますか
Django公式の説明では、危険な値がクリック可能なリンクとして表示される問題です。
代表的な攻撃では、管理者がリンクをクリックする必要があります。
ただし、危険な値を保存できる経路自体も修正してください。
set_language()を使っていなければCVE-2026-15337は関係ありませんか
Django公式が示す入力経路は、デフォルトでは有効でないset_language()です。
URLへ登録していなければ代表的な経路はありません。ただし、check_for_language()を独自処理から呼び出している場合は確認してください。
Dockerコンテナ内で直接pip installしてもよいですか
一時的な検証以外では推奨しません。
実行中コンテナへ直接インストールすると、コンテナを再作成した際に更新が失われます。requirementsやロックファイルを更新し、Dockerイメージを再ビルドしてください。
データベースのマイグレーションは必要ですか
プロジェクト側のモデル変更状況によって異なります。
makemigrations --check --dry-runとmigrate --planを実行し、意図しない差分がないことを確認してください。
更新後に空間検索が失敗するのはなぜですか
CVE-2026-15307の修正により、空間検索へ渡せる入力型が制限されました。
辞書や、有効なGEOSGeometryではない文字列を空間検索へ渡している場合は、入力を検証し、適切なGISオブジェクトへ明示的に変換する必要があります。
参考情報
Django公式のセキュリティ情報
Django 6.0.8および5.2.17のセキュリティリリース
Django Software Foundationによる今回の公式セキュリティ告知です。
CVE-2026-15307、CVE-2026-15337、CVE-2026-15830、CVE-2026-15920の影響、深刻度、修正内容、影響するDjango系列がまとめられています。
https://www.djangoproject.com/weblog/2026/aug/04/security-releases/
Django 5.2.17リリースノート
Django 5.2.16から5.2.17へ更新した際の変更内容を確認できます。
GeoDjangoの空間検索で受け入れられる値の変更、言語コードの500文字制限、GeometryCollectionの上限、Django AdminのURLField検証が記載されています。
https://docs.djangoproject.com/en/5.2/releases/5.2.17/
Djangoのセキュリティポリシー
Djangoにおける脆弱性の深刻度、セキュリティリリースの対象系列、脆弱性の報告方法を確認できます。
https://docs.djangoproject.com/en/dev/internals/security/
Djangoのサポート対象バージョン
Django 5.2 LTSのサポート期間と、現在利用可能な正式リリースを確認できます。
https://www.djangoproject.com/download/
CVE情報
CVE-2026-15307
GeoDjangoの空間検索を通じて、サーバー側ファイル書込みやSSRFが発生する可能性がある脆弱性です。
環境や書込み先などの条件がそろった場合、リモートコード実行へ発展する可能性があります。
NVD:
https://nvd.nist.gov/vuln/detail/CVE-2026-15307
Debian Security Tracker:
https://security-tracker.debian.org/tracker/CVE-2026-15307
CVE-2026-15337
django.utils.translation.check_for_language()へ多数の異なる長大な言語コードを渡すことで、Djangoプロセスのメモリを消費させる可能性がある脆弱性です。
NVD:
https://nvd.nist.gov/vuln/detail/CVE-2026-15337
Debian Security Tracker:
https://security-tracker.debian.org/tracker/CVE-2026-15337
CVE-2026-15830
深く入れ子になったGEOMETRYCOLLECTIONをGeoDjangoで解析すると、GEOSでセグメンテーションフォルトが発生する可能性がある脆弱性です。
NVD:
https://nvd.nist.gov/vuln/detail/CVE-2026-15830
Debian Security Tracker:
https://security-tracker.debian.org/tracker/CVE-2026-15830
CVE-2026-15920
安全でないURLスキームを含むURLFieldの値がDjango Adminでリンクとして表示され、管理者がクリックした場合に格納型XSSが発生する可能性がある脆弱性です。
NVD:
https://nvd.nist.gov/vuln/detail/CVE-2026-15920
Debian Security Tracker:
https://security-tracker.debian.org/tracker/CVE-2026-15920
Django 5.2系列の公式修正コミット
CVE-2026-15307の修正コミット
空間検索において、文字列や辞書が暗黙的にGDALRasterへ渡される処理を制限した修正です。
https://github.com/django/django/commit/115ffd0463a765ab1cc93de18e94b5459b8a300e
CVE-2026-15337の修正コミット
500文字を超える言語コードを、キャッシュされた言語検索へ渡す前に拒否する修正です。
https://github.com/django/django/commit/c72a5dbb64d0777f3f471f1be94e8b2ca91e0959
CVE-2026-15830の修正コミット
WKTとWKBで処理できるGEOMETRYCOLLECTIONの深さと総数に上限を追加した修正です。
https://github.com/django/django/commit/ba80833fa656dd09660b97c4429331067db1b080
CVE-2026-15920の修正コミット
Django AdminでURLFieldをリンクとして表示する前に、URLValidatorで検証する修正です。
https://github.com/django/django/commit/b9adb81339cc418f8f56b1050cca6dfec3ab6349
GeoDjango・GDALの公式資料
Django公式のGDAL API
GeoDjangoからGDALを利用する方法、GDALRaster、仮想ファイルシステム、ラスター処理の仕様を確認できます。
https://docs.djangoproject.com/en/5.2/ref/contrib/gis/gdal/
Django公式のGeoDjangoデータベースAPI
空間検索、GeometryField、RasterField、地理空間ルックアップの仕様を確認できます。
https://docs.djangoproject.com/en/5.2/ref/contrib/gis/db-api/
Django公式の空間ルックアップ一覧
GeoDjangoで利用できる空間検索と、検索値として扱われるジオメトリやラスターの仕様を確認できます。
https://docs.djangoproject.com/en/5.2/ref/contrib/gis/geoquerysets/
GDALのセキュリティ情報
GDALドライバー、外部データ、ネットワークアクセス、信頼できない入力を処理する際の注意点を確認できます。
https://gdal.org/en/stable/user/security.html
GDAL仮想ファイルシステム
GDALがローカルファイル以外のHTTP、クラウドストレージ、圧縮ファイルなどを扱う仮想ファイルシステムの仕様です。
https://gdal.org/en/stable/user/virtual_file_systems.html
Djangoの更新・本番運用資料
Djangoを新しいバージョンへ更新する方法
更新前のリリースノート確認、非推奨警告の表示、テスト方法など、Django公式のアップグレード手順です。
https://docs.djangoproject.com/en/5.2/howto/upgrade-version/
Djangoの本番デプロイチェックリスト
DEBUG、SECRET_KEY、HTTPS、Cookie、データベース、キャッシュ、バックアップなど、本番環境で確認すべき項目がまとめられています。
https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
Djangoの国際化機能
set_language()、言語選択、URL設定、翻訳機能の利用方法を確認できます。
https://docs.djangoproject.com/en/5.2/topics/i18n/translation/
set_language()ビュー
CVE-2026-15337の入力経路となる可能性がある、Django標準の言語切替ビューの仕様です。
https://docs.djangoproject.com/en/5.2/topics/i18n/translation/#the-set-language-redirect-view
URLValidator
DjangoがURLの形式と許可されたスキームを検証するURLValidatorの仕様です。
https://docs.djangoproject.com/en/5.2/ref/validators/#urlvalidator
パッケージ情報
PyPIのDjango 5.2.17
Django 5.2.17のパッケージ情報、配布ファイル、公開日時を確認できます。
https://pypi.org/project/Django/5.2.17/
Django公式GitHubリポジトリ
Django本体のソースコード、コミット履歴、ブランチ、タグを確認できます。
https://github.com/django/django
関連記事
Django 5.2.15以前の脆弱性と重大バグ
Django 5.2.16までに修正されたSQLインジェクション、共有キャッシュからの情報漏えい、ASGIのDoS、管理画面、メールなどの問題をまとめています。
https://kurutann.com/diary/detail/1724/
本記事は、上記記事の続報です。
2026年7月時点ではDjango 5.2.16が修正版でしたが、2026年8月4日にDjango 5.2.17が公開されたため、現在の更新先はDjango 5.2.17となります。
報道記事
GBHackers:Django Flaws Let Attackers Trigger RCE, SSRF, DoS, and XSS Attacks
今回の4件をRCE、SSRF、DoS、XSSの観点からまとめた報道記事です。
見出しだけでは攻撃成立条件が省略されているため、脆弱性の正確な影響判断にはDjango公式告知とリリースノートを優先してください。
https://gbhackers.com/django-flaws/
参照時の注意
脆弱性の影響範囲、修正版、後方互換性のない変更については、Django公式のセキュリティ告知とDjango 5.2.17リリースノートを一次情報として扱ってください。
NVDのCVSS評価や悪用状況は、公開直後には未評価または暫定値になっている場合があります。
報道記事や第三者の脆弱性データベースは概要把握に利用し、実際の更新判断ではDjango公式情報と修正コミットを確認してください。
コメント(0件)
まだコメントはありません。最初のコメントを投稿してください!