When a multipart form upload includes an RFC 2231 encoded filename* parameter with an invalid encoding name (e.g., filename*=BOGUS''test%20file.txt), parse_header_parameters(), django/utils/http.py passes the encoding to urllib.parse.unquote(), which raises LookupError.
The caller in django/http/multipartparser.py only catches ValueError:
except ValueError: # Invalid header.
continue
Since LookupError is not a subclass of ValueError, the exception propagates and results in a 500 Internal Server Error.
Steps to Reproduce
- Create a simple upload view:
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload(request):
if request.method == "POST" and request.FILES:
return JsonResponse({"filename": request.FILES["file"].name})
return JsonResponse({"error": "No file"}, status=400)
- Send a multipart request with a bogus encoding:
import http.client
boundary = "----PoC"
body = (
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"file\"; "
f"filename*=BOGUS''test%20file.txt\r\n"
f"Content-Type: application/octet-stream\r\n"
f"\r\n"
f"content\r\n"
f"--{boundary}--\r\n"
)
conn = http.client.HTTPConnection("localhost", 8000)
conn.request("POST", "/upload/", body=body.encode(),
headers={"Content-Type": f"multipart/form-data; boundary={boundary}"})
print(conn.getresponse().status) # Returns 500
The filename must contain at least one percent-encoded character (e.g., %20) for unquote() to invoke the codec.
Confirmed on Django 6.0.2, Python 3.14.
PR link: https://github.com/django/django/pull/20714
PR: https://github.com/django/django/pull/20714
All tests pass (requests_tests — 115 tests) under SQLite, Python 3.14, macOS.