{"id":"GHSA-86qp-5c8j-p5mr","summary":"Starlette has missing Host header validation that poisons request.url.path, bypassing path-based security checks","details":"### Summary\nIn affected versions, the HTTP `Host` request header was not validated before being used to reconstruct `request.url`. Because the routing algorithm relies on the raw HTTP path while `request.url` is rebuilt from the `Host` header, a malformed header could make `request.url.path` differ from the path that was actually requested. Middleware and endpoints that apply security restrictions based on `request.url` (rather than the raw `scope` path) could therefore be bypassed.\n\n### Details\nWhen a client requests `http://example.com/foo`, it sends:\n\n```http\nGET /foo HTTP/1.1\nHost: example.com\n```\n\nAffected versions reconstructed the URL by concatenating `http://{host}{path}` and re-parsing the result. The `Host` value is only valid as a `uri-host [ \":\" port ]` per [RFC 9112 §3.2](https://www.rfc-editor.org/rfc/rfc9112.html#section-3.2-6), where `uri-host` follows the restricted `host` grammar of [RFC 3986 §3.2.2](https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2). When it contains characters outside that grammar - notably `/`, `?`, or `#` - those characters move the path/query/fragment boundaries during re-parsing, so the parsed `request.url.path` no longer matches the path the server actually received. For example:\n\n```http\nGET /foo HTTP/1.1\nHost: example.com/abc?bar=\n```\n\nreconstructs to `http://example.com/abc?bar=/foo`, whose parsed `path` is `/abc` - even though routing used the real path `/foo`. The router still dispatches to `/foo` and the endpoint executes, but any middleware or code that reads `request.url.path` sees `/abc`, so path-based authorization checks can be bypassed.\n\n### Impact\nAny application running an affected version that relies on `request.url` (or `request.url.path`) for security-sensitive decisions is affected. The most common case is middleware that gates access to certain path prefixes based on `request.url.path`. Deployments fronted by a proxy or load balancer are mitigated only if that proxy rejects or normalizes the malformed `Host` header before forwarding and the application does not trust attacker-controlled host headers (e.g. `X-Forwarded-Host`) elsewhere.\n\n### Mitigation\nUpgrade to a patched version, which validates the `Host` header against the grammar of [RFC 9112 §3.2](https://www.rfc-editor.org/rfc/rfc9112.html#section-3.2-6) / [RFC 3986 §3.2.2](https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2) when constructing `request.url` and falls back to `scope[\"server\"]` for malformed values.","aliases":["CVE-2026-48710","PYSEC-2026-161","X41-2026-002"],"modified":"2026-08-28T18:45:05.676328710Z","published":"2026-06-04T13:15:17Z","database_specific":{"nvd_published_at":"2026-05-26T22:16:44Z","cwe_ids":["CWE-1289","CWE-444"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-06-04T13:15:17Z"},"references":[{"type":"WEB","url":"https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-48710"},{"type":"WEB","url":"https://github.com/Kludex/starlette/commit/764dab0dcfb9033d75442d7a359645c9f94648c6"},{"type":"WEB","url":"https://www.x41-dsec.de/lab/advisories/x41-2026-002-starlette"},{"type":"WEB","url":"https://www.secwest.net/starlette"},{"type":"WEB","url":"https://www.cve.org/CVERecord?id=CVE-2026-48710"},{"type":"WEB","url":"https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-48710.json"},{"type":"WEB","url":"https://ostif.org/disclosing-the-badhost-vulnerability-in-starlette"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/starlette/PYSEC-2026-161.yaml"},{"type":"PACKAGE","url":"https://github.com/Kludex/starlette"},{"type":"WEB","url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481742"},{"type":"WEB","url":"https://badhost.org"},{"type":"WEB","url":"https://access.redhat.com/security/cve/CVE-2026-48710"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:60520"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:51357"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:44696"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:43038"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:37275"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:34532"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:34526"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:34456"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:30089"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:30088"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:26226"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:24866"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:23346"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:22993"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:22992"}],"affected":[{"package":{"name":"starlette","ecosystem":"PyPI","purl":"pkg:pypi/starlette"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.0.1"}]}],"versions":["0.1.0","0.1.1","0.1.10","0.1.11","0.1.12","0.1.13","0.1.14","0.1.15","0.1.16","0.1.17","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6","0.1.7","0.1.8","0.1.9","0.10.0","0.10.1","0.10.2","0.10.3","0.10.4","0.10.5","0.10.6","0.10.7","0.11.0","0.11.1","0.11.2","0.11.3","0.11.4","0.12.0","0.12.0b1","0.12.0b2","0.12.0b3","0.12.1","0.12.10","0.12.11","0.12.12","0.12.13","0.12.2","0.12.3","0.12.4","0.12.5","0.12.6","0.12.7","0.12.8","0.12.9","0.13.0","0.13.1","0.13.2","0.13.3","0.13.4","0.13.5","0.13.6","0.13.7","0.13.8","0.14.0","0.14.1","0.14.2","0.15.0","0.16.0","0.17.0","0.17.1","0.18.0","0.19.0","0.19.1","0.2.0","0.2.1","0.2.2","0.2.3","0.20.0","0.20.1","0.20.2","0.20.3","0.20.4","0.21.0","0.22.0","0.23.0","0.23.1","0.24.0","0.25.0","0.26.0","0.26.0.post1","0.26.1","0.27.0","0.28.0","0.29.0","0.3.0","0.3.1","0.3.2","0.3.3","0.3.4","0.3.5","0.3.6","0.3.7","0.30.0","0.31.0","0.31.1","0.32.0","0.32.0.post1","0.33.0","0.34.0","0.35.0","0.35.1","0.36.0","0.36.1","0.36.2","0.36.3","0.37.0","0.37.1","0.37.2","0.38.0","0.38.1","0.38.2","0.38.3","0.38.4","0.38.5","0.38.6","0.39.0","0.39.1","0.39.2","0.4.0","0.4.1","0.4.2","0.40.0","0.41.0","0.41.1","0.41.2","0.41.3","0.42.0","0.43.0","0.44.0","0.45.0","0.45.1","0.45.2","0.45.3","0.46.0","0.46.1","0.46.2","0.47.0","0.47.1","0.47.2","0.47.3","0.48.0","0.49.0","0.49.1","0.49.2","0.49.3","0.5.0","0.5.1","0.5.2","0.5.3","0.5.4","0.5.5","0.50.0","0.51.0","0.52.0","0.52.1","0.6.0","0.6.1","0.6.2","0.6.3","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.8.6","0.8.7","0.8.8","0.9.0","0.9.1","0.9.10","0.9.11","0.9.2","0.9.3","0.9.4","0.9.5","0.9.6","0.9.7","0.9.8","0.9.9","1.0.0","1.0.0rc1"],"database_specific":{"last_known_affected_version_range":"\u003c= 1.0.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-86qp-5c8j-p5mr/GHSA-86qp-5c8j-p5mr.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"}]}