CVE-2026-53538: python-multipart Semicolon Treated As Querystring Field Vulnerability
LOWCVE-2026-53538 is a LOW (CVSS 3.7) semicolon treated as querystring field vulnerability (CWE-436: Interpretation Conflict) affecting python-multipart libraries in the PyPI ecosystem. The issue involves semicolon treated as querystring field separator enables parameter smuggling. Remediation is available by upgrading affected packages to version 0.0.30.
CVE-2026-53538 at a Glance
Security Impact
CVSS: 3.7
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N).
How to Fix CVE-2026-53538
To remediate this vulnerability, upgrade all affected python-multipart dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
pip install python-multipart>=0.0.30
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show python-multipart
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2026-53538, inspect your installed packages using pip:
pip show python-multipart
Analyze the terminal output to locate any version of python-multipart in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.0.30), your application is affected.
Note: The pip show python-multipart command checks currently installed packages in your active Python environment.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-436: Interpretation Conflict, where product a handles inputs or steps differently than product b, which causes a to perform incorrect actions based on its perception of b's state. In python-multipart, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-53538 Affected python-multipart Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
python-multipart
|
PyPI |
< 0.0.30
|
0.0.30
|
References
Frequently Asked Questions
What is CVE-2026-53538?
Which python-multipart versions are affected?
What version fixes CVE-2026-53538?
Is python-multipart affected?
What is the CVSS score of CVE-2026-53538?
What CWE is associated with CVE-2026-53538?
How can I check PyPI dependencies for CVE-2026-53538?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-6jv3-5f52-599m",
"modified" : "2026-06-15T20:22:25Z",
"published" : "2026-06-15T20:22:25Z",
"aliases" : [ "CVE-2026-53538" ],
"summary" : "python-multipart: Semicolon treated as querystring field separator enables parameter smuggling",
"details" : "### Summary\n\n`QuerystringParser` treated `;` as a field separator in `application/x-www-form-urlencoded` bodies, in addition to `&`. The [WHATWG URL standard](https://url.spec.whatwg.org/#urlencoded-parsing), modern browsers, and Python's `urllib.parse` (since the CVE-2021-23336 fix) treat only `&` as a separator. This creates a parser differential: the same bytes are tokenized into different fields than a WHATWG compliant intermediary would produce, allowing an attacker to smuggle extra form fields past an upstream body inspecting component.\n\n### Details\n\nIn `python_multipart/multipart.py`, the `FIELD_NAME` and `FIELD_DATA` states located the next separator by scanning for `&` and, failing that, for `;`:\n\n```python\nsep_pos = data.find(b\"&\", i)\nif sep_pos == -1:\n sep_pos = data.find(b\";\", i)\n```\n\nAs a result, `;` acted as a field boundary. Because the fallback only triggered when no `&` remained in the current chunk, tokenization also depended on unrelated bytes later in the buffer and on how the body was split across `write()` calls. This is the same class of issue as CVE-2021-23336 in CPython's `urllib.parse`.\n\nFor example, a body inspecting WAF or gateway that follows the WHATWG rule (only `&` separates fields) receives:\n\n```\nrole=user&x=;role=admin\n```\n\nThe upstream parses two fields, `role=user` and `x=\";role=admin\"`, sees a benign `role=user`, and forwards the request. `QuerystringParser` parsed the same bytes as three fields: `role=\"user\"`, `x=\"\"`, and `role=\"admin\"`. The application (for example via Starlette/FastAPI `request.form()`, where the last value wins) then received `role=admin`, a value the upstream validator never saw.\n\nThe parser is reachable through the public `QuerystringParser` class, the high level `FormParser`, `create_form_parser`, and `parse_form` APIs, and Starlette/FastAPI `request.form()` for url encoded bodies.\n\n### Impact\n\nInterpretation conflict / HTTP parameter pollution. An attacker can smuggle extra or overriding form fields past an upstream component that applies the WHATWG separator rule, reaching the backend with parameters the intermediary did not observe.\n\n### Mitigation\n\nUpgrade to `python-multipart` `0.0.30` or later, which treats only `&` as a field separator per the [WHATWG URL standard](https://url.spec.whatwg.org/#urlencoded-parsing). `;` is parsed as ordinary field data, matching `urllib.parse`, browsers, and other compliant parsers.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "python-multipart"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.0.30"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/Kludex/python-multipart/security/advisories/GHSA-6jv3-5f52-599m"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/Kludex/python-multipart"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-436", "CWE-444" ],
"severity" : "LOW",
"github_reviewed" : true,
"github_reviewed_at" : "2026-06-15T20:22:25Z",
"nvd_published_at" : null
}
}