scanrub
HTTP Request Smugglinghigh prioritypartial coverage

HTTP Request Smuggling (HRS) / De-sync

5 min read 52 reports analyzed ScanRub Research
Share

Summary

HRS reports cluster around parser disagreement between a front-end (CDN/proxy/load-balancer) and a back-end (application server). Variants: classic CL.TE / TE.CL / TE.TE on HTTP/1.1, plus modern HTTP/2 downgrade smuggling, CL.0 desync, pause-based desync, and client-side desync (CSD). Root causes are almost always permissive parsing of header obfuscation: duplicate Transfer-Encoding, space/tab before colon, multi-line obs-fold, chunk extensions, CR-only or LF-only line terminators, embedded NULs in header names, trailers without colons, hex chunk-size confusion, and improper header termination (\r\n\rX). Node.js llhttp dominates the corpus (CVE-2020-8287, 2021-22959/22960, 2022-32213/32214/32215/35256, 2023-30589, 2024-27982, 2025-23167) but Apache Tomcat (CVE-2023-45648, 2024-21733), Apache HTTPD (pause-based desync), Cloudflare Transform/Origin Rules, and various CDN/origin combinations are also represented. Impact is consistently high: bypass of Cloudflare Access / WAF, cache poisoning, credential capture, mass redirect, and access to internal origin servers.

◈ flow diagram
Ambiguous Re…Front-End Pa…Back-End Mis…Request Boun…Smuggled Req…
◈ chart
Critical
4
High
13
Medium
22
Low
13

Top Affected Components / Targets

  • Node.js (Express/Fastify/Koa) behind a CDN - llhttp parser
  • Apache Tomcat 8.5/9.0 with trailer support enabled
  • Apache HTTPD (mod_proxy + back-end stack)
  • Cloudflare Workers / Transform Rules / Origin Rules
  • Akamai / Fastly / AWS ALB front-ends in front of misbehaving origins
  • Custom reverse proxies written in Go/Rust without strict header parsing
  • HTTP/2 endpoints downgrading to HTTP/1.1 backend

Common Attack Vectors

  • TE-CL: front-end honours Transfer-Encoding, back-end honours Content-Length
  • CL-TE: opposite, with chunk-size 0 hiding a smuggled second request
  • TE-TE: ship two TE headers, one obfuscated, peers disagree which to honour
  • Smuggle a request that bypasses CDN access controls (Cloudflare Access bypass)
  • Poison the back-end TCP/TLS socket with attacker-controlled prefix; next victim sees attacker response
  • Cache-poison a path with attacker response (mass-redirect / phishing)
  • Capture victim cookies by smuggling a request that echoes them
  • HTTP/2 downgrade: smuggle pseudo-headers into HTTP/1.1 backend
  • CL.0 client-side desync (Tomcat CVE-2024-21733) to leak victim browser data
  • Host-header injection chained with X-Forwarded-Host to redirect via internal links

Common Payloads

  • Transfer-Encoding: chunked\r\nTransfer-Encoding: identity (TE-TE)
  • Transfer-Encoding\t: chunked (tab before colon)
  • Content-Length : 5 (space before colon)
  • Transfer-Encoding: chunkedchunked
  • Transfer-Encoding: chunked\r\n , identity (multi-line obs-fold)
  • 5; ext=value\r\n... (chunk extension confusion)
  • Header block ending with \r\n\rX
  • Lone-CR or lone-LF line terminator inside a header
  • POST /\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET /smuggled HTTP/1.1\r\nHost: a\r\n\r\n
  • Trailer line lacking colon (Tomcat CVE-2023-45648 PoC)

Detection Strategy

Black-box detection of HRS is risky for production targets, so a passive-by-default posture makes sense: run active probes only when explicitly authorized.

Stage 0: fingerprint front-end and back-end

Fetch the homepage and check Server, Via, X-Cache, X-Served-By, CF-Ray, X-Amz-Cf-Id headers; if a CDN is detected, raise the risk score.

Stage 1: timing differential

Replay a 'CL-TE' style request with a tight Content-Length and a 0\r\n\r\n chunked body; measure TTFB. If response timing for the next request on the keep-alive connection deviates >2x from baseline, mark as suspect (medium confidence).

Stage 2: Burp-style 'safe' probes from PortSwigger research

Send timing-based probes that DO NOT inject into back-end socket - only force a back-end timeout differential.

Stage 3: header-obfuscation surveys

Emit Transfer-Encoding\t: chunked and Content-Length : 5 and verify whether server returns 400 vs 200 - only the response code differential is recorded, never a smuggled second request.

Stage 4: Tomcat trailer probe

If Server: Apache Tomcat detected, send a chunked POST with a colon-less trailer line and observe whether the response includes echoed input from a 'smuggled' marker - but limit this probe to test/staging only, not production.

Stage 5: HTTP/2 downgrade probe

If HTTP/2 is offered, send a request whose :authority differs from Host; observe whether the back-end leaks the alternate authority.

Stage 6: advisory

Match server/version against the CVE list (CVE-2020-8287, CVE-2021-22959/22960, CVE-2022-32213/32214/32215/35256, CVE-2023-30589/45648, CVE-2024-21733/27982, CVE-2025-23167) using the existing nuclei pipeline.

Confidence: timing alone = low; header-obfuscation 400/200 differential = medium; nuclei version match = high. Active end-to-end smuggling tests should be opt-in and require an out-of-band test endpoint.

Tip: Testing tools that run these checks in parallel across every discovered endpoint can cut the time required substantially compared to fully manual testing, as long as they confirm findings with more than one signal to keep the false-positive rate down.

False-Positive Notes

  • End-to-end smuggling detection requires sending payloads that cross requests on a keep-alive socket, which can cause real damage by poisoning legitimate users' connections, so this should never be attempted against a production target.
  • Safer alternatives are version-based CVE matching, passive header fingerprinting, and obfuscation-payload probes that only read response codes, never sending a follow-up request that would consume the smuggled prefix.
  • Even safe probes should be rate-limited and avoid endpoints that mutate state.
  • Many CDNs, including Cloudflare and Akamai, reject obfuscated headers with a 400 response.
  • That's a positive signal of correct front-end behavior, not a finding.

How to Test

Manual Testing Methodology

Here is a systematic approach to identifying HTTP Request Smuggling (HRS) / De-sync vulnerabilities in a target application.

Step 1: Reconnaissance and Surface Mapping

Before testing, map all input vectors that could be affected. Identify parameters, headers, cookies, and request bodies that interact with the vulnerable component. A proxy such as Burp Suite or OWASP ZAP, paired with normal browsing of the target, is usually enough to build this list.

Step 2: Baseline Request

Send a legitimate request and record the normal response: status code, content length, response time, and any identifying tokens. This baseline matters because it's what you'll compare later responses against once payloads are involved.

Step 3: Payload Injection

Inject test payloads into each identified input vector one at a time. Start with benign detection payloads before escalating to anything that could actually trigger the vulnerability. For HTTP Request Smuggling (HRS) / De-sync specifically, send requests with both Content-Length and Transfer-Encoding: chunked headers present, with conflicting values, and with malformed chunked encoding, then observe the timing and content of the following request's response for evidence the back-end and front-end disagreed on the boundary.

Step 4: Response Analysis

Compare the response against your baseline, looking specifically for a response that doesn't match the request that was sent (evidence of desync), an unexpectedly long response delay characteristic of the request being queued behind smuggled data, or content from a different, unrelated request appearing in the response.

Step 5: Confirmation

Once a potential vulnerability is detected, confirm it with at least a few independent test cases to rule out coincidence. Document the exact request and response as proof. For HTTP Request Smuggling (HRS) / De-sync, a confirmed finding typically means showing that attacker-controlled input changes the application's behavior in a way that matters for security, not just that a payload was reflected somewhere harmless.

Real-World Impact

Real-World Impact

HTTP request smuggling exploits disagreement between a front-end proxy and a back-end server about where one HTTP request ends and the next begins — usually from conflicting or ambiguous Content-Length and Transfer-Encoding headers. That disagreement lets an attacker prepend part of their request onto the next, unrelated request in the same connection, effectively injecting a request into another user's traffic.

The consequences scale from response queue poisoning that returns one user's response to another, to full request hijacking that can bypass front-end access controls, and to cache poisoning when a smuggled request gets cached and served to subsequent visitors.

Because it depends on the specific parsing behavior of two different pieces of infrastructure interacting, request smuggling is inconsistent across environments — a technique that smuggles cleanly through one proxy/server pair may not work at all against another, which makes it both easy to dismiss prematurely and genuinely hard to fully rule out.

Prevention & Remediation

Prevention and Secure Coding

Preventing HTTP Request Smuggling (HRS) / De-sync takes a defense-in-depth approach — no single control below is sufficient alone, but together they close off both the primary path and the most common bypasses.

Consistent parsing front-to-back. Keep the front-end proxy and back-end server's HTTP parsing behavior aligned — ideally by using the same well-tested HTTP implementation, or by validating that both explicitly agree on ambiguous-header handling.

Prefer HTTP/2 end-to-end. HTTP/2's binary framing removes most of the header-based ambiguity that enables smuggling in HTTP/1.1; using it end-to-end (not just downgraded at the edge) closes off the bulk of this attack surface.

Reject ambiguous requests at the edge. Normalize or outright reject requests containing both Content-Length and Transfer-Encoding headers, or with a malformed Transfer-Encoding value, at the first hop rather than passing them through.

Keep both layers current. Known HTTP-parser smuggling issues get patched over time; an outdated proxy or server component reintroduces problems that were already fixed elsewhere.

Disable connection reuse to untrusted origins where feasible. Isolating requests to separate connections limits how far a successful smuggle can reach.

Source reports

A sample of the disclosed HackerOne reports this playbook was synthesized from.

Frequently Asked Questions

What is HTTP Request Smuggling (HRS) / De-sync?
HRS reports cluster around parser disagreement between a front-end (CDN/proxy/load-balancer) and a back-end (application server).
How common is HTTP Request Smuggling (HRS) / De-sync in bug bounty reports?
Scanrub's research corpus for this playbook is built from 52 disclosed HackerOne reports in this category, synthesized for detection and prevention guidance rather than reproduced verbatim.
How do I test for HTTP Request Smuggling (HRS) / De-sync?
Map every input vector, record a baseline response, then inject targeted test payloads one field at a time and compare the response for timing, length, error, or reflection differences from that baseline. The "How to Test" section above walks through the full methodology for this specific vulnerability class.
What is the single most effective fix for HTTP Request Smuggling (HRS) / De-sync?
Reject requests with ambiguous or conflicting Content-Length/Transfer-Encoding headers at the edge, and prefer HTTP/2 end-to-end to remove the parsing ambiguity smuggling depends on.
Weekly security research

New vulnerability playbooks, tool updates, and bug bounty insights - delivered to your inbox. No spam.

Unsubscribe anytime. We respect your inbox.
Press ⌘K to search×