[Django] #36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is invalid

0 views
Skip to first unread message

Django

unread,
Feb 15, 2026, 10:18:52 PM (10 hours ago) Feb 15
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Type: Bug
Status: new | Component: HTTP
| handling
Version: 6.0 | Severity: Normal
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
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()](https://github.com/django/django/blob/main/django/utils/http.py#L332),
[django/utils/http.py](https://github.com/django/django/blob/main/django/utils/http.py)
passes the encoding to `urllib.parse.unquote()`, which raises
`LookupError`.

The caller in
[django/http/multipartparser.py](https://github.com/django/django/blob/main/django/http/multipartparser.py#L729)
only catches `ValueError`:

{{{#!python
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 ==
1. Create a simple upload view:
{{{#!python
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)
}}}
2. Send a multipart request with a bogus encoding:
{{{#!python
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/36931>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 15, 2026, 10:36:51 PM (10 hours ago) Feb 15
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by sammiee5311:

Old description:
New description:
PR link: https://github.com/django/django/pull/20714

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:1>

Django

unread,
3:34 AM (5 hours ago) 3:34 AM
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by sammiee5311):

PR: https://github.com/django/django/pull/20714

All tests pass (requests_tests — 115 tests) under SQLite, Python 3.14,
macOS.
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:2>
Reply all
Reply to author
Forward
0 new messages