The HTTP TRACE method makes a server echo the received request back to the client. What is it meant to be used for, and why do most production servers and proxies disable it?
answer
- Loop-back echo, Content-Type: message/http
- Max-Forwards picks the hop that answers
- Echoes Cookie / Authorization / internal headers
- XST 2003 — defeated HttpOnly; browsers now block TRACE
- Block TRACK too; allow-list methods at the edge
basics
~20 sTRACE is a loop-back diagnostic: the final server echoes the request it received back as the response body, revealing how proxies rewrote it. It is disabled because the echo reflects cookies, Authorization headers, and internal proxy headers back to the caller — information disclosure, historically exploited as Cross-Site Tracing.
solid answer
~50 s**TRACE is a diagnostic loop-back.** The client sends `TRACE`, and the final recipient echoes the exact request message it received back as the response body with `Content-Type: message/http`, status 200. Comparing what you sent with what came back shows how intermediaries rewrote headers, added `Via`/`X-Forwarded-For`, or stripped things. `Max-Forwards` lets you stop the request at a chosen hop and ask *that* proxy what it saw. **Why it is disabled:** the echoed message contains everything the request carried — session cookies, `Authorization`, internal proxy headers with internal hostnames and IPs. The 2003 *Cross-Site Tracing* (XST) attack used script to force a browser into sending a credentialed TRACE and then read the echo, defeating `HttpOnly` cookies. Modern browsers forbid TRACE from `fetch`/XHR, so XST is largely dead, but the information disclosure remains, scanners still flag it, and TRACE has essentially no operational value in an era of structured logging and request tracing headers. Default-deny it at the edge — including IIS's `TRACK` variant.
code
http · 15 linesTRACE /app HTTP/1.1
Host: example.com
Cookie: session=8f3ac1d9
Authorization: Bearer eyJhbGci...
HTTP/1.1 200 OK
Content-Type: message/http
TRACE /app HTTP/1.1
Host: example.com
Cookie: session=8f3ac1d9
Authorization: Bearer eyJhbGci...
Via: 1.1 edge-cache-07.internal
X-Forwarded-For: 203.0.113.9
X-Backend-Pool: app-blue-eugo deeper
It is enough to know TRACE echoes your request back and that it is turned off in production because the echo can leak cookies and other sensitive headers.
Describe the loop-back mechanics — message/http body, Max-Forwards choosing the responding hop — and name credential reflection as the reason it is disabled.
Place XST historically and accurately, explain that browsers now refuse the method so the live risk is internal-header disclosure, and describe layered disabling including TRACK and origin-level enforcement.
Argue the policy: an allow-list of methods at every layer rather than a deny-list of remembered bad ones, justified by TRACE having zero operational value against non-zero disclosure risk, and note that perimeter-only method policy fails under an internal compromise.
## What TRACE does `TRACE` performs a message loop-back test along the request path. The client issues a TRACE for a target URI; each intermediary forwards it (decrementing `Max-Forwards` if present); the final recipient — the origin server, or the proxy where `Max-Forwards` hits zero — reflects the request message it received back to the client as the response body, with status `200 OK` and `Content-Type: message/http`. TRACE is safe and idempotent. A TRACE request must not carry a body, because the body of the *response* is defined to be the request itself. ## The diagnostic idea On a path with several hops — a CDN, a WAF, a load balancer, a reverse proxy, an app server — you often want to know what the origin *actually* sees. Intermediaries add `Via`, append to `X-Forwarded-For`, rewrite `Host`, strip hop-by-hop headers named in `Connection`, normalise casing, merge duplicates. TRACE was the protocol's own way to answer "which box mangled my header?": diff the request you sent against the echoed copy. `Max-Forwards` turns this into a hop-by-hop probe. `Max-Forwards: 0` makes the first intermediary answer instead of forwarding; `Max-Forwards: 1` makes the second answer, and so on. This is the same mechanism `OPTIONS` uses to address a specific hop. ## Why it is switched off everywhere **1. Credential and internal-state disclosure.** The echo is a faithful copy of the request, including `Cookie`, `Authorization`, `Proxy-Authorization`, and any internal headers a proxy injected — internal hostnames, backend pool names, real client IPs, sometimes auth tokens minted at the edge. A response that reflects all of that to whoever asked is a disclosure primitive: an attacker who can get *any* credentialed TRACE issued sees the credentials. **2. Cross-Site Tracing (XST).** Published in 2003, XST chained TRACE with script execution. Browser scripting APIs of the day would issue a TRACE with the site's cookies attached; because the credentials arrive back inside a readable *response body* rather than a cookie jar, `HttpOnly` — whose whole purpose is to hide cookies from script — provided no protection. XST was the reason TRACE landed on hardening checklists. It matters less today: the Fetch specification forbids TRACE, TRACK, and CONNECT as request methods, so `fetch()` and `XMLHttpRequest` refuse them outright, and plugin-based vectors are gone. Treat XST as historical context, not a live exploit — but say so precisely rather than claiming TRACE is harmless now. **3. TRACK, the Microsoft variant.** IIS historically implemented `TRACK` with the same loop-back behaviour. Blocking only `TRACE` by name and leaving `TRACK` open is a classic incomplete fix, and scanners test both. **4. It buys nothing.** Modern debugging uses structured access logs, `traceparent`/W3C Trace Context, request-ID headers, packet capture, and per-hop debug endpoints. Nobody's incident response depends on TRACE. When a method has non-zero risk and near-zero value, default-deny is the easy call — which is why PCI-style scans and most hardening baselines simply require it off. ## How to disable it correctly Turn it off at every layer that can answer, not just one: `TraceEnable off` in Apache, method filtering in nginx or the reverse proxy, `<verbs>` restrictions in IIS covering TRACE *and* TRACK, plus the application framework's own method routing. Prefer an allow-list of methods at the edge over a deny-list of the ones you have heard of — the allow-list also catches WebDAV methods and anything a future framework enables by default. Verify by sending a real TRACE with curl and confirming `405` or `501`. A subtlety: if the edge blocks TRACE but an internal caller can reach the origin directly, the origin still needs it disabled. Method policy applied only at the perimeter fails the moment something inside the perimeter is compromised. ## What a good answer sounds like Name the mechanism (loop-back echo, `message/http`, `Max-Forwards`), name the real risk (reflection of credentials and internal headers), place XST accurately in time (2003, largely mitigated by browsers refusing the method), and finish on policy: allow-list methods at the edge, cover TRACK, verify at the origin too.
- Browsers no longer allow TRACE from fetch or XMLHttpRequest. Does that mean leaving TRACE enabled is now acceptable?No. Removing the browser vector retires Cross-Site Tracing specifically, but the response still reflects Authorization headers, cookies, and internal proxy headers such as backend pool names and internal IPs to any caller — including a compromised host inside the network or an SSRF primitive. Since TRACE provides no operational value that logs and trace headers do not already provide, the cost of leaving it on is entirely one-sided.
- How does Max-Forwards change which hop answers a TRACE, and why is that useful?Each intermediary that forwards the request decrements Max-Forwards; when a recipient sees the value 0 it must answer itself instead of forwarding. Sending Max-Forwards: 0 therefore gets a reply from the first proxy, 1 from the second, and so on. That lets you walk the chain and see exactly where a header was added, rewritten, or stripped. The same mechanism applies to OPTIONS.
TRACE is asking every post office on the route to photocopy your envelope and mail the copy back — useful for finding which office restamped it, disastrous when the envelope contained your keys.
saying these in an interview costs you the question
- Saying TRACE is a debugging tool with no security implication
- Claiming HttpOnly cookies protected against Cross-Site Tracing
- Blocking TRACE but leaving the IIS TRACK variant enabled
- Disabling TRACE only at the edge and leaving the origin answering it
- Confusing TRACE with distributed tracing headers such as traceparent