# Making desync attacks easy with TRACE

TRACE method reflection combined with HTTP/2 desync and response smuggling lets an attacker craft arbitrary cached responses, achieving stored XSS and full app compromise.

- Payout: Research
- Severity: high
- Program: PortSwigger research target
- Credited: PortSwigger Research
- Disclosed: 2024-03-19
- Write-up quality: 9/10
- Original: https://portswigger.net/research/trace-desync-attack
- Library page: https://bugbountylibrary.com/r/blog%3Aportswigger-net-research-trace-desync-attack
- Tags: domain:web impact:ato impact:integrity kind:research platform:research sev:high technique:chained vuln:cache-poisoning vuln:request-smuggling vuln:xss

**Target:** HTTP/2 frontend proxy with backend supporting TRACE
**Root cause:** Backend reflects full request (including injected headers) in TRACE responses; combined with CL.0/HTTP2 desync and HEAD response concatenation, attacker controls bytes of a cached response.
**Steps:**
1. Confirm HTTP/2 header injection allows smuggling a transfer-encoding header to split requests at backend.
2. Send `HEAD /smuggled` smuggled request so proxy treats next response as body of HEAD.
3. Send `TRACE / HTTP/1.1` with header `A: HTTP/1.1 200 Ok\r\nCache-Control: max-age=1000000` to inject response headers via reflection.
4. Append a second smuggled `TRACE` with `A: <script>alert('XSS')</script>` to supply body.
5. Resulting concatenated response is parsed as a valid HTTP response with text/html and long cache, stored in cache for /smuggled.
**How found:** After a bounty triager rejected a bare smuggling report, researcher searched for reflection primitives; noticed backend responded to TRACE, realized TRACE echoes request headers verbatim, and combined with HEAD response concatenation to synthesize arbitrary cached responses.
**Exploitation:** Attacker smuggles HEAD + TRACE requests over a desynced HTTP/2 connection; TRACE reflects attacker-controlled headers as response bytes, which the proxy parses as a new HTTP response with attacker-chosen Content-Type, Cache-Control and body. The poisoned response is cached and served to victims, executing arbitrary JavaScript (stored XSS) on the target origin.
**Escalation:** Chains desync (HTTP/2 header injection) + response smuggling + TRACE reflection + web cache poisoning to convert a non-exploitable smuggling primitive into stored XSS affecting all users.
**Insight:** When a desync primitive lacks a reflection endpoint, check for TRACE (often enabled by default on Apache/IIS/Tomcat) — its loopback reflection of headers gives you a byte-controlled response body that can be split into a full fake HTTP response for cache poisoning.
