#33062: Null byte in uploaded filename extension is not cleaned up, results in
exception
-----------------------------------------+------------------------
Reporter: Alex Vandiver | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
A >2.5M file uploaded with a raw null byte anyplace after the `.` in its
filename means that Django attempts to create a tempfile with that same
"extension," which errors out with `ValueError: embedded null byte`.
It's almost certainly a violation of RFC to have a filename with a raw
null byte in it, but it shouldn't result in a 500 when parsing the form.
Here's code to generate a bad request:
{{{
#!/usr/bin/env python3
import io
import requests
contents = io.StringIO("." * (1024 * 1024 * 3))
files = {"docfile": (b"bogus.txt!", contents, "text/plain")}
req = requests.Request("POST", "http://localhost:8000/", files=files,
data={})
prepared = req.prepare()
body = prepared.body
assert isinstance(body, bytes)
prepared.body = body.replace(b"!", b"\x00")
requests.Session().send(prepared)
}}}
...which produces an error with the view:
{{{
from django import forms
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
class UploadFileForm(forms.Form):
docfile = forms.FileField()
@csrf_exempt
def index(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
print(repr(request.FILES['docfile']))
return HttpResponseRedirect('/')
else:
print("Not valid!")
return HttpResponseRedirect('/')
else:
form = UploadFileForm()
return render(request, 'uploads/index.html', {'form': form})
}}}
-----
I'm not sure what the goal is of preserving the "extension" of the
uploaded file in the tempfile that is made; if that's important enough a
behaviour to keep, some amount of escaping on the parsed-out extension may
be necessary.
--
Ticket URL: <https://code.djangoproject.com/ticket/33062>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/049.92fec8dce21c15dbbcebc85edba41ea9%40djangoproject.com.