#37292 new Bug

TemporaryUploadedFile raises OSError for a filename with a very long extension

Reported by: Prakhar Pratyush Owned by:
Component: File uploads/storage Version: 5.2
Severity: Normal Keywords:
Cc: Prakhar Pratyush Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Uploading a file whose extension is long enough makes the request die with an unhandled OSError instead of the name being sanitized.

TemporaryUploadedFile takes the extension straight off the client-supplied filename and uses it as the suffix of the temporary file:

    _, ext = os.path.splitext(name)
    file = tempfile.NamedTemporaryFile(
        suffix=".upload" + ext, dir=settings.FILE_UPLOAD_TEMP_DIR
    )
    super().__init__(file, name, content_type, size, charset, content_type_extra)

NAME_MAX is 255 bytes on ext4 and most other filesystems, and tempfile adds "tmp" plus 8 random characters on top of the 7-byte ".upload", so an extension of 238 bytes or more is enough to make os.open() fail.

Replication

>>> from django.core.files.uploadedfile import TemporaryUploadedFile
>>> TemporaryUploadedFile("x." + "a" * 250, "text/plain", 6, None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/srv/zulip/.venv/lib/python3.10/site-packages/django/core/files/uploadedfile.py", line 77, in __init__
    file = tempfile.NamedTemporaryFile(
  File "/usr/lib/python3.10/tempfile.py", line 714, in NamedTemporaryFile
    file = _io.open(dir, mode, buffering=buffering,
  File "/usr/lib/python3.10/tempfile.py", line 711, in opener
    fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
  File "/usr/lib/python3.10/tempfile.py", line 395, in _mkstemp_inner
    fd = _os.open(file, flags, 0o600)
OSError: [Errno 36] File name too long: '/tmp/tmpm5gby_up.upload.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

Also:

Over a real request you need an upload larger than FILE_UPLOAD_MAX_MEMORY_SIZE so that MemoryFileUploadHandler declines it and the temporary file handler takes over. Anything that reads request.POST on that request will then raise, it comes out as a 500.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top