資安雷達 2026 年 10 月 7 日

2026-10-07 Django 同日修補四個 CVE,formset 可被偽造 POST 越權

primary=https://www.djangoproject.com/weblog/2026/oct/06/security-releases/ primary=https://www.openwall.com/lists/oss-security/2026/10/06/3

Django 同日修補四個 CVE,formset 可被偽造 POST 越權

Django Security Team(經 oss-security 公告)· 2026-10-06

Django 這次的安全更新裡,最值得先看的不是兩個 DoS,而是 CVE-2026-87975:只要 model formset 的主鍵可以從表單設定,攻擊者偽造的 POST 資料就能刪除 limiting queryset 之外的資料列,或在 edit-only formset 裡新增資料列。另一個 CVE-2026-87890 則是 CVE-2026-15307 修補不完全留下的缺口,而且修法是向後不相容的。

Django 團隊在 2026-10-06 同時發布 6.1.2、6.0.9 與 5.2.18,受影響的支援分支為 main、6.1、6.0、5.2。

漏洞機制:formset 的主鍵可以被表單改寫

CVE-2026-87975(severity 為 moderate)發生在 model formset。公告指出,當 model 的主鍵能透過表單設定時,formset 會錯誤接受偽造的 POST 資料,結果是兩種越權:刪除 limiting queryset 以外的實例,或在 edit-only formset 中建立實例。

公告列出的觸發條件有兩類:

  • 主鍵是 OneToOneField(或 inline formset 中以 parent link 當主鍵的 model)。
  • 自然主鍵或 UUID 主鍵被放進表單的 fields。

使用預設 BigAutoField 主鍵的 model 不受影響。也就是說,多數只用預設自增主鍵的專案不必擔心這一項,但常見的「一對一 profile 當 inline」做法就在範圍內。

CVE-2026-87890(moderate)是 GeoDjango 的請求偽造。spatial lookup 原本接受 bytes 形式的 raster 值,不要求先包成 django.contrib.gis.gdal.GDALRaster。這些 bytes 雖然經由 GDAL 的記憶體虛擬檔案系統開啟,卻可以是一份 VRT 文件,引用外部 raster 來源,讓 GDAL 在準備查詢時以 Django 行程使用者的身分發出網路請求。公告明說這是「overlooked in the fix for CVE-2026-15307」,也就是前一次修補遺漏的路徑。

兩個 DoS:長語言代碼與 header 解析

CVE-2026-77050(severity 為 low):django.utils.translation.get_supported_language_variant() 先把語言代碼當作記憶體內快取的 key,才限制長度。攻擊者送出大量互不相同的超長語言代碼,就能讓行程記憶體持續增長。修法是在查快取之前,把超過 500 字元的語言代碼拒絕或截斷。

CVE-2026-84429(moderate):django.utils.http.parse_header_parameters() 解析「引號內含大量分隔符」的值時是二次方時間複雜度。未認證請求可經由 Accept、Content-Type 等 header 觸發,例如 HttpRequest.accepts() 做內容協商的路徑。公告特別提到,單次呼叫的長度限制無法約束重複 header 加總後的大小,所以只靠 header 長度上限不能當緩解。

受影響版本與行為變更

CVE元件嚴重度性質
CVE-2026-77050get_supported_language_variant()low記憶體 DoS
CVE-2026-84429parse_header_parameters()moderate二次方時間 DoS
CVE-2026-87890GIS spatial lookupmoderate經 GDAL 的請求偽造
CVE-2026-87975model formsetsmoderate越權刪除與新增

四個 CVE 都影響 Django 6.1、6.0、5.2 與 main,升級目標分別是 6.1.2、6.0.9、5.2.18。

修補與升級時要檢查的地方

這次有兩處行為會變,升級後可能讓原本能跑的程式出錯。

GIS:傳 raw bytes 給 spatial lookup 的程式碼必須改寫。公告說明,代表有效十六進位幾何的 bytes 仍然接受,但 raster 的 bytes 必須先包裝。

# 舊:bytes 直接當 raster lookup 值
Place.objects.filter(rast__contains=raster_bytes)

# 新:必須明確包成 GDALRaster
from django.contrib.gis.gdal import GDALRaster
Place.objects.filter(rast__contains=GDALRaster(raster_bytes))

上面的 lookup 名稱僅為示意,公告只說明 raster bytes 必須先包裝為 GDALRaster。公告同時提醒:所有不受信任的使用者輸入都應先驗證再使用。

Header 解析:parse_header_parameters() 現在改用 Python 的 email.message.Message 解析。公告提醒,部分畸形或不尋常的 header 值解析結果會不同,例如缺少編碼宣告的 RFC 2231 值現在會被解碼。這個函式在文件中沒有公開,但如果你的專案或套件直接 import 它,或有測試依賴特定畸形 header 的解析結果,升級後要重跑。

影響範圍:誰該先處理

  • 用 model formset 且主鍵可編輯的專案:檢查 inline formset 是否以 OneToOneField 或 parent link 當主鍵,以及 UUID 或自然主鍵是否被列進表單 fields。符合就是最優先的升級對象,因為這是資料被刪或被偽造新增的問題。
  • GeoDjango 使用者:搜尋所有把 bytes 傳給 spatial lookup 的呼叫點,尤其是來源為使用者輸入的。公告指出,只有把攻擊者可控的 bytes 直接傳入 lookup 的應用程式才會被利用。
  • 對外開放的 Django 服務:CVE-2026-84429 不需認證,走一般的內容協商就能觸及。
  • 啟用多語系且接受 Accept-Language 之類輸入的站點:CVE-2026-77050 嚴重度雖為 low,升級成本和其他三項一樣,不必另外處理。

各分支的修補 commit 都列在官方公告,例如 main 分支上 CVE-2026-87975 的修補是 83cbd21,無法立刻升級時可以先 cherry-pick 對應分支的 commit 來評估。

發布使用 Sarah Boyce 的 PGP key(ID 3955B19851EA96EF)簽署,下載 tarball 後請核對 checksum。

公告未提供 CVSS 分數,只標示 Django 自己的 severity 等級;也未說明是否已有實際利用。

原始來源:Django Security releases、oss-security 公告


End of article
0
Would love your thoughts, please comment.x
()
x