CVE-2026-53538: python-multipart Semicolon Treated As Querystring Field Vulnerability

LOW
Advisory Identifier: GHSA-6jv3-5f52-599m
CVSS 3.7
CWE-436 CWE-444
Published
Advisory Summary

CVE-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

CVE Identifier CVE-2026-53538
GHSA Identifier GHSA-6jv3-5f52-599m
Severity LOW
CVSS v3.1 Base Score 3.7
CWE Classification CWE-436: Interpretation Conflict
Affected Product python-multipart
Package Ecosystem PyPI
Published Date
Last Updated

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).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity Low (I:L)
Availability None (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.

python-multipart fixed: 0.0.30
pip install python-multipart>=0.0.30
Verify Direct and Transitive Dependencies

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

### Summary `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. ### Details In `python_multipart/multipart.py`, the `FIELD_NAME` and `FIELD_DATA` states located the next separator by scanning for `&` and, failing that, for `;`: ```python sep_pos = data.find(b"&", i) if sep_pos == -1: sep_pos = data.find(b";", i) ``` As 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`. For example, a body inspecting WAF or gateway that follows the WHATWG rule (only `&` separates fields) receives: ``` role=user&x=;role=admin ``` The 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. The 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. ### Impact Interpretation 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. ### Mitigation Upgrade 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.

CVE-2026-53538 Affected python-multipart Versions

1 component(s)
Fixed Versions:
0.0.30
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?
CVE-2026-53538 is a security vulnerability in python-multipart involving Semicolon treated as querystring field separator enables parameter smuggling under CWE-436: Interpretation Conflict.
Which python-multipart versions are affected?
Affected versions include releases prior to 0.0.30 across affected packages: python-multipart.
What version fixes CVE-2026-53538?
Upgrading to 0.0.30 (or the latest patched release for your respective branch) resolves the vulnerability.
Is python-multipart affected?
Yes, python-multipart is affected in releases prior to 0.0.30. Upgrade your dependency to 0.0.30 or later.
What is the CVSS score of CVE-2026-53538?
CVE-2026-53538 has a CVSS v3.1 base score of 3.7 (LOW) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N.
What CWE is associated with CVE-2026-53538?
CVE-2026-53538 is classified under CWE-436: Interpretation Conflict (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.).
How can I check PyPI dependencies for CVE-2026-53538?
Run the dependency tree command: 'pip show python-multipart'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "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
  }
}