VYPR
High severityOSV Advisory· Published Jan 27, 2026· Updated Jan 27, 2026

Python-Multipart has Arbitrary File Write via Non-Default Configuration

CVE-2026-24486

Description

Python-Multipart is a streaming multipart parser for Python. Prior to version 0.0.22, a Path Traversal vulnerability exists when using non-default configuration options UPLOAD_DIR and UPLOAD_KEEP_FILENAME=True. An attacker can write uploaded files to arbitrary locations on the filesystem by crafting a malicious filename. Users should upgrade to version 0.0.22 to receive a patch or, as a workaround, avoid using UPLOAD_KEEP_FILENAME=True in project configurations.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
python-multipartPyPI
< 0.0.220.0.22

Affected products

1

Patches

1
9433f4bbc965

Merge commit from fork

https://github.com/Kludex/python-multipartMarcelo TrylesinskiJan 25, 2026via ghsa
2 files changed · +29 1
  • python_multipart/multipart.py+3 1 modified
    @@ -375,7 +375,9 @@ def __init__(self, file_name: bytes | None, field_name: bytes | None = None, con
     
             # Split the extension from the filename.
             if file_name is not None:
    -            base, ext = os.path.splitext(file_name)
    +            # Extract just the basename to avoid directory traversal
    +            basename = os.path.basename(file_name)
    +            base, ext = os.path.splitext(basename)
                 self._file_base = base
                 self._ext = ext
     
    
  • tests/test_file.py+26 0 added
    @@ -0,0 +1,26 @@
    +from pathlib import Path
    +
    +from python_multipart.multipart import File
    +
    +
    +def test_upload_dir_with_leading_slash_in_filename(tmp_path: Path):
    +    upload_dir = tmp_path / "upload"
    +    upload_dir.mkdir()
    +
    +    # When the file_name provided has a leading slash, we should only use the basename.
    +    # This is to avoid directory traversal.
    +    to_upload = tmp_path / "foo.txt"
    +
    +    file = File(
    +        bytes(to_upload),
    +        config={
    +            "UPLOAD_DIR": bytes(upload_dir),
    +            "UPLOAD_KEEP_FILENAME": True,
    +            "UPLOAD_KEEP_EXTENSIONS": True,
    +            "MAX_MEMORY_FILE_SIZE": 10,
    +        },
    +    )
    +    file.write(b"123456789012")
    +    assert not file.in_memory
    +    assert Path(upload_dir / "foo.txt").exists()
    +    assert Path(upload_dir / "foo.txt").read_bytes() == b"123456789012"
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.