信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
Django 6.0.5・5.2.14セキュリティリリース——ASGIアップロードメモリ制限バイパスの仕組みと対策
2026年5月5日、DjangoがASGIアップロードのContent-Length未検証によるFILE_UPLOAD_MAX_MEMORY_SIZEバイパスを修正。Django 6.0.x・5.2.xユーザーは即時アップグレードを推奨。原因と多層防御策を解説。
一言結論
Django 6.0.5・5.2.14がASGIリクエストのContent-Lengthヘッダー未検証によるFILE_UPLOAD_MAX_MEMORY_SIZEバイパス脆弱性を修正した。深刻度は「低」だが大容量ファイルでメモリ枯渇・サービス低下が起きうる。WSGI環境は非影響。パッチ適用に加えWebサーバーレベルのアップロードサイズ制限の二重防御が推奨される。
何が起きたか
2026年5月5日、DjangoプロジェクトはセキュリティリリースとしてDjango 6.0.5およびDjango 5.2.14を公開した。
修正された脆弱性はASGIアップロードのメモリ制限バイパスだ。
対象: Django 6.0.x, 5.2.x (ASGIデプロイメント)
深刻度: Low(Djangoセキュリティポリシー基準)
影響: Webサーバーレベルの制限がない場合にDoSリスク
非影響: WSGI環境(Gunicorn + 通常Djangoなど)
脆弱性の仕組み
FILE_UPLOAD_MAX_MEMORY_SIZE とは
DjangoはファイルアップロードをメモリかTemporaryFileのどちらで処理するか、サイズに応じて切り替える:
# settings.py(デフォルト値)
FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440 # 2.5 MB
# これを超えるファイルはディスクに書き出される
# これ以下のファイルはメモリ(InMemoryUploadedFile)で処理
バイパスが起きる条件
ASGI環境(uvicorn、daphneなど)でリクエストを受け取るとき、DjangoはアップロードサイズをContent-Lengthヘッダーから事前に取得する。
問題はContent-Lengthが欠落または過小申告されていた場合だ:
POST /upload/ HTTP/1.1
Content-Type: multipart/form-data; boundary=----boundary
# Content-Length: を省略、または実際より小さい値を設定
------boundary
Content-Disposition: form-data; name="file"; filename="huge.bin"
[実際は100MBのデータ]
------boundary--
# ❌ 修正前の動作(概念的)
# DjangoはContent-Lengthから事前サイズを読む
declared_size = int(request.headers.get("Content-Length", 0))
if declared_size <= FILE_UPLOAD_MAX_MEMORY_SIZE:
# 「小さいファイル」と判定してメモリ読み込みを開始
# → 実際には100MBが全部メモリに乗る
data = await request.body()
Content-Lengthが欠落・過小申告されていると、Django側は「小さいファイル」と誤認してメモリ読み込みを続け、FILE_UPLOAD_MAX_MEMORY_SIZEの制限が機能しなくなる。
実際のリスク
公開エンドポイントにファイルアップロード機能がある場合:
→ 攻撃者が大容量ファイルを連続送信
→ Djangoプロセスのメモリが枯渇
→ サービス低下(DoS)
内部APIのみの場合: リスクは大幅に低下
Djangoが「低」深刻度としているのは、Webサーバーレベルでアップロードサイズを制限している場合は影響を受けないためだ。ただし多くのデプロイメントでWebサーバー側の制限を設定していない場合も多い。
対策
1. 即時:パッチ適用
# pip
pip install "Django>=6.0.5" # Django 6.0.x系
pip install "Django>=5.2.14" # Django 5.2.x系
# 確認
python -m django --version
2. Webサーバーレベルの二重防御
Djangoは「Webサーバー側でも制限を設定すべき」と明示している。これは本脆弱性への対策として有効であり、パッチ適用と並行して実施を推奨する。
Nginx(推奨):
server {
# アップロードサイズをWebサーバーレベルで制限(例: 10MB)
client_max_body_size 10M;
location / {
proxy_pass http://django_asgi;
}
}
uvicorn(ASGI)でのhttps越しの場合:
# Nginx → uvicorn構成が一般的
# uvicorn自体にはボディサイズ制限オプションは少ない
# → Nginxの client_max_body_size が有効な防御層
3. ASGI環境かどうかの確認
# manage.py runserver はWSGIのため非影響
# 本番でASGIを使っているかの確認:
# asgi.py の存在確認
# uvicorn/daphne/hypercorn を使用しているか確認
# 起動コマンドで判断
uvicorn myproject.asgi:application # → ASGI(影響あり)
gunicorn myproject.wsgi:application # → WSGI(影響なし)
バージョン確認チートシート
| Django バージョン | 状態 | 対応 |
|---|---|---|
| 6.0.5以上 | 安全 | そのまま |
| 6.0.0〜6.0.4 | 脆弱 | 6.0.5にアップグレード |
| 5.2.14以上 | 安全 | そのまま |
| 5.2.0〜5.2.13 | 脆弱 | 5.2.14にアップグレード |
| 4.2.x | 今回のリリースに含まれず | Webサーバー側制限で対応 |
| 4.2未満 | 非サポート | 速やかにアップグレード |
まとめ
今回の脆弱性はASGI環境特有の問題で、WSGI(Gunicorn等)には影響しない。深刻度は「低」だが公開エンドポイントのアップロード機能では実際のDoSリスクがある。対策は2層:①Django 6.0.5/5.2.14へのパッチ適用、②Nginxのclient_max_body_sizeによるWebサーバーレベルの制限。両方の実施が推奨される。