Detect Starlette HTTP Request/Response Smuggling (CVE-2026-48710) Exploitation in Google Chronicle
Detects exploitation attempts against CVE-2026-48710, an HTTP Request/Response Smuggling vulnerability (CWE-444) in Kludex Starlette, the ASGI framework underpinning FastAPI and many Python web services. Ambiguous or conflicting message-framing headers (both Content-Length and Transfer-Encoding, duplicated Content-Length, obsolete line folding, or malformed Transfer-Encoding values) allow an attacker to desynchronize the interpretation of request boundaries between an upstream proxy/load balancer and the Starlette backend. This enables request smuggling for cache poisoning, security-control bypass, credential/session hijacking, and request queue poisoning. The vulnerability is listed in CISA KEV (BOD 26-04) as known-exploited. This detection surfaces smuggling-indicative header anomalies and framing discrepancies in web/proxy telemetry reaching Starlette/ASGI endpoints.
MITRE ATT&CK
- Tactic
- Initial Access Lateral Movement
YARA-L Detection Query
rule starlette_cve_2026_48710_smuggling {
meta:
author = "argus"
description = "Detects CVE-2026-48710 Starlette HTTP request smuggling via ambiguous framing headers"
severity = "HIGH"
cve = "CVE-2026-48710"
events:
$e.metadata.event_type = "NETWORK_HTTP"
(
(re.regex($e.network.http.response_headers, "(?i)transfer-encoding") and re.regex($e.network.http.response_headers, "(?i)content-length")) or
re.regex($e.network.http.user_agent, "(?i)smuggler|h2csmuggler") or
re.regex($e.principal.resource.name, "(?i)chunked\\s*,\\s*chunked")
)
$src = $e.principal.ip
match:
$src over 5m
condition:
$e
} Chronicle YARA-L rule identifying HTTP events toward Starlette/ASGI endpoints with conflicting Transfer-Encoding and Content-Length framing or known desync tooling signatures, mapped to CVE-2026-48710.
Data Sources
Required Tables
False Positives & Tuning
- UDM parsers that populate both header fields from a single reassembled stream
- Authorized security scanning with desync tools
- Legacy clients emitting dual framing headers
Other platforms for CVE-2026-48710
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1 TE+CL conflicting framing request to Starlette
Expected signal: Proxy/WAF or packet-capture log entry showing a single request with both Content-Length and Transfer-Encoding headers.
- Test 2 Duplicate Content-Length header
Expected signal: Log event containing two Content-Length header occurrences for one request.
- Test 3 Malformed chunked Transfer-Encoding token
Expected signal: Log entry showing a Transfer-Encoding header with a doubled/obfuscated chunked token.
- Test 4 HTTP desync scanner probe (Windows)
Expected signal: Network/HTTP telemetry from the Windows host showing an outbound request with conflicting framing headers.
References (4)
- https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr
- https://www.cisa.gov/news-events/directives/bod-26-04-prioritizing-security-updates-based-risk
- https://www.cisa.gov/news-events/directives/bod-26-04-implementation-guidance-prioritizing-security-updates-based-risk
- https://nvd.nist.gov/vuln/detail/CVE-2026-48710
Response Playbook
Triage
- Confirm the destination host runs Starlette (or a FastAPI/ASGI app built on it) and identify the deployed version; compare against the fixed release referenced in GHSA-86qp-5c8j-p5mr.
- Extract the raw request headers from the alert and determine the specific framing anomaly: both Transfer-Encoding and Content-Length present, duplicated Content-Length, obsolete line folding, or malformed chunked token.
- Correlate the source IP across the fronting proxy/load balancer and the Starlette backend logs to determine whether the two tiers disagreed on request boundaries (a hallmark of successful desync).
- Check whether the smuggled request reached an authenticated or administrative endpoint, or whether cache entries were served to other clients after the event.
Containment
- Deploy or tighten a WAF/proxy rule that rejects any request carrying both Transfer-Encoding and Content-Length, duplicated Content-Length, or non-RFC-compliant chunked encoding, returning HTTP 400.
- Upgrade Starlette to the patched version across all affected services; where immediate patching is impossible, place a normalizing reverse proxy that enforces strict HTTP/1.1 framing in front of the backend.
- Invalidate and purge shared HTTP caches (CDN, Varnish, reverse-proxy cache) that may hold poisoned entries, and rotate session tokens for any users potentially served smuggled responses.
Evidence Collection
- Preserve full raw request/response captures (headers and bodies) from both the proxy and Starlette tiers for the affected time window.
- Export proxy, WAF, and application access logs for the source IP and destination service, plus Starlette/ASGI application logs showing request parsing.
- Snapshot the running Starlette service version, dependency lockfile (requirements.txt/poetry.lock), and container image digest to establish exposure.
Escalation Criteria
- !Escalate to incident response if evidence shows a smuggled request reached an authenticated, admin, or state-changing endpoint, or if cache poisoning served attacker content to other users.
- !Escalate if the same source or technique targets multiple internet-facing Starlette services, indicating active exploitation of the KEV-listed CVE at scale.
- !Escalate to legal/compliance if session hijacking or credential capture against real user sessions is confirmed.
Investigation Guide
Forensic Artifacts
- >
Proxy and WAF access logs showing conflicting framing headers for a source IP - >
Starlette/uvicorn/gunicorn application logs reflecting misparsed or split requests - >
Shared HTTP cache entries (CDN/Varnish) with anomalous keys or bodies - >
Packet captures demonstrating request/response boundary disagreement between tiers
Tuning Guidance
Baseline which internal clients and middleboxes legitimately emit dual framing headers and exclude them by source IP/user-agent to cut noise. Focus the highest-severity alerting on external source IPs hitting authenticated or cacheable endpoints. Where the proxy already strips or normalizes framing before the backend, move detection to the outermost tier (CDN/edge) so anomalies are observed before normalization. Suppress internal red-team and load-test ranges via allowlist rather than disabling the rule.
Hunting Queries
Retrospective hunt for co-occurring Transfer-Encoding and Content-Length headers toward Starlette services over the past 30 days, revealing prior desync probing.
CommonSecurityLog | where TimeGenerated > ago(30d) | extend H = tolower(AdditionalExtensions) | where H has "transfer-encoding" and H has "content-length" | summarize count() by SourceIP, DestinationIP, bin(TimeGenerated, 1h) index=proxy OR index=web earliest=-30d | eval h=lower(_raw) | where match(h,"transfer-encoding") AND match(h,"content-length") | stats count by src_ip dest_ip Atomic Red Team Tests
Sends a raw HTTP/1.1 request carrying both Transfer-Encoding: chunked and Content-Length headers to a lab Starlette instance to trigger framing-anomaly telemetry.
Command
printf 'POST / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nG' | nc -w2 127.0.0.1 8000 Cleanup
echo 'No persistent artifacts; restart the lab Starlette service if request queue appears poisoned: pkill -f uvicorn' Expected Telemetry
Proxy/WAF or packet-capture log entry showing a single request with both Content-Length and Transfer-Encoding headers.
Expected Detection
The kql/spl framing-conflict rule fires with Reason 'TE+CL both present'.
Issues a request with two Content-Length headers to a lab endpoint fronting Starlette to simulate duplicate-length desync.
Command
printf 'GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nContent-Length: 0\r\nContent-Length: 44\r\n\r\n' | nc -w2 127.0.0.1 8000 Cleanup
echo 'No cleanup required; no files written.' Expected Telemetry
Log event containing two Content-Length header occurrences for one request.
Expected Detection
Detection fires with Reason 'Duplicate Content-Length'.
Sends an obfuscated Transfer-Encoding value ('chunked, chunked') designed to be parsed differently by proxy and Starlette backend.
Command
printf 'POST / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nTransfer-Encoding: chunked, chunked\r\n\r\n0\r\n\r\n' | nc -w2 127.0.0.1 8000 Cleanup
echo 'No persistent artifacts to remove.' Expected Telemetry
Log entry showing a Transfer-Encoding header with a doubled/obfuscated chunked token.
Expected Detection
Detection fires with Reason 'Malformed Transfer-Encoding'.
Runs an HTTP desync probe from a Windows host using a raw socket PowerShell client against a lab Starlette endpoint.
Command
$c=New-Object Net.Sockets.TcpClient('127.0.0.1',8000);$s=$c.GetStream();$b=[Text.Encoding]::ASCII.GetBytes("POST / HTTP/1.1`r`nHost: 127.0.0.1`r`nContent-Length: 6`r`nTransfer-Encoding: chunked`r`n`r`n0`r`n`r`nG");$s.Write($b,0,$b.Length);Start-Sleep 2;$c.Close() Cleanup
Remove-Variable c,s,b -ErrorAction SilentlyContinue Expected Telemetry
Network/HTTP telemetry from the Windows host showing an outbound request with conflicting framing headers.
Expected Detection
The crowdstrike_cql / chronicle_yaral rules flag the conflicting-framing request from the source host.