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

