Does Starlette GHSA-86qp-5c8j-p5mr affect FastAPI installations using Starlette <= 1.0.0? #15593
-
First Check
Commit to Help
Example Codefrom fastapi import FastAPI, Request
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/foo")
async def foo(request: Request):
return {"path": request.url.path}
client = TestClient(app)
response = client.get(
"/foo",
headers={"host": "example.com/abc?bar="},
)
print(response.json())
assert response.json()["path"] == "/foo"DescriptionThis is not a new private vulnerability report. The upstream Starlette advisory is already public and fixed in Starlette 1.0.1: I would like to confirm the expected impact and guidance for FastAPI users. FastAPI depends on Starlette, and Specifically, with a malformed Host header such as This is fixed by upgrading Starlette to 1.0.1 or higher, where malformed Host headers are ignored when constructing Operating SystemmacOS Operating System DetailsNo response FastAPI Version0.136.1 Pydantic Version2.13.4 Python Version3.14.3 Additional ContextI tested the behavior with both Starlette 1.0.0 and 1.0.1:
Again, this is about confirming FastAPI impact for an already public upstream Starlette advisory, not reporting a new undisclosed vulnerability. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
|
Hi @ftnext — your analysis is correct. |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
|
Would it be worth updating the fastapi dependency Starlette>=1.0.1? |
Beta Was this translation helpful? Give feedback.
Hi @ftnext — your analysis is correct.
Since FastAPI delegates all Request / request.url handling to Starlette, any FastAPI application running on Starlette ≤ 1.0.0 is exposed to the same issue described in GHSA-86qp-5c8j-p5mr (CVE-2026-48710).
Root cause (from the advisory): Affected versions reconstruct request.url by concatenating http://{host}{path} and re-parsing the result. When the Host header contains characters invalid per RFC 9112 §3.2 — such as /, ?, or # — the re-parsing shifts the path/query boundaries. This means request.url.path can return a different value than the path the router actually dispatched to. Your example reproduces this exactly: the request is routed to /foo, …