SJ blog
backend
S

信頼度ランク

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環境(uvicorndaphneなど)でリクエストを受け取るとき、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サーバーレベルの制限。両方の実施が推奨される。


参考リンク