2026年10月6日、PythonのWebフレームワークDjangoが、セキュリティ修正を含む6.1.2、6.0.9、5.2.18を公開しました。修正された脆弱性は4件で、深刻度は低が1件、中が3件です。
公式ブログでは、Djangoを使っているすべての人に、できるだけ早く更新するよう呼びかけています。Djangoでアプリを作っている方は、手元のバージョンを確かめておきましょう。
とはいえ、脆弱性の説明は専門用語が多く、何が危ないのかつかみにくいですよね。今回は、それぞれの問題をできるだけかみ砕いて見ていきます。
まずは何が修正されたのかを整理しよう¶
最初に、今回修正された4件を表にまとめます。内容は、Djangoの公式リポジトリにあるリリースノートにもとづいています。
| 識別番号 | 問題の種類 | 深刻度 |
|---|---|---|
| CVE-2026-77050 | 長い言語コードでメモリを使い果たすおそれ | 低 |
| CVE-2026-84429 | HTTPヘッダーの解析で処理が極端に遅くなるおそれ | 中 |
| CVE-2026-87890 | 地図データの検索で意図しない通信が起きるおそれ | 中 |
| CVE-2026-87975 | フォームセットで許されていない削除や作成ができるおそれ | 中 |
CVEは、公開された脆弱性に付けられる世界共通の識別番号です。番号で検索すれば、世界中の情報をまとめて調べられます。
Djangoそのものがまだよくわからない方は、先にこちらを読んでおくと話がつながります。【関連記事】PythonのDjangoとは?
修正された版と対象の系列¶
今回の修正は、セキュリティサポート中の3つの系列にそろって入っています。自分が使っている系列の修正版を、表で確かめてください。
| 系列 | 修正版 | 公開日 |
|---|---|---|
| 6.1系 | 6.1.2 | 2026年10月6日 |
| 6.0系 | 6.0.9 | 2026年10月6日 |
| 5.2系(長期サポート版) | 5.2.18 | 2026年10月6日 |
Djangoのセキュリティポリシーによると、修正版が出るのはサポート中の版だけです。古い系列も影響を受ける可能性はありますが、調査も修正も行われません。
つまり、この表にない系列を使っている場合は、修正版そのものが出ていないということです。サポートの切れた系列を使い続けること自体が、いちばんのリスクだと考えてください。
Djangoのサポートの仕組みは、2028年から大きく変わることが決まっています。【関連記事】Djangoが年1回リリースへ
Djangoの深刻度は3段階¶
表にある低や中という深刻度は、Djangoのセキュリティポリシーで決められた区分です。基本的には、攻撃の種類によって決まります。
ポリシーに書かれた区分を、表にまとめます。
| 深刻度 | 主な攻撃の種類 |
|---|---|
| 高 | 遠隔からのコード実行、SQLインジェクション |
| 中 | クロスサイトスクリプティング、CSRF、認証の不備 |
| 低 | サービス停止攻撃、機密データの露出、珍しい設定が前提の問題など |
ただし、セキュリティチームは個々の事情に応じて深刻度を調整できるとも書かれています。今回のHTTPヘッダーの問題は、サービス停止の一種ですが中と判定されました。
今回は高の問題は含まれていません。それでも、中が3件というのは軽く見てよい数ではありません。
4つの脆弱性を順番に見ていく¶
ここからは、それぞれの問題を初心者向けに言い換えて紹介します。細かな条件は、リリースノートの原文で確認してください。
長い言語コードでメモリを使い果たす¶
1つ目は、表示する言語を選ぶ処理の問題です。Djangoには、利用者のブラウザの設定などから、使う言語を判断する仕組みがあります。
この処理では、言語コードを長さで制限する前に、メモリ上の一時保存場所へ記録していました。とても長い言語コードを大量に送られると、メモリを使い果たすおそれがあったわけです。
修正後は、500文字を超える言語コードは、記録の前に拒否されるか切り詰められます。
HTTPヘッダーの解析が極端に遅くなる¶
2つ目は、ブラウザから届くHTTPヘッダーを読み取る処理の問題です。特定の形の値を送られると、処理時間がデータの量の2乗に比例して増えてしまいました。
リリースノートによると、ログインしていない利用者からのリクエストでも、この処理に到達できたそうです。たとえばAcceptやContent-Typeといった、どのリクエストにも付くようなヘッダーが入口になりえました。
修正後は、Python標準ライブラリのemail.message.Messageを使って解析するようになっています。その影響で、形の崩れた一部のヘッダーは、これまでと違う読まれ方をすることがあります。
地図データの検索で意図しない通信が起きる¶
3つ目は、地図や位置情報を扱うGeoDjangoという機能の問題です。GeoDjangoを使っていないアプリには関係ありません。
検索の条件に、ラスターと呼ばれる画像形式の地図データをバイト列のまま渡せる状態になっていました。中に外部の場所を指すデータが含まれていると、サーバーがそこへ通信してしまうおそれがあったのです。
修正後は、バイト列のラスターをGDALRasterで包んでから渡す必要があります。リリースノートでは、これは後方互換性のない変更だと明記されています。
リリースノートは、この問題の説明の最後に、信頼できない利用者の入力は使う前に必ず検証するよう念を押しています。利用者から受け取ったデータをそのまま渡すと、こうした問題の入口になりやすいからです。
フレームワークが守ってくれる範囲には限りがあります。入力のチェックは、最後は自分のコードの責任だと覚えておきましょう。
フォームセットで権限を越えた操作ができる¶
4つ目は、複数のフォームをまとめて扱うモデルフォームセットの問題です。主キーをフォームから設定できるモデルで、偽造したPOSTデータを送ると、許されていない範囲のデータを削除したり作成したりできるおそれがありました。
影響を受けるのは、主キーがOneToOneFieldだったり、自然キーやUUIDの主キーをフォームに含めていたりする場合です。Djangoが標準で使うBigAutoFieldの主キーなら、影響はありませんでした。
主キーを自分で決めるような少し凝った設計ほど、思わぬ落とし穴が潜みやすいという好例です。
脆弱性以外にも直されたこと¶
今回のリリースでは、4件の脆弱性のほかにも、いくつかの不具合が直されています。リリースノートに書かれているものから、主なものを表にまとめました。
| 内容 | 対象 |
|---|---|
| 以前の修正(CVE-2026-15830)が不十分だった問題の追加修正 | GeoDjangoの深く入れ子になった図形の扱い |
| 外部の場所にあるラスターが、閉じたときに削除されてしまう問題 | Django 4.0から続いていたデータ消失 |
| F()式を使ったタプルの検索で、処理が終わらなくなる問題 | Django 5.2からの不具合 |
| 6.1で入った細かな不具合のまとめての修正 | 管理画面や移行処理など |
特に目を引くのは、データ消失の修正です。セキュリティの問題ではありませんが、ファイルが消えてしまうという、利用者にとっては脆弱性と同じくらい痛い不具合でした。
また、以前の修正が不十分だったという追加修正も含まれています。セキュリティの修正は一度で完全に終わるとは限らず、こうして何度か重ねて固められていくものです。
だからこそ、修正版が出るたびに追いかける習慣が大切になります。1回の更新で安心せず、継続して最新の修正版を保つようにしましょう。
自分のバージョンを確かめるコード¶
では、手元のDjangoが修正済みかどうかを確かめてみましょう。系列ごとに修正版が違うので、まず系列を見分けてから比べます。
次のコードは、バージョンの文字列を受け取って、修正済みかどうかを判定します。バージョンの比較には、pipの内部でも使われているpackagingを使っています。
from packaging.version import Version
# 2026年10月6日のセキュリティリリースで修正された版
PATCHED = {
(6, 1): Version("6.1.2"),
(6, 0): Version("6.0.9"),
(5, 2): Version("5.2.18"),
}
def check_django(installed):
v = Version(installed)
fixed = PATCHED.get((v.major, v.minor))
if fixed is None:
return f"Django {installed}: セキュリティサポート外の系列です。サポート中の版へ移行を"
if v < fixed:
return f"Django {installed}: 修正前の版です。{fixed} 以上へ更新してください"
return f"Django {installed}: 修正済みです"
for sample in ["6.1.1", "6.1.2", "6.0.8", "5.2.18", "4.2.30"]:
print(check_django(sample))
手元のPython 3.11で実行した結果です。4.2系のように今回の表にない系列は、サポート外として判定されます。
Django 6.1.1: 修正前の版です。6.1.2 以上へ更新してください
Django 6.1.2: 修正済みです
Django 6.0.8: 修正前の版です。6.0.9 以上へ更新してください
Django 5.2.18: 修正済みです
Django 4.2.30: セキュリティサポート外の系列です。サポート中の版へ移行を
実際の環境で調べるときは、python -m django --versionを実行すると、入っているDjangoのバージョンが表示されます。その値を、このcheck_django()に渡してみてください。
更新するときの進め方¶
修正前の版だった場合は、同じ系列の最新版に上げるのが基本です。系列をまたがない更新なら、互換性の問題はほとんど起きません。
pip install --upgrade "django>=6.1.2,<6.2"
上の例は6.1系の場合です。6.0系なら"django>=6.0.9,<6.1"のように、自分の系列に合わせて範囲を書き換えます。
pipでの更新に不安がある方は、こちらで基本を確認できます。【関連記事】Pythonのpipとは?
ただし、GeoDjangoでバイト列のラスターを検索に使っている場合は、コードの修正も必要です。更新したあと、テストを一通り流して確かめましょう。
私は10年ほどエンジニアとして開発に関わってきましたが、セキュリティ更新を次のリリースのついでにしようと後回しにして、結局数か月放置してしまった現場を見たことがあります。修正版はそれだけで出すくらいの気持ちでいると、更新が溜まりません。
こうした脆弱性の情報を毎回自分で追いかけるのは大変です。pip-auditを使えば、入っているライブラリに既知の脆弱性がないかをまとめて調べられます。【関連記事】pip-auditとは?
まとめ¶
2026年10月6日、Djangoが6.1.2、6.0.9、5.2.18を公開し、4件の脆弱性を修正しました。サービス停止につながる問題や、フォームセットで権限を越えた操作ができる問題などが含まれています。
Djangoを使っている方は、自分の系列の修正版まで更新してください。あわせて、使っている系列がまだサポート中かどうかも、この機会に確かめておくと安心です。
ここまでお読みいただきありがとうございました。