python-multipart, HTTP Parameter Pollution, CVE-2021-23336 (Medium) -DC-Jun2026-447

Listen to this Post

Intro – How CVE-2021-23336 works (and why it applies to python-multipart)
CVE-2021-23336 originally affected CPython’s `urllib.parse` when parsing `application/x-www-form-urlencoded` query strings. The standard (WHATWG URL) and modern browsers treat only `&` as a field separator. However, older `urllib.parse` versions also considered `;` as a separator, creating a parser differential. An attacker could inject `;role=admin` into a parameter value – e.g., role=user&x=;role=admin. A WHATWG‑compliant intermediary (WAF, reverse proxy) would see two fields: `role=user` and x=;role=admin. The backend using the vulnerable `urllib.parse` would split `x=;role=admin` into `x=` and role=admin, thereby overriding the `role` parameter to admin. This allowed parameter smuggling and cache poisoning.
The same logic flaw exists in `python-multipart` before version 0.0.30. In python_multipart/multipart.py, the `FIELD_NAME` and `FIELD_DATA` states locate separators by first scanning for &, and if none is found, they fall back to ;. Consequently, `;` acts as a field boundary. The fallback triggers only when no `&` remains in the current chunk, making tokenization dependent on buffer splits. An attacker can craft a body like role=user&x=;role=admin. An upstream WHATWG‑compliant component parses two fields (role=user, x=;role=admin) and forwards the request. `QuerystringParser` inside python-multipart parses the same bytes into three fields: role=user, x=, and role=admin. The application (e.g., Starlette/FastAPI request.form(), where last value wins) then sees `role=admin` – a value the upstream never validated. This enables HTTP parameter pollution and smuggling of arbitrary form fields past security checks.

DailyCVE Form:

Platform: python-multipart
Version: <0.0.30
Vulnerability: Parameter smuggling
Severity: Medium
date: 2024-02-05

Prediction: 2024-02-20

What Undercode Say:

Simulate vulnerable parser behavior
python3 -c "
from python_multipart import parse_form
body = b'role=user&x=;role=admin'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
result = parse_form(headers, body, charset='utf-8')
print('Parsed fields:', result[bash])
"

Exploit:

Send POST request with body role=user&x=;role=admin. Upstream WAF sees only role=user. Backend python-multipart <0.0.30 extracts role=admin, overwriting the intended role.

Protection:

Upgrade to python-multipart>=0.0.30. No backport needed. Alternatively, manually patch `multipart.py` to remove `;` as separator (scan only for &).

Impact:

Interpretation conflict leading to HTTP parameter pollution. Attacker can smuggle admin parameters, bypass input validation, modify state, or escalate privileges in frameworks relying on request.form().

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top