{"id":"CVE-2026-54282","aliases":["CLSA-2026-1784077472","CLSA-2026-1789447406","CLSA-2026-1789537996","DEBIAN-CVE-2026-54282","EUVD-2026-38318","GHSA-jp82-jpqv-5vv3","MGASA-2026-0413","PYSEC-2026-248","ROOT-APP-PYPI-CVE-2026-54282","SUSE-SU-2026:22360-1","UBUNTU-CVE-2026-54282","openSUSE-SU-2026:11058-1","openSUSE-SU-2026:21053-1"],"status":"published","title":"Starlette: Unvalidated request path concatenated into authority poisons request.url.hostname","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","severity":{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00273,"percentile":0.19859,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-20","CWE-706"],"published":"2026-06-15T20:38:08Z","modified":"2026-10-28T02:30:32Z","fixes":[{"ecosystem":"PyPI","package":"starlette","fixed_in":["1.3.0"],"sources":["ghsa","osv"]},{"ecosystem":"TuxCare:PyPI","package":"starlette","fixed_in":["0.27.0.post6+tuxcare"],"sources":["osv"]},{"ecosystem":"Debian:12","package":"starlette","fixed_in":["0.26.1-1+deb12u2"],"sources":["osv"]},{"ecosystem":"Debian:13","package":"starlette","fixed_in":["0.46.1-3+deb13u3"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"starlette","fixed_in":["1.3.1-1"],"sources":["osv"]},{"ecosystem":"Root:PyPI","package":"rootio-starlette","fixed_in":["0.50.0+root.io.2","0.45.3+root.io.14","0.49.3+root.io.4","0.49.2+root.io.4","0.46.2+root.io.7","0.52.1+root.io.3","1.0.0+root.io.2","1.0.1+root.io.2","1.2.0+root.io.2","1.2.1+root.io.2","0.49.1+root.io.3","1.1.0+root.io.2","1.0.0+root.io.3","0.45.3+root.io.15"],"sources":["osv"]},{"ecosystem":"Root:PyPI","package":"starlette","fixed_in":["0.50.0+aikido.2","0.45.3+aikido.14","0.49.3+aikido.4","0.49.2+aikido.4","0.46.2+aikido.7","0.52.1+aikido.3","1.0.0+aikido.2","1.0.1+aikido.2","1.2.0+aikido.2","1.2.1+aikido.2","0.49.1+aikido.3","1.1.0+aikido.2","1.0.0+aikido.3","0.45.3+aikido.15","0.50.0+aikido.3"],"sources":["osv"]},{"ecosystem":"openSUSE:Tumbleweed","package":"python-starlette","fixed_in":["1.3.1-1.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.0"}]}]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.27.0"},{"fixed":"0.27.0.post6+tuxcare"}]}],"versions":["0.27.0","0.27.0.post1+tuxcare","0.27.0.post2+tuxcare","0.27.0.post3+tuxcare","0.27.0.post4+tuxcare","0.27.0.post5+tuxcare"]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.25.0"},{"fixed":"0.25.0.post1+tuxcare"}]}],"versions":["0.25.0"],"bundled":8},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.13.6"},{"fixed":"0.13.6.post5+tuxcare"}]}],"versions":["0.13.6","0.13.6.post1+tuxcare","0.13.6.post2+tuxcare","0.13.6.post3+tuxcare","0.13.6.post4+tuxcare"],"bundled":4},{"source":"osv","ecosystem":"Debian:12","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.26.1-1+deb12u2"}]}],"versions":["0.26.1-1","0.26.1-1+deb12u1"]},{"source":"osv","ecosystem":"Debian:13","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.46.1-3+deb13u3"}]}],"versions":["0.46.1-3","0.46.1-3+deb13u1","0.46.1-3+deb13u2"]},{"source":"osv","ecosystem":"Debian:14","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.1-1"}]}],"versions":["0.46.1-3","0.50.0-1","1.0.0-1","1.1.0-1"]},{"source":"osv","ecosystem":"PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.0"}]}],"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","1.0.1","1.1.0","1.2.0","1.2.1"]},{"source":"osv","ecosystem":"Mageia:10","package":"python-starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.46.0-3.2.mga10"}]}],"bundled":3},{"source":"osv","ecosystem":"PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.0"}]}],"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","1.0.1","1.1.0","1.2.0","1.2.1"]},{"source":"osv","ecosystem":"Root:PyPI","package":"rootio-starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.50.0+root.io.2"},{"fixed":"0.45.3+root.io.14"},{"fixed":"0.49.3+root.io.4"},{"fixed":"0.49.2+root.io.4"},{"fixed":"0.46.2+root.io.7"},{"fixed":"0.52.1+root.io.3"},{"fixed":"1.0.0+root.io.2"},{"fixed":"1.0.1+root.io.2"},{"fixed":"1.2.0+root.io.2"},{"fixed":"1.2.1+root.io.2"},{"fixed":"0.49.1+root.io.3"},{"fixed":"1.1.0+root.io.2"},{"fixed":"1.0.0+root.io.3"},{"fixed":"0.45.3+root.io.15"}]}]},{"source":"osv","ecosystem":"Root:PyPI","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.50.0+aikido.2"},{"fixed":"0.45.3+aikido.14"},{"fixed":"0.49.3+aikido.4"},{"fixed":"0.49.2+aikido.4"},{"fixed":"0.46.2+aikido.7"},{"fixed":"0.52.1+aikido.3"},{"fixed":"1.0.0+aikido.2"},{"fixed":"1.0.1+aikido.2"},{"fixed":"1.2.0+aikido.2"},{"fixed":"1.2.1+aikido.2"},{"fixed":"0.49.1+aikido.3"},{"fixed":"1.1.0+aikido.2"},{"fixed":"1.0.0+aikido.3"},{"fixed":"0.45.3+aikido.15"},{"fixed":"0.50.0+aikido.3"}]}]},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 16.0","package":"python-starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.41.3-160000.4.1"}]}],"bundled":3},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP applications 16.0","package":"python-starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.41.3-160000.4.1"}]}],"bundled":3},{"source":"osv","ecosystem":"Ubuntu:22.04:LTS","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.14.1-1","0.16.0-1","0.18.0-1"]},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.30.0-1","0.31.1-1"]},{"source":"osv","ecosystem":"Ubuntu:25.10","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.46.1-2","0.46.1-3"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.50.0-1","1.1.0-1","1.3.1-1","1.7.0-2"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.46.1-3","0.50.0-1"]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"python-starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.1-1.1"}]}]},{"source":"osv","ecosystem":"openSUSE:Leap 16.0","package":"python-starlette","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.41.3-160000.4.1"}]}],"bundled":3}],"products":[{"vendor":"encode","product":"starlette"},{"vendor":"kludex","product":"starlette"}],"references":[{"url":"https://github.com/Kludex/starlette/security/advisories/GHSA-jp82-jpqv-5vv3","tags":["x_refsource_CONFIRM","Mitigation","Vendor Advisory","advisory","web","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-54282","tags":["advisory"]},{"url":"https://github.com/pypa/advisory-database/tree/main/vulns/starlette/PYSEC-2026-248.yaml","tags":["web"]},{"url":"https://github.com/advisories/GHSA-jp82-jpqv-5vv3"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54282.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-54282","tags":["advisory"]},{"url":"https://github.com/Kludex/starlette","tags":["package"]},{"url":"https://advisories.mageia.org/MGASA-2026-0413.html","tags":["advisory"]},{"url":"https://bugs.mageia.org/show_bug.cgi?id=36224","tags":["report"]},{"url":"https://lists.debian.org/debian-security-announce/2026/msg00389.html","tags":["web"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202622360-1/","tags":["advisory"]},{"url":"https://bugzilla.suse.com/1268389","tags":["report"]},{"url":"https://bugzilla.suse.com/1268517","tags":["report"]},{"url":"https://bugzilla.suse.com/1268520","tags":["report"]},{"url":"https://www.suse.com/security/cve/CVE-2026-48817","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-54282","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-54283","tags":["web"]},{"url":"https://ubuntu.com/security/CVE-2026-54282","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-54282","tags":["report"]},{"url":"https://github.com/Kludex/starlette/pull/3326","tags":["report"]},{"url":"","tags":["advisory"]}],"sources":{"cve":[{"id":"CVE-2026-54282","title":"Starlette: Unvalidated request path concatenated into authority poisons request.url.hostname","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T16:45:01.629Z","modified":"2026-06-22T17:26:58.637Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low","assessor":"cna"}],"cwes":["CWE-706"],"updated_at":"2026-11-02T13:38:09.774038Z"}],"euvd":[{"id":"EUVD-2026-38318","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T16:45:01Z","modified":"2026-06-22T17:26:58Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"updated_at":"2026-11-02T18:20:34.238696Z"}],"ghsa":[{"id":"GHSA-jp82-jpqv-5vv3","title":"Starlette: Unvalidated request path concatenated into authority poisons request.url.hostname","description":"### 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 §3.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\"`.","status":"published","published":"2026-06-15T20:38:08Z","modified":"2026-07-15T22:07:17Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"cwes":["CWE-20","CWE-706"],"updated_at":"2026-11-02T14:40:44.915484Z"}],"nvd":[{"id":"CVE-2026-54282","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T18:16:46.807Z","modified":"2026-10-25T23:10:00.167Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low","assessor":"secondary"},{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-706"],"updated_at":"2026-11-02T14:12:24.912854Z"}],"osv":[{"id":"CVE-2026-54282","title":"Starlette: Unvalidated request path concatenated into authority poisons request.url.hostname","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T16:45:01.629Z","modified":"2026-10-28T02:30:32.059448466Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"cwes":["CWE-706"],"updated_at":"2026-11-02T15:45:10.818486Z"},{"id":"DEBIAN-CVE-2026-54282","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T18:16:46.807Z","modified":"2026-10-26T11:47:28.716516948Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T15:45:57.236551Z"},{"id":"GHSA-jp82-jpqv-5vv3","title":"Starlette: Unvalidated request path concatenated into authority poisons request.url.hostname","description":"### 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 §3.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\"`.","status":"published","published":"2026-06-15T20:38:08Z","modified":"2026-09-10T03:50:50.05080009Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"cwes":["CWE-20","CWE-706"],"updated_at":"2026-11-02T15:46:50.687609Z"},{"id":"PYSEC-2026-248","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T18:16:46.807Z","modified":"2026-06-27T11:15:06.799060438Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T15:52:55.961245Z"},{"id":"UBUNTU-CVE-2026-54282","description":"Starlette is a lightweight ASGI framework/toolkit. Prior to 1.3.0, 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. This vulnerability is fixed in 1.3.0.","status":"published","published":"2026-06-22T18:16:00Z","modified":"2026-10-17T12:58:36.423270787Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"},{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T16:56:41.382716Z"},{"id":"CLSA-2026-1784077472","title":"TuxCare security update for starlette (1 CVE)","description":"TuxCare rebuilt starlette to address 1 CVE. Fixed in 0.27.0.post6+tuxcare.","status":"published","published":"2026-08-04T14:52:43Z","modified":"2026-10-15T09:48:05.488661847Z","updated_at":"2026-11-02T15:43:46.151924Z"},{"id":"CLSA-2026-1789447406","title":"TuxCare security update for starlette (8 CVEs)","description":"TuxCare rebuilt starlette to address 8 CVEs. Fixed in 0.25.0.post1+tuxcare.","status":"published","published":"2026-09-15T04:43:26Z","modified":"2026-10-15T09:48:01.789333066Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1789537996","title":"TuxCare security update for starlette (4 CVEs)","description":"TuxCare rebuilt starlette to address 4 CVEs. Fixed in 0.13.6.post5+tuxcare.","status":"published","published":"2026-09-16T05:53:16Z","modified":"2026-10-15T09:48:01.802525719Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"MGASA-2026-0413","title":"Updated python-starlette package fixes security vulnerabilities","description":"Arbitrary HTTP method dispatched to `HTTPEndpoint` attributes via\n`getattr`. (CVE-2026-48817)\nUnvalidated request path concatenated into authority poisons\nrequest.url.hostname. (CVE-2026-54282)\n","status":"published","published":"2026-09-17T14:10:41Z","modified":"2026-09-17T14:15:02.602502957Z","updated_at":"2026-11-02T15:49:43.795591Z"},{"id":"openSUSE-SU-2026:11058-1","title":"python311-starlette-1.3.1-1.1 on GA media","description":"These are all security issues fixed in the python311-starlette-1.3.1-1.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-06-18T00:00:00Z","modified":"2026-06-19T08:15:08.49178551Z","updated_at":"2026-11-02T16:58:38.95195Z"},{"id":"openSUSE-SU-2026:21053-1","title":"Security update for python-starlette","description":"This update for python-starlette fixes the following issues\n\n- CVE-2026-48817: arbitrary HTTP method dispatched to `HTTPEndpoint` attributes via `getattr` (bsc#1268389).\n- CVE-2026-54282: request path that lacks a leading forward slash can lead to request.url.hostname manipulation\n  (bsc#1268520).\n- CVE-2026-54283: urlencoded request body with an oversized data can lead to a denial of service (bsc#1268517).\n","status":"published","published":"2026-06-24T21:39:55Z","modified":"2026-06-30T18:24:37.951801192Z","updated_at":"2026-11-02T16:58:41.885092Z"},{"id":"ROOT-APP-PYPI-CVE-2026-54282","title":"CVE-2026-54282 in rootio-starlette - Patched by Root","description":"Root has patched CVE-2026-54282 in the rootio-starlette package for Root:PyPI. Multiple fixed versions available.","status":"published","published":"2026-08-03T10:35:24Z","modified":"2026-08-03T13:45:04.69220277Z","updated_at":"2026-11-02T15:53:28.259095Z"},{"id":"SUSE-SU-2026:22360-1","title":"Security update for python-starlette","description":"This update for python-starlette fixes the following issues\n\n- CVE-2026-48817: arbitrary HTTP method dispatched to `HTTPEndpoint` attributes via `getattr` (bsc#1268389).\n- CVE-2026-54282: request path that lacks a leading forward slash can lead to request.url.hostname manipulation\n  (bsc#1268520).\n- CVE-2026-54283: urlencoded request body with an oversized data can lead to a denial of service (bsc#1268517).\n","status":"published","published":"2026-06-24T21:41:06Z","modified":"2026-07-02T18:24:12.84134627Z","updated_at":"2026-11-02T15:54:03.080707Z"}]}}
