James Kettle — PortSwigger's Director of Research and the researcher who put HTTP request smuggling back on the map — has built something every defender running edge infrastructure needs to understand: HTTP Terminator, an AI-assisted research system that autonomously explored roughly 30,000 candidate HTTP desynchronization vectors, then generated and proved novel, working desync techniques on its own.
That alone would be significant. But a related human-guided discovery cascade uncovered something more immediately urgent for operations teams: an unpatched vulnerability in Apache Traffic Server (ATS) — the open-source caching proxy that sits in front of significant portions of the internet, powering CDNs, large-scale reverse proxies, and high-traffic web properties. Kettle's research reportedly exercised the techniques against 30,000 live websites.
There is no CVE assigned yet (as of publication), no vendor patch, and no KEV entry. That is precisely why this matters right now: you are defending against proven, working desynchronization primitives that your upstream vendor cannot yet fix. Your mitigations today are detection, strict request normalization, and architectural controls.
If you run Apache Traffic Server, HAProxy, nginx, Varnish, an ALB/CloudFront front tier, or any multi-hop HTTP architecture — and statistically you do — this post is your defensive playbook.
Technical Analysis
What HTTP Desynchronization Actually Buys an Attacker
HTTP request smuggling (desync) exploits disagreement between front-end and back-end servers about where one request ends and the next begins. In a modern architecture — CDN → load balancer → reverse proxy → application server — every hop parses the HTTP stream independently. When two hops disagree on message boundaries (typically around Content-Length vs. Transfer-Encoding: chunked), an attacker can "smuggle" a second request that the front-end considers part of the first request's body, but the back-end treats as a fresh request from a legitimate user.
The impact profile from a defensive standpoint:
- Cache poisoning — the smuggled request's response gets cached and served to every subsequent visitor (defacement, malware delivery, session fixation at CDN scale).
- Session hijacking / request prefixing — the victim's next request gets prefixed with attacker-controlled headers or content.
- Security control bypass — the front-end's WAF, auth gates, and rate limiters never see the smuggled request. It materializes behind every control you deployed at the edge.
- Internal surface access — smuggled requests can reach internal-only routes (
/admin, management endpoints, cloud metadata-adjacent paths) that the edge explicitly blocks.
Why the HTTP Terminator Findings Are Different
Traditional desync research produced a known taxonomy: CL.TE, TE.CL, TE.TE with header obfuscation (e.g., Transfer-Encoding : chunked with whitespace tricks, Transfer-Encoding: xchunked, line-wrapping, duplicate headers with divergent values). WAFs and hardened proxies have spent years encoding defenses against that known list.
HTTP Terminator's significance is that it explored 30,000 candidate vectors and proved novel ones — variations in header parsing, chunk framing, connection reuse handling, and intermediary behavior that do not appear in existing WAF signatures because no human had catalogued them. The defensive implication is stark: signature-based request smuggling protection is now structurally behind. Your WAF vendor's smuggling ruleset was written against human-discovered techniques. An AI system just demonstrated it can generate working vectors faster than signature pipelines can consume them.
The Apache Traffic Server Exposure
The unpatched ATS vulnerability emerged from the same research effort. ATS is deployed as:
- Forward and reverse caching proxy at CDN and ISP scale
- Edge termination layer in front of origin infrastructure
- A component embedded in commercial CDN platforms (historically, several major CDNs have been built on or derived from ATS)
Until Apache publishes a fixed version, defenders must assume the parsing differential between ATS and common back-ends (nginx, Apache httpd, application frameworks) is exploitable in the wild by anyone who reads the research. PortSwigger's responsible disclosure cadence historically means technique details reach the offensive community quickly — Burp Suite's smuggling tooling has been the delivery vehicle for prior Kettle research. Expect reproduction tooling in weeks, not months.
Exploitation Status
| Factor | Status |
|---|---|
| CVE assigned | None — no identifier published as of this writing |
| Vendor patch (Apache Traffic Server) | Not available — unpatched |
| CISA KEV | Not listed (no CVE yet) |
| Working PoC | Yes — techniques proven by the researcher; tested at scale against live sites |
| Public exploit tooling | Not yet, but PortSwigger research historically ships in Burp Suite shortly after publication |
| Active exploitation confirmed | Not publicly confirmed — treat as imminent |
Severity assessment: For organizations running ATS or heterogeneous proxy chains, treat this as high-priority, pre-CVE exposure. The attack is remote, unauthenticated, and bypasses edge controls by design.
Detection & Response
The uncomfortable truth about desync: it is invisible to the layer that gets attacked. Your front-end logs show a normal request; your back-end logs show a normal request; only the mismatch between them reveals the smuggling. That means detection lives in three places: (1) anomalous header combinations at the edge, (2) backend log entries with no corresponding edge entry, and (3) behavioral symptoms — 408 storms, connection reuse anomalies, cache incoherence.
Sigma Rules
These rules target the observable fingerprints of desync probing — ambiguous framing headers and request-smuggling-relevant connection behavior. They are tuned against the technique class, not against the exact novel vectors (which, by definition, we don't have signatures for yet — that is why behavior matters here).
---
title: HTTP Request with Ambiguous Message Framing Headers (Desync Probe)
id: 8f2b1c47-3d9e-4a61-bf52-9c4e7a1d8306
status: experimental
description: Detects inbound HTTP requests containing both Content-Length and Transfer-Encoding headers, or obfuscated Transfer-Encoding values — the canonical fingerprint of HTTP request smuggling / desynchronization attempts against proxy chains, including vectors disclosed via PortSwigger HTTP Terminator research.
references:
- https://portswigger.net/web-security/request-smuggling
- https://thehackernews.com/2026/08/ai-assisted-http-terminator-finds-novel.html
author: Security Arsenal
date: 2026/08/15
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_both_headers:
cs-method|contains:
- 'POST'
- 'PUT'
- 'PATCH'
cs-headers|contains|all:
- 'Content-Length'
- 'Transfer-Encoding'
selection_te_obfuscation:
cs-headers|contains:
- 'Transfer-Encoding :'
- 'Transfer-Encoding: chunked'
- 'Transfer-Encoding: xchunked'
- 'Transfer-Encoding: identity'
- 'Transfer-Encoding: cow'
- 'Transfer\t-Encoding'
- ' Transfer-Encoding'
condition: selection_both_headers or selection_te_obfuscation
falsepositives:
- Legacy HTTP/1.0 clients in industrial environments
- Certain API gateways that normalize but forward both headers during migration
level: high
---
title: HTTP 408 Response Storm on Reused Keep-Alive Connections
title: HTTP 408 Timeout Storm Indicating Desync Back-End Divergence
id: 1e7c4a92-6b3f-4d28-9e51-2a8b5f3c6047
status: experimental
description: Detects elevated volumes of HTTP 408 (Request Timeout) responses on a single virtual host or back-end pool — a classic operational symptom of desynchronization, where smuggled request prefixes leave the back-end waiting for a body that never completes. Observed during active smuggling probing per PortSwigger desync methodology.
references:
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://thehackernews.com/2026/08/ai-assisted-http-terminator-finds-novel.html
author: Security Arsenal
date: 2026/08/15
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection:
sc-status: 408
condition: selection | count() by c-ip > 20
timeframe: 5m
falsepositives:
- Slow mobile clients on high-latency networks
- Health-check misconfigurations
level: medium
---
title: POST Request with Mismatched Expect and Chunked Body to Origin Server
id: 5b3d8e14-7a2c-4f96-8c41-6d9e2b5a7138
status: experimental
description: Detects requests combining Expect: 100-continue with chunked transfer framing directed at origin/application servers — a framing ambiguity class exercised by novel desync vectors, where intermediaries disagree on interim-response handling and body boundaries.
references:
- https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
- https://thehackernews.com/2026/08/ai-assisted-http-terminator-finds-novel.html
author: Security Arsenal
date: 2026/08/15
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection:
cs-headers|contains|all:
- 'Expect: 100-continue'
- 'Transfer-Encoding'
condition: selection
falsepositives:
- curl-based API clients sending large chunked payloads
level: medium
Operational note on tuning: selection_te_obfuscation includes Transfer-Encoding: chunked as a bare duplicate-pattern signal in some SIEM web log schemas — if your legitimate traffic legitimately uses chunked encoding (it will), scope that rule to requests that also contain Content-Length, or restrict to non-standard header spellings only. A desync rule that fires on every chunked upload will be disabled by Friday.
KQL — Microsoft Sentinel
This query assumes edge/proxy logs (ATS, nginx, HAProxy, WAF) are ingested via CEF/Syslog or a custom table, and compares edge-observed requests against back-end application logs to find the smoking gun of smuggling: requests that materialized on the origin with no corresponding edge entry. Run it as a scheduled hunting query.
// Hunt: Requests present at the back-end but absent at the edge — the structural fingerprint of successful request smuggling
let EdgeRequests =
CommonSecurityLog
| where TimeGenerated > ago(1h)
| where DeviceProduct has_any ("Traffic Server", "nginx", "haproxy", "Apache")
| where RequestMethod in ("POST", "PUT", "PATCH")
| project EdgeTime=TimeGenerated, SourceIP, RequestURL, RequestMethod, EdgeHeaders=AdditionalExtensions;
let BackendRequests =
Syslog
| where TimeGenerated > ago(1h)
| where SyslogMessage has_any ("POST", "PUT", "PATCH")
| extend ParsedURL = extract(@'"(POST|PUT|PATCH) ([^ ]+)', 2, SyslogMessage)
| extend ParsedMethod = extract(@'"(POST|PUT|PATCH) ([^ ]+)', 1, SyslogMessage)
| where isnotempty(ParsedURL)
| project BackendTime=TimeGenerated, Computer, ParsedMethod, ParsedURL, SyslogMessage;
BackendRequests
| join kind=leftanti (
EdgeRequests
| where RequestURL != ""
) on $left.ParsedURL == $right.RequestURL
| where ParsedURL has_any ("/admin", "/internal", "/api", "/manage", "/debug")
or SyslogMessage has_any ("Content-Length", "Transfer-Encoding")
| summarize FirstSeen=min(BackendTime), LastSeen=max(BackendTime), Hits=count() by Computer, ParsedMethod, ParsedURL
| order by Hits desc;
A second, complementary hunt for framing-ambiguity probing at the edge itself:
// Hunt: Edge-observed requests carrying both CL and TE headers, or obfuscated Transfer-Encoding spellings
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where isnotempty(AdditionalExtensions)
| where (AdditionalExtensions has "Content-Length" and AdditionalExtensions has "Transfer-Encoding")
or AdditionalExtensions has_any (
"Transfer-Encoding :", "xchunked", "Transfer-Encoding: identity",
"Transfer-Encoding: cow", " Transfer-Encoding"
)
| summarize Attempts=count(), DistinctTargets=dcount(DestinationHostName),
FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated)
by SourceIP, DestinationHostName, RequestURL
| where Attempts > 5 or DistinctTargets > 3 // probing sweeps, not one-off clients
| order by Attempts desc;
Velociraptor VQL
For DFIR teams validating whether a proxy or origin server was subjected to desync probing, this artifact hunts local web/proxy access logs for ambiguous framing patterns and evidence of 408 divergence — useful during retroactive scoping once the ATS advisory drops.
-- Hunt local web/proxy access logs for HTTP desync indicators:
-- ambiguous framing headers and 408-timeout clustering on keep-alive connections
LET log_paths = SELECT FullPath
FROM glob(globs=[
'/var/log/trafficserver/*.log',
'/var/log/apache2/*access*.log',
'/var/log/nginx/*access*.log',
'/var/log/haproxy*.log'
])
SELECT FullPath,
Line,
parse_string_with_regex(
string=Line,
regex='(?i)(content-length|transfer-encoding|expect:\s*100)'
) AS HeaderEvidence
FROM foreach(
row=log_paths,
query={
SELECT FullPath, Line
FROM split_lines(filename=FullPath, buffer_size=1000000)
WHERE Line =~ '(?i)content-length'
AND Line =~ '(?i)transfer-encoding'
OR Line =~ ' 408 '
OR Line =~ '(?i)transfer-encoding[\t ]*:'
})
Remediation / Hardening Script
No ATS patch exists yet. The highest-value compensating control for any HTTP/1.1 front tier is strict request normalization: reject ambiguous framing outright rather than attempting to interpret it. This Bash script audits and hardens an nginx or Apache httpd front-end (and flags ATS deployments for manual verification), enforcing the "reject, don't reconcile" posture.
#!/bin/bash
# Security Arsenal — HTTP Desync Compensating Controls Audit & Hardening
# Applies defense-in-depth for unpatched HTTP desync exposure (PortSwigger HTTP Terminator research, Aug 2026)
# Run on each edge proxy / origin server. Review before applying in production.
set -euo pipefail
echo "=== HTTP Desync Posture Check — $(hostname) — $(date -u) ==="
# --- 1. Detect Apache Traffic Server and report version (NO PATCH AVAILABLE — inventory first) ---
if command -v traffic_server >/dev/null 2>&1; then
echo "[!] Apache Traffic Server DETECTED:"
traffic_server -V 2>/dev/null | head -3
echo " ACTION REQUIRED: Unpatched desync vulnerability disclosed Aug 2026."
echo " - Subscribe to https://lists.apache.org/list.html?users@trafficserver.apache.org"
echo " - Track https://github.com/apache/trafficserver/security for the advisory + fixed release"
echo " - Enable strict header checks in records.config NOW:"
echo " CONFIG proxy.config.http.strict_transaction_parsing INT 1"
fi
# --- 2. nginx: verify hardened framing posture ---
if command -v nginx >/dev/null 2>&1; then
echo "[+] nginx detected — verifying desync-relevant configuration..."
nginx -V 2>&1 | grep -q 'with-http_v2' && echo " [i] HTTP/2 module present (back-end h2 reduces desync surface)"
grep -Rq 'merge_slashes\|underscores_in_headers' /etc/nginx/ 2>/dev/null \
&& echo " [!] Review header normalization directives in /etc/nginx/"
echo " RECOMMENDED: terminate HTTP/2 at edge, use HTTP/1.1 upstream ONLY with"
echo " keepalive disabled for smuggling-sensitive vhosts, or gRPC/h2 upstreams."
fi
# --- 3. Apache httpd: enforce strict request rejection ---
if command -v apachectl >/dev/null 2>&1 || command -v httpd >/dev/null 2>&1; then
HTTPD_CONF=$(apachectl -V 2>/dev/null | awk -F'"' '/HTTPD_ROOT/{print $2}')/conf || true
echo "[+] Apache httpd detected at ${HTTPD_CONF:-unknown}"
cat > /etc/apache2/conf-available/zz-desync-hardening.conf <<'EOF'
# Reject ambiguous message framing — compensating control for HTTP desync research (Aug 2026)
HttpProtocolOptions Strict
<IfModule mod_rewrite.c>
RewriteEngine On
# Reject requests carrying both Content-Length and Transfer-Encoding
RewriteCond %{HTTP:Content-Length} . [NC]
RewriteCond %{HTTP:Transfer-Encoding} . [NC]
RewriteRule .* - [R=400,L]
# Reject obfuscated Transfer-Encoding spellings (whitespace/prefix tricks)
RewriteCond %{HTTP:Transfer-Encoding} "!^chunked$" [NC]
RewriteRule .* - [R=400,L]
</IfModule>
EOF
echo " Wrote zz-desync-hardening.conf — enable with: a2enconf zz-desync-hardening && systemctl reload apache2"
fi
# --- 4. Universal: flag HTTP/1.1-only origins sitting behind CDNs ---
echo "=== Architecture check ==="
echo "[i] Highest-risk posture: HTTP/1.1 with keep-alive connection reuse between front-end and back-end."
echo " Mitigations (vendor-agnostic):"
echo " 1. Use HTTP/2 for the front-end→back-end hop where supported (h2 has no ambiguous framing)"
echo " 2. If HTTP/1.1 upstream is mandatory: disable connection reuse to the back-end"
echo " 3. Reject (never silently reconcile) any request with both CL and TE headers"
echo " 4. Ensure WAF normalizes/observe-blocks duplicate & whitespace-obfuscated headers"
echo "=== Done. ==="
Remediation
There is no patch for the Apache Traffic Server vulnerability at time of writing. Your remediation plan is compensating controls plus a patch-readiness posture:
-
Inventory and isolate ATS exposure today. Run the script above across your fleet. If ATS fronts internet-facing traffic, assume probing begins within days of technique publication. Monitor the Apache Traffic Server project and its GitHub security advisories — when the fixed version lands, treat it as an emergency change.
-
Enforce strict framing rejection at every hop. Any request with both
Content-LengthandTransfer-Encoding, duplicate framing headers, or obfuscatedTransfer-Encodingspellings must get a 400, not a best-effort interpretation. "Reject, don't reconcile" is the single most effective desync control. -
Collapse the parsing differential. Desync requires disagreement. Where feasible, use HTTP/2 end-to-end (edge to origin) — h2's binary framing eliminates the CL/TE ambiguity class entirely. If your back-end is HTTP/1.1-only, disable connection reuse/keep-alive between the proxy and back-end for sensitive virtual hosts; performance cost is real but bounded, and it removes the smuggling precondition.
-
Brief your WAF vendor explicitly. Ask them — in writing — whether their request-smuggling ruleset covers vectors beyond the documented CL.TE/TE.CL/TE.TE taxonomy, and what their ingestion process is for the PortSwigger research. If the answer is "we'll update signatures after Burp ships the feature," that tells you your WAF is a lagging control for this threat class. Weight control #2 accordingly.
-
Stand up the back-end/edge log reconciliation hunt (KQL above) before you need it. Successful smuggling is otherwise invisible — cache poisoning may be your first and only symptom.
-
If you operate a CDN or shared caching layer: audit cache keying and purge capability now. The worst realistic outcome of these vectors is poisoned responses served to thousands of users; your mean-time-to-purge is the metric that matters during the incident.
-
Watch for the CVE. When Apache assigns an identifier, it will land in CISA KEV quickly given ATS's footprint. Pre-build your patch pipeline so KEV listing triggers deployment, not discovery.
The Bigger Picture
HTTP Terminator is a proof point for something security leadership needs to internalize: AI-assisted vulnerability research has crossed from fuzzing assistance to autonomous technique discovery at a scale no human research team matches. 30,000 explored vectors and machine-proven exploits means the "novel web protocol attack" pipeline is now industrialized. Signature-driven edge defense was already strained; it is now structurally insufficient. The durable defenses — strict parsing, homogeneous protocol stacks, behavioral log reconciliation — are architectural, and they take quarters, not sprints, to deploy. Start now.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.