SECURITY ADVISORY / 01

CVE-2026-48710 Exploit & Vulnerability Analysis

Complete CVE-2026-48710 security advisory with proof of concept (PoC), exploit details, and patch analysis for starlette.

starlette products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

The attacker only needs the ability to send HTTP requests to the Starlette application.

curl -i -s -X GET 'http://127.0.0.1:8000/admin' \
  -H 'Host: example.com/foo'

The app accepts the malformed Host header and still routes the raw request path /admin, returning the protected endpoint content. This proves that request.url was rebuilt from an attacker-controlled Host header and could disagree with the actual scope["path"] used for routing.

What the Patch Did

Before:

from collections.abc import ItemsView, Iterable, Iterator, KeysView, Mapping, MutableMapping, Sequence, ValuesView
from shlex import shlex
from typing import Any, BinaryIO, NamedTuple, TypeVar, cast
from urllib.parse import SplitResult, parse_qsl, urlencode, urlsplit

## Rejects Host header chars (/, ?, #, @, ...) that would let urlsplit produce a path differing from scope["path"].
class URL:
    ...
            if host_header is not None:
                url = f"{scheme}://{host_header}{path}"

After:

import re
from collections.abc import ItemsView, Iterable, Iterator, KeysView, Mapping, MutableMapping, Sequence, ValuesView
from shlex import shlex
from typing import Any, BinaryIO, NamedTuple, TypeVar, cast
from urllib.parse import SplitResult, parse_qsl, urlencode, urlsplit

## Rejects Host header chars (/, ?, #, @, ...) that would let urlsplit produce a path differing from scope["path"].
_HOST_RE = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\])(?::[0-9]+)?$", re.IGNORECASE)

class URL:
    ...
            if host_header is not None and _HOST_RE.fullmatch(host_header):
                url = f"{scheme}://{host_header}{path}"

The patch adds explicit validation of the Host header with _HOST_RE.fullmatch(host_header) before rebuilding request.url. Invalid Host values are ignored, forcing the URL builder to fall back to the trusted scope["server"] tuple.

Root Cause

This is an input-validation / request-parsing bug (CWE-20 / CWE-444) where attacker-controlled Host header data crosses a trust boundary unchecked. Starlette reconstructed request.url from raw scope["headers"] host_header values and scope["path"], while routing continued to use the original raw HTTP path. A malformed Host header like example.com/foo could change the URL parser’s interpretation of the path without changing the actual route selected, allowing security checks based on request.url to be bypassed.

Why It Works

The load-bearing fix is the and _HOST_RE.fullmatch(host_header) condition. If that line is removed, host_header is still accepted and url = f"{scheme}://{host_header}{path} will reconstruct a URL containing invalid path characters from the header. The regex constant _HOST_RE is the defence; the import and comment simply make the validation explicit and document why malformed hosts are rejected. Without the regex check, the library would still trust attacker-supplied Host values and the mismatch between request.url.path and scope["path"] remains exploitable.

Hardening Checklist

  • Validate Host header values against RFC 9112 / RFC 3986 host syntax before using them to rebuild URLs.
  • Use scope["server"] or another trusted canonical host when header validation fails, instead of using malformed header data.
  • Keep routing decisions and authorization checks based on the same canonical request representation, not mixed derived values.
  • Treat all HTTP request headers as attacker-controlled input; do not rely on Host for access control or security policy decisions.
  • Add regression tests for invalid Host headers such as foo/?x=, foo/#, foo/bar, user@foo, foo\bar, and foo bar.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2026-48710

Frequently asked questions about CVE-2026-48710

What is CVE-2026-48710?

CVE-2026-48710 is a security vulnerability identified in starlette. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2026-48710?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2026-48710. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2026-48710 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting starlette. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2026-48710?

CVE-2026-48710 affects starlette. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2026-48710?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for starlette.

What is the CVSS score for CVE-2026-48710?

The severity rating and CVSS scoring for CVE-2026-48710 affecting starlette is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.