Action not permitted
Modal body text goes here.
Modal Title
Modal Body
Vulnerability from cleanstart
Package airflow-3 version 3.2.1-r4 fixes 16 vulnerabilities: ghsa-4m7w-qmgq-4wj5, ghsa-9x8q-7h8h-wcw9, ghsa-537c-gmf6-5ccf, ghsa-4xpc-pv4p-pm3w, ghsa-5rvq-cxj2-64vf...
| URL | Type | |
|---|---|---|
{
"affected": [
{
"package": {
"ecosystem": "Alpine",
"name": "airflow-3"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.2.1-r4"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"3.2.1-r4"
]
}
],
"credits": [],
"database_specific": {},
"details": "Package airflow-3 version 3.2.1-r4 fixes 16 vulnerabilities: ghsa-4m7w-qmgq-4wj5, ghsa-9x8q-7h8h-wcw9, ghsa-537c-gmf6-5ccf, ghsa-4xpc-pv4p-pm3w, ghsa-5rvq-cxj2-64vf...",
"id": "CLEANSTART-2026-PZ43099",
"modified": "2026-07-30T09:30:18Z",
"published": "2026-07-30T07:10:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/apache/airflow"
}
],
"related": [],
"schema_version": "1.7.3",
"summary": "Security fixes in airflow-3 3.2.1-r4",
"upstream": [
"ghsa-4m7w-qmgq-4wj5",
"ghsa-9x8q-7h8h-wcw9",
"ghsa-537c-gmf6-5ccf",
"ghsa-4xpc-pv4p-pm3w",
"ghsa-5rvq-cxj2-64vf",
"ghsa-82w8-qh3p-5jfq",
"ghsa-wqp7-x3pw-xc5r",
"ghsa-3x9g-8vmp-wqvf",
"ghsa-mgf9-4vpg-hj56",
"ghsa-x746-7m8f-x49c",
"ghsa-pw6j-qg29-8w7f",
"ghsa-6jv3-5f52-599m",
"ghsa-v9pg-7xvm-68hf",
"ghsa-vffw-93wf-4j4q",
"ghsa-jp82-jpqv-5vv3",
"ghsa-cx3h-4qpv-8hc9"
]
}
GHSA-3X9G-8VMP-WQVF
Vulnerability from github – Published: 2026-06-15 20:20 – Updated: 2026-06-15 20:20Summary
When SimpleAsyncHTTPClient follows a 3xx redirect, it shallow-copies the original HTTPRequest, rewrites the URL, decrements max_redirects, and removes only the Host header. It does not clear Authorization, auth_username, auth_password, or auth_mode when the redirect target changes origin.
As a result, credentials intended for one origin can be forwarded to a different origin when follow_redirects=True, which is the default.
Beginning in Tornado 6.5.6, SimpleAsyncHTTPClient matches the default behavior of libcurl (and therefore CurlAsyncHTTPClient): When a redirect changes the scheme, host, or port of the url, the Authorization and Cookie headers will be removed when following the redirect.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "tornado"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.5.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-49853"
],
"database_specific": {
"cwe_ids": [
"CWE-200"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:20:00Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nWhen SimpleAsyncHTTPClient follows a 3xx redirect, it shallow-copies the original HTTPRequest, rewrites the URL, decrements max_redirects, and removes only the Host header. It does not clear Authorization, auth_username, auth_password, or auth_mode when the redirect target changes origin.\n\nAs a result, credentials intended for one origin can be forwarded to a different origin when follow_redirects=True, which is the default.\n\nBeginning in Tornado 6.5.6, `SimpleAsyncHTTPClient` matches the default behavior of `libcurl` (and therefore `CurlAsyncHTTPClient`): When a redirect changes the scheme, host, or port of the url, the `Authorization` and `Cookie` headers will be removed when following the redirect.",
"id": "GHSA-3x9g-8vmp-wqvf",
"modified": "2026-06-15T20:20:00Z",
"published": "2026-06-15T20:20:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tornadoweb/tornado/security/advisories/GHSA-3x9g-8vmp-wqvf"
},
{
"type": "PACKAGE",
"url": "https://github.com/tornadoweb/tornado"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Tornado: Authorization header forwarded across cross-origin redirects in SimpleAsyncHTTPClient"
}
GHSA-4M7W-QMGQ-4WJ5
Vulnerability from github – Published: 2026-06-15 20:11 – Updated: 2026-06-15 20:11Summary
The server_hostname TLS SNI check can be bypassed when an existing connection is reused.
Impact
If an application makes multiple requests to the same domain, but with different per-request server_hostname parameters, then the later calls may succeed by reusing the existing connection when they should have been rejected due to the TLS SNI check.
Workaround
Disable keep_alive if you need to change the server_hostname check between requests.
Patch: https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.14.0"
},
"package": {
"ecosystem": "PyPI",
"name": "aiohttp"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.14.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54275"
],
"database_specific": {
"cwe_ids": [
"CWE-297"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:11:13Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\n\nThe `server_hostname` TLS SNI check can be bypassed when an existing connection is reused.\n\n### Impact\n\nIf an application makes multiple requests to the same domain, but with different per-request `server_hostname` parameters, then the later calls may succeed by reusing the existing connection when they should have been rejected due to the TLS SNI check.\n\n### Workaround\n\nDisable keep_alive if you need to change the `server_hostname` check between requests.\n\n-----\n\nPatch: https://github.com/aio-libs/aiohttp/commit/0ca2b6c28a25726527a8b60f25960262a91ed0e0",
"id": "GHSA-4m7w-qmgq-4wj5",
"modified": "2026-06-15T20:11:13Z",
"published": "2026-06-15T20:11:13Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/aio-libs/aiohttp/security/advisories/GHSA-4m7w-qmgq-4wj5"
},
{
"type": "PACKAGE",
"url": "https://github.com/aio-libs/aiohttp"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "aiohttp: TLS Server Hostname Override Is Ignored When Reusing HTTPS Connections"
}
GHSA-4XPC-PV4P-PM3W
Vulnerability from github – Published: 2026-06-16 23:38 – Updated: 2026-07-18 17:26Impact
A Host-header parsing flaw in the LiteLLM proxy could, under specific conditions, allow unauthenticated access to protected management routes.
The auth layer derived the effective route from request.url.path in litellm/proxy/auth/auth_utils.py::get_request_route(), which Starlette reconstructs from the Host header. A crafted Host could therefore make the auth gate evaluate a different route from the one FastAPI dispatched.
Most deployments are not affected. The bypass is blocked by any upstream layer that validates or normalizes Host, such as:
- a CDN or WAF, such as Cloudflare
- a reverse proxy with
server_nameallowlists - a host-based load balancer
LiteLLM Cloud customers are not affected.
Patches
Fixed in 1.84.0. Upgrade to 1.84.0 or later. No configuration change is required.
Workarounds
If upgrading is not immediately possible, place the proxy behind an upstream component that validates or normalizes the Host header before forwarding (a CDN/WAF, a reverse proxy with explicit server_name allowlists, or a cloud load balancer with host-based routing rules), or otherwise restrict network access to the proxy listener.
References
- Patched release:
v1.84.0
Discovery Credit: Le The Thang (KCSC) and Kim Ngoc Chung (One Mount Group)
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "litellm"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.84.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-49468"
],
"database_specific": {
"cwe_ids": [
"CWE-290"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-16T23:38:26Z",
"nvd_published_at": "2026-06-22T21:16:25Z",
"severity": "CRITICAL"
},
"details": "### Impact\n\nA Host-header parsing flaw in the LiteLLM proxy could, under specific conditions, allow unauthenticated access to protected management routes.\n\nThe auth layer derived the effective route from `request.url.path` in `litellm/proxy/auth/auth_utils.py::get_request_route()`, which Starlette reconstructs from the `Host` header. A crafted `Host` could therefore make the auth gate evaluate a different route from the one FastAPI dispatched.\n\n**Most deployments are not affected.** The bypass is blocked by any upstream layer that validates or normalizes `Host`, such as:\n\n- a CDN or WAF, such as Cloudflare\n- a reverse proxy with `server_name` allowlists\n- a host-based load balancer\n\n**LiteLLM Cloud customers are not affected.**\n\n### Patches\n\nFixed in **`1.84.0`**. Upgrade to `1.84.0` or later. No configuration change is required.\n\n### Workarounds\n\nIf upgrading is not immediately possible, place the proxy behind an upstream component that validates or normalizes the `Host` header before forwarding (a CDN/WAF, a reverse proxy with explicit `server_name` allowlists, or a cloud load balancer with host-based routing rules), or otherwise restrict network access to the proxy listener.\n\n### References\n\n- Patched release: [`v1.84.0`](https://github.com/BerriAI/litellm/releases/tag/v1.84.0)\n\n**Discovery Credit**: Le The Thang (KCSC) and Kim Ngoc Chung (One Mount Group)",
"id": "GHSA-4xpc-pv4p-pm3w",
"modified": "2026-07-18T17:26:13Z",
"published": "2026-06-16T23:38:26Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/BerriAI/litellm/security/advisories/GHSA-4xpc-pv4p-pm3w"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-49468"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-49468"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2491520"
},
{
"type": "PACKAGE",
"url": "https://github.com/BerriAI/litellm"
},
{
"type": "WEB",
"url": "https://github.com/BerriAI/litellm/releases/tag/v1.84.0"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-4xpc-pv4p-pm3w"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/litellm/PYSEC-2026-388.yaml"
},
{
"type": "WEB",
"url": "https://pypi.org/project/litellm"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-49468.json"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "LiteLLM: Authentication Bypass via Host Header Injection"
}
GHSA-537C-GMF6-5CCF
Vulnerability from github – Published: 2026-06-15 20:12 – Updated: 2026-06-15 20:12pyca/cryptography's wheels include a statically linked copy of OpenSSL. The versions of OpenSSL included in wheels prior to cryptograph 48.01 are vulnerable to a security issue. More details about the vulnerability itself can be found in https://openssl-library.org/news/secadv/20260609.txt.
If you are building cryptography source ("sdist") then you are responsible for upgrading your copy of OpenSSL. Only users installing from wheels built by the cryptography project (i.e., those distributed on PyPI) need to update their cryptography versions.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "cryptography"
},
"ranges": [
{
"events": [
{
"introduced": "0.5.0"
},
{
"fixed": "48.0.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-125",
"CWE-1395"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:12:27Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "pyca/cryptography\u0027s wheels include a statically linked copy of OpenSSL. The versions of OpenSSL included in wheels prior to cryptograph 48.01 are vulnerable to a security issue. More details about the vulnerability itself can be found in https://openssl-library.org/news/secadv/20260609.txt.\n\nIf you are building cryptography source (\"sdist\") then you are responsible for upgrading your copy of OpenSSL. Only users installing from wheels built by the cryptography project (i.e., those distributed on PyPI) need to update their cryptography versions.",
"id": "GHSA-537c-gmf6-5ccf",
"modified": "2026-06-15T20:12:27Z",
"published": "2026-06-15T20:12:27Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pyca/cryptography/security/advisories/GHSA-537c-gmf6-5ccf"
},
{
"type": "PACKAGE",
"url": "https://github.com/pyca/cryptography"
},
{
"type": "WEB",
"url": "https://openssl-library.org/news/secadv/20260609.txt"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Vulnerable OpenSSL included in cryptography wheels"
}
GHSA-5RVQ-CXJ2-64VF
Vulnerability from github – Published: 2026-06-15 20:24 – Updated: 2026-06-15 20:24Summary
When parsing application/x-www-form-urlencoded bodies, QuerystringParser located the field separator with a two step lookup: it first scanned the entire remaining buffer for &, and only when no & existed anywhere ahead did it fall back to scanning for ;. For a body that uses ; as the separator and contains no &, every field iteration performed a full failed & scan over the entire remaining buffer before locating the nearby ;. With N semicolon separated fields in a chunk of size B, this yields O(B^2) byte comparisons per chunk.
An attacker can submit a small crafted body of the form a;a;a;... and cause the parser to spend seconds of CPU per request. A handful of concurrent requests can exhaust worker processes.
Details
In python_multipart/multipart.py, both the FIELD_NAME and FIELD_DATA states located the next separator like this:
sep_pos = data.find(b"&", i)
if sep_pos == -1:
sep_pos = data.find(b";", i)
data.find(b"&", i) scans from i to the end of the buffer and returns -1 only when there is no & anywhere in the remainder. For a ; separated body with no &, this failed full buffer scan repeats once per field, making parsing quadratic in the body length.
For example, a 1 MiB url encoded body consisting of a; repeated ~500,000 times, submitted with Content-Type: application/x-www-form-urlencoded, causes the parser to perform on the order of 10^11 byte comparisons, consuming several seconds of CPU for a single request. Cost scales quadratically with chunk size.
The parser is reachable through the public QuerystringParser class and through the high level FormParser, create_form_parser, and parse_form APIs for url encoded bodies. It is also the parser Starlette and FastAPI use for application/x-www-form-urlencoded request bodies via request.form().
Impact
Uncontrolled CPU consumption (denial of service). Parsing is synchronous, so a single small crafted form body occupies the handling worker for seconds, blocking any other work on that worker until parsing finishes. Sustained concurrent requests keep workers continuously busy, degrading or denying service.
Mitigation
Upgrade to python-multipart 0.0.30 or later, which treats only & as a field separator (per the WHATWG URL standard) using a single bounded scan, making parsing linear in the body length.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "python-multipart"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.30"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53539"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-407"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:24:09Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nWhen parsing `application/x-www-form-urlencoded` bodies, `QuerystringParser` located the field separator with a two step lookup: it first scanned the entire remaining buffer for `\u0026`, and only when no `\u0026` existed anywhere ahead did it fall back to scanning for `;`. For a body that uses `;` as the separator and contains no `\u0026`, every field iteration performed a full failed `\u0026` scan over the entire remaining buffer before locating the nearby `;`. With N semicolon separated fields in a chunk of size B, this yields O(B^2) byte comparisons per chunk.\n\nAn attacker can submit a small crafted body of the form `a;a;a;...` and cause the parser to spend seconds of CPU per request. A handful of concurrent requests can exhaust worker processes.\n\n### Details\n\nIn `python_multipart/multipart.py`, both the `FIELD_NAME` and `FIELD_DATA` states located the next separator like this:\n\n```python\nsep_pos = data.find(b\"\u0026\", i)\nif sep_pos == -1:\n sep_pos = data.find(b\";\", i)\n```\n\n`data.find(b\"\u0026\", i)` scans from `i` to the end of the buffer and returns `-1` only when there is no `\u0026` anywhere in the remainder. For a `;` separated body with no `\u0026`, this failed full buffer scan repeats once per field, making parsing quadratic in the body length.\n\nFor example, a 1 MiB url encoded body consisting of `a;` repeated ~500,000 times, submitted with `Content-Type: application/x-www-form-urlencoded`, causes the parser to perform on the order of 10^11 byte comparisons, consuming several seconds of CPU for a single request. Cost scales quadratically with chunk size.\n\nThe parser is reachable through the public `QuerystringParser` class and through the high level `FormParser`, `create_form_parser`, and `parse_form` APIs for url encoded bodies. It is also the parser Starlette and FastAPI use for `application/x-www-form-urlencoded` request bodies via `request.form()`.\n\n### Impact\n\nUncontrolled CPU consumption (denial of service). Parsing is synchronous, so a single small crafted form body occupies the handling worker for seconds, blocking any other work on that worker until parsing finishes. Sustained concurrent requests keep workers continuously busy, degrading or denying service.\n\n### Mitigation\n\nUpgrade to `python-multipart` `0.0.30` or later, which treats only `\u0026` as a field separator (per the [WHATWG URL standard](https://url.spec.whatwg.org/#urlencoded-parsing)) using a single bounded scan, making parsing linear in the body length.",
"id": "GHSA-5rvq-cxj2-64vf",
"modified": "2026-06-15T20:24:09Z",
"published": "2026-06-15T20:24:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Kludex/python-multipart/security/advisories/GHSA-5rvq-cxj2-64vf"
},
{
"type": "PACKAGE",
"url": "https://github.com/Kludex/python-multipart"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "python-multipart: Quadratic-time querystring parsing with semicolon separators causes CPU denial of service"
}
GHSA-6JV3-5F52-599M
Vulnerability from github – Published: 2026-06-15 20:22 – Updated: 2026-06-15 20:22Summary
QuerystringParser treated ; as a field separator in application/x-www-form-urlencoded bodies, in addition to &. The WHATWG URL standard, 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 ;:
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. ; is parsed as ordinary field data, matching urllib.parse, browsers, and other compliant parsers.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "python-multipart"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.30"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53538"
],
"database_specific": {
"cwe_ids": [
"CWE-436",
"CWE-444"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:22:25Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\n\n`QuerystringParser` treated `;` as a field separator in `application/x-www-form-urlencoded` bodies, in addition to `\u0026`. The [WHATWG URL standard](https://url.spec.whatwg.org/#urlencoded-parsing), modern browsers, and Python\u0027s `urllib.parse` (since the CVE-2021-23336 fix) treat only `\u0026` 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 `\u0026` and, failing that, for `;`:\n\n```python\nsep_pos = data.find(b\"\u0026\", 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 `\u0026` 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\u0027s `urllib.parse`.\n\nFor example, a body inspecting WAF or gateway that follows the WHATWG rule (only `\u0026` separates fields) receives:\n\n```\nrole=user\u0026x=;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 `\u0026` 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.",
"id": "GHSA-6jv3-5f52-599m",
"modified": "2026-06-15T20:22:25Z",
"published": "2026-06-15T20:22:25Z",
"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"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "python-multipart: Semicolon treated as querystring field separator enables parameter smuggling"
}
GHSA-82W8-QH3P-5JFQ
Vulnerability from github – Published: 2026-06-15 20:39 – Updated: 2026-06-15 20:39Summary
request.form() accepts max_fields and max_part_size to bound resource consumption while parsing form data. These limits are enforced for multipart/form-data, but silently ignored for application/x-www-form-urlencoded. An unauthenticated attacker can therefore send a urlencoded body with an arbitrarily large number of fields or an arbitrarily large field, even when the application configured limits it believed would apply.
Details
request.form() dispatches to a different parser depending on the Content-Type. For multipart/form-data the max_files, max_fields, and max_part_size limits are forwarded to the parser, but for application/x-www-form-urlencoded the parser is constructed without them. It has no max_fields or max_part_size parameter to receive them, and it appends every field with no count check and accumulates each field's name and value with no size check. The configured limits are therefore both unreachable and unenforced for url-encoded bodies.
Because the url-encoded parser does its work synchronously between stream reads, the two attack shapes have different effects:
- Field count drives CPU and event-loop blocking. A body of ~1,000,000 fields (a sub-10MB payload such as
f0=v&f1=v&...) blocks the worker's event loop for several seconds while parsing, during which the worker serves no other request. - Field size drives memory. A single large field value (e.g. a 50MB value) is buffered in full to build the
FormData, forcing memory allocation proportional to the request body.
The equivalent multipart/form-data request is correctly rejected with 400 Too many fields / 400 Field exceeded maximum size.
Impact
This Denial of service (DoS) vulnerability affects all applications built with Starlette (or FastAPI) that call request.form() on application/x-www-form-urlencoded requests. A single request with a very large number of fields blocks the event loop for several seconds, and a single request with a very large field forces unbounded memory allocation; in either case, parallel requests can render the service unusable. A reverse proxy that enforces a request body size limit reduces but does not eliminate the exposure, since a sub-10MB body is already enough to block the event loop.
Mitigation
Upgrade to a patched version, which forwards max_fields and max_part_size to the url-encoded parser and enforces them while parsing, raising before the oversized field or excess fields are accumulated. The defaults match multipart/form-data (max_fields=1000, max_part_size=1MB) and can be customized via request.form(max_fields=..., max_part_size=...).
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "starlette"
},
"ranges": [
{
"events": [
{
"introduced": "0.4.1"
},
{
"fixed": "1.3.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54283"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:39:53Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n`request.form()` accepts `max_fields` and `max_part_size` to bound resource consumption while parsing form data. These limits are enforced for `multipart/form-data`, but silently ignored for `application/x-www-form-urlencoded`. An unauthenticated attacker can therefore send a urlencoded body with an arbitrarily large number of fields or an arbitrarily large field, even when the application configured limits it believed would apply.\n\n### Details\n`request.form()` dispatches to a different parser depending on the `Content-Type`. For `multipart/form-data` the `max_files`, `max_fields`, and `max_part_size` limits are forwarded to the parser, but for `application/x-www-form-urlencoded` the parser is constructed without them. It has no `max_fields` or `max_part_size` parameter to receive them, and it appends every field with no count check and accumulates each field\u0027s name and value with no size check. The configured limits are therefore both unreachable and unenforced for url-encoded bodies.\n\nBecause the url-encoded parser does its work synchronously between stream reads, the two attack shapes have different effects:\n\n- **Field count** drives CPU and event-loop blocking. A body of ~1,000,000 fields (a sub-10MB payload such as `f0=v\u0026f1=v\u0026...`) blocks the worker\u0027s event loop for several seconds while parsing, during which the worker serves no other request.\n- **Field size** drives memory. A single large field value (e.g. a 50MB value) is buffered in full to build the `FormData`, forcing memory allocation proportional to the request body.\n\nThe equivalent `multipart/form-data` request is correctly rejected with `400 Too many fields` / `400 Field exceeded maximum size`.\n\n### Impact\nThis Denial of service (DoS) vulnerability affects all applications built with Starlette (or FastAPI) that call `request.form()` on `application/x-www-form-urlencoded` requests. A single request with a very large number of fields blocks the event loop for several seconds, and a single request with a very large field forces unbounded memory allocation; in either case, parallel requests can render the service unusable. A reverse proxy that enforces a request body size limit reduces but does not eliminate the exposure, since a sub-10MB body is already enough to block the event loop.\n\n### Mitigation\nUpgrade to a patched version, which forwards `max_fields` and `max_part_size` to the url-encoded parser and enforces them while parsing, raising before the oversized field or excess fields are accumulated. The defaults match `multipart/form-data` (`max_fields=1000`, `max_part_size=1MB`) and can be customized via `request.form(max_fields=..., max_part_size=...)`.",
"id": "GHSA-82w8-qh3p-5jfq",
"modified": "2026-06-15T20:39:53Z",
"published": "2026-06-15T20:39:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Kludex/starlette/security/advisories/GHSA-82w8-qh3p-5jfq"
},
{
"type": "PACKAGE",
"url": "https://github.com/Kludex/starlette"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Starlette: request.form() limits silently ignored for application/x-www-form-urlencoded enable DoS"
}
GHSA-9X8Q-7H8H-WCW9
Vulnerability from github – Published: 2026-06-15 20:10 – Updated: 2026-06-15 20:10Summary
Payload resources are not closed correctly when a client disconnects in the middle of a write.
Impact
If a payload is using an open file or similar limited resource, then an attacker may be able to cause resource starvation temporarily until garbage collection or similar closes the file.
Patch: https://github.com/aio-libs/aiohttp/commit/a762eda5242f6490d6ba667533193f8b473ad587
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.14.0"
},
"package": {
"ecosystem": "PyPI",
"name": "aiohttp"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.14.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54280"
],
"database_specific": {
"cwe_ids": [
"CWE-404"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:10:44Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\n\nPayload resources are not closed correctly when a client disconnects in the middle of a write.\n\n### Impact\n\nIf a payload is using an open file or similar limited resource, then an attacker may be able to cause resource starvation temporarily until garbage collection or similar closes the file.\n\n-----\n\nPatch: https://github.com/aio-libs/aiohttp/commit/a762eda5242f6490d6ba667533193f8b473ad587",
"id": "GHSA-9x8q-7h8h-wcw9",
"modified": "2026-06-15T20:10:44Z",
"published": "2026-06-15T20:10:44Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/aio-libs/aiohttp/security/advisories/GHSA-9x8q-7h8h-wcw9"
},
{
"type": "WEB",
"url": "https://github.com/aio-libs/aiohttp/commit/a762eda5242f6490d6ba667533193f8b473ad587"
},
{
"type": "PACKAGE",
"url": "https://github.com/aio-libs/aiohttp"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "aiohttp: Payload Response Resources Are Not Closed After Mid-Body Disconnect"
}
GHSA-CX3H-4QPV-8HC9
Vulnerability from github – Published: 2026-06-12 18:30 – Updated: 2026-06-12 18:30Summary
Tornado's optional native extension tornado.speedups implements websocket_mask without validating that the mask argument is exactly four bytes long. The C function reads four bytes from mask unconditionally, even when Python passes a shorter byte string. This can read beyond the provided buffer, exposing up to 3 bytes of uninitialized memory.
The behavior is reachable from Tornado's XSRF token decoder when xsrf_cookies=True and the native extension is active.
Mitigations
This bug is fixed in Tornado 6.5.6. Prior to upgrading to this version, setting the environment variable TORNADO_EXTENSION=0 will disable the vulnerable code (at the expense of reducing websocket performance).
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "tornado"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.5.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-49854"
],
"database_specific": {
"cwe_ids": [
"CWE-126"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-12T18:30:19Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\n\nTornado\u0027s optional native extension `tornado.speedups` implements `websocket_mask` without validating that the `mask` argument is exactly four bytes long. The C function reads four bytes from `mask` unconditionally, even when Python passes a shorter byte string. This can read beyond the provided buffer, exposing up to 3 bytes of uninitialized memory.\n\nThe behavior is reachable from Tornado\u0027s XSRF token decoder when `xsrf_cookies=True` and the native extension is active. \n\n### Mitigations\n\nThis bug is fixed in Tornado 6.5.6. Prior to upgrading to this version, setting the environment variable TORNADO_EXTENSION=0 will disable the vulnerable code (at the expense of reducing websocket performance).",
"id": "GHSA-cx3h-4qpv-8hc9",
"modified": "2026-06-12T18:30:19Z",
"published": "2026-06-12T18:30:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tornadoweb/tornado/security/advisories/GHSA-cx3h-4qpv-8hc9"
},
{
"type": "PACKAGE",
"url": "https://github.com/tornadoweb/tornado"
},
{
"type": "WEB",
"url": "https://github.com/tornadoweb/tornado/releases/tag/v6.5.6"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Tornado has out-of-bounds memory access via C extension"
}
GHSA-JP82-JPQV-5VV3
Vulnerability from github – Published: 2026-06-15 20:38 – Updated: 2026-07-15 22:07Summary
In affected versions, the HTTP request path is not validated before being used to reconstruct request.url. Because request.url is rebuilt by concatenating {scheme}://{host}{path} and re-parsing the result, a path that does not begin with / (for example @google.com) moves the authority boundary during re-parsing, so request.url.hostname and request.url.netloc become attacker-controlled. Code that reads request.url.hostname (rather than the Host header or scope) can therefore be misled into trusting an attacker-supplied host.
Details
When a client requests a path that does not start with /:
GET @google.com HTTP/1.1
Host: localhost
affected versions reconstruct the URL as http://localhost@google.com. Per RFC 3986 §3.2.1, the substring before @ in the authority is userinfo, so re-parsing yields username = "localhost" and hostname = "google.com", with an empty path:
request.url == "http://localhost@google.com"
request.url.hostname == "google.com"
request.url.path == ""
The root cause is that the path is concatenated directly after the host without a separating /, and without validating that it begins with one. Only the Host header was validated when constructing request.url; the path was not.
This requires an ASGI server that forwards a request-target lacking a leading / into scope["path"].
Impact
Any application running an affected version that uses request.url, request.url.netloc, or request.url.hostname for a security-sensitive decision (host-based authorization, redirect/callback base, SSRF target, cache key, audit log) may be affected, when no fronting proxy or load balancer rejects the malformed request-target first.
Note that this is less exploitable than GHSA-86qp-5c8j-p5mr: there, the poison is carried in the Host header, so the real path still routes to a valid endpoint while request.url.path lies. Here, the poison must be carried in the path itself, and that path (@google.com) does not match any registered route, so routing returns 404 and no endpoint handler runs. The exposure is limited to code that reads request.url before routing - notably middleware - or in 404/exception handlers.
Mitigation
Upgrade to a patched version, which prevents the request path from crossing into the URL authority. The request above instead yields http://localhost/@google.com with request.url.hostname == "localhost".
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "Starlette"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.3.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54282"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-706"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T20:38:08Z",
"nvd_published_at": "2026-06-22T18:16:46Z",
"severity": "LOW"
},
"details": "### Summary\n\nIn affected versions, the HTTP request path is not validated before being used to reconstruct `request.url`. Because `request.url` is rebuilt by concatenating `{scheme}://{host}{path}` and re-parsing the result, a path that does not begin with `/` (for example `@google.com`) moves the authority boundary during re-parsing, so `request.url.hostname` and `request.url.netloc` become attacker-controlled. Code that reads `request.url.hostname` (rather than the `Host` header or `scope`) can therefore be misled into trusting an attacker-supplied host.\n\n### Details\n\nWhen a client requests a path that does not start with `/`:\n\n```http\nGET @google.com HTTP/1.1\nHost: localhost\n```\n\naffected versions reconstruct the URL as `http://localhost@google.com`. Per [RFC 3986 \u00a73.2.1](https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.1), the substring before `@` in the authority is `userinfo`, so re-parsing yields `username = \"localhost\"` and `hostname = \"google.com\"`, with an empty path:\n\n```text\nrequest.url == \"http://localhost@google.com\"\nrequest.url.hostname == \"google.com\"\nrequest.url.path == \"\"\n```\n\nThe root cause is that the path is concatenated directly after the host without a separating `/`, and without validating that it begins with one. Only the `Host` header was validated when constructing `request.url`; the path was not.\n\nThis requires an ASGI server that forwards a request-target lacking a leading `/` into `scope[\"path\"]`.\n\n### Impact\n\nAny application running an affected version that uses `request.url`, `request.url.netloc`, or `request.url.hostname` for a security-sensitive decision (host-based authorization, redirect/callback base, SSRF target, cache key, audit log) may be affected, when no fronting proxy or load balancer rejects the malformed request-target first.\n\nNote that this is less exploitable than [GHSA-86qp-5c8j-p5mr](https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr): there, the poison is carried in the `Host` header, so the real path still routes to a valid endpoint while `request.url.path` lies. Here, the poison must be carried in the path itself, and that path (`@google.com`) does not match any registered route, so routing returns `404` and no endpoint handler runs. The exposure is limited to code that reads `request.url` before routing - notably middleware - or in 404/exception handlers.\n\n### Mitigation\n\nUpgrade to a patched version, which prevents the request path from crossing into the URL authority. The request above instead yields `http://localhost/@google.com` with `request.url.hostname == \"localhost\"`.",
"id": "GHSA-jp82-jpqv-5vv3",
"modified": "2026-07-15T22:07:17Z",
"published": "2026-06-15T20:38:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Kludex/starlette/security/advisories/GHSA-jp82-jpqv-5vv3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54282"
},
{
"type": "PACKAGE",
"url": "https://github.com/Kludex/starlette"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/starlette/PYSEC-2026-248.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Starlette: Unvalidated request path concatenated into authority poisons request.url.hostname"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.