HTTP Request Smuggling 2026 — TE.CL, CL.TE Techniques & High-Impact Exploitation | BB Day21

HTTP Request Smuggling 2026 — TE.CL, CL.TE Techniques & High-Impact Exploitation | BB Day21
🎯 BUG BOUNTY MASTERY
FREE

Part of the Bug Bounty Mastery Course

Day 21 of 180 · 12% complete

HTTP Request Smuggling in 2026 :— James Kettle called it “reborn” in 2019 when he showed how a single ambiguous HTTP request could poison another user’s connection. Six years later, the vulnerability class has evolved — HTTP/2 downgrade attacks created new variants — but the core condition remains widespread: front-end load balancers and back-end origin servers parsing the same request differently, creating a gap where hidden requests can slip through every perimeter defence. It bypasses authentication, captures other users’ credentials, and poisons CDN caches at scale. It is one of the highest-severity and highest-paying vulnerability classes in modern web bug bounty, and it sits in almost every application running HTTP/1.1 between layers.

🎯 What You’ll Master Today

Understand the CL/TE desync condition that makes request smuggling possible
Distinguish CL.TE vs TE.CL attack types and know which to test first for each target
Detect smuggling vulnerabilities safely using Burp’s HTTP Request Smuggler extension
Exploit for access control bypass — reaching admin endpoints the front-end blocks
Exploit for credential capture — poisoning connections to receive another user’s request
Write a complete bug bounty report for a confirmed smuggling finding

⏱️ 60 min · 3 exercises · Burp Suite + PortSwigger labs

📋 Prerequisites — Complete Before Day 21

  • Day 12: File Upload Bug Bounty — intermediate HTTP manipulation skills needed before tackling the complex header interactions in request smuggling
  • Day 18: OAuth Attacks — understand multi-layer auth flows; smuggling exploits the same front-end/back-end trust relationships that OAuth attacks target
  • Burp Suite installed and configured as browser proxy — all exercises require active Burp Proxy interception

How HTTP Request Smuggling Works — The Desync Condition

Modern web applications typically use a front-end server — a CDN, reverse proxy, or load balancer — that forwards requests to back-end origin servers. HTTP/1.1 allows multiple requests over a single TCP connection (keep-alive). When the front-end forwards these requests to the back-end, it needs to correctly determine where one request ends and the next begins. HTTP/1.1 specifies two headers for this purpose: Content-Length (specifying the exact byte count of the body) and Transfer-Encoding: chunked (specifying body length through a series of chunks with hexadecimal length prefixes).

The specification says both headers should never appear in the same request. When they do, different servers make different decisions about which to honour. If the front-end and back-end make different decisions — one honours Content-Length, the other honours Transfer-Encoding — they disagree about where the request body ends. The bytes the front-end includes as part of the first request body may be interpreted by the back-end as the beginning of a second request. That second request was smuggled in without going through the front-end’s security checks.

securityelites.com
CL.TE Desync — How One Request Becomes Two
FRONT-END sees (uses Content-Length: 13)
POST / HTTP/1.1
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

Forwards all 13 bytes as one request body

BACK-END sees (uses Transfer-Encoding)
Request 1:
POST / HTTP/1.1
body: [chunk “0\r\n\r\n” = empty]
Request 2 (smuggled):
SMUGGLED ← next user’s request appended
Treats “SMUGGLED” as start of new request

📸 The CL.TE desync condition. The front-end honours Content-Length and sees a single 13-byte request body. The back-end honours Transfer-Encoding and sees the chunk terminator (0\r\n\r\n) as the end of the request, then interprets “SMUGGLED” as the beginning of a new request. The smuggled data is prepended to the next user’s incoming request — poisoning it with attacker-controlled content before it reaches the application.


CL.TE Attack — Front-End Uses Content-Length

In a CL.TE attack, the front-end uses the Content-Length header to determine the body size and forwards the entire CL-length body to the back-end. The back-end uses Transfer-Encoding and processes the chunked body — reading each chunk and its hex length prefix until it encounters the zero-length terminator chunk (0\r\n\r\n). Any bytes after the terminator that were included in the CL-sized body are left in the back-end’s read buffer and treated as the beginning of the next request.

The attack payload places a zero-length chunk terminator early in the body, followed by the smuggled request prefix. The front-end reads the full CL-sized body and forwards all of it. The back-end reads up to the zero-length chunk and stops, leaving the smuggled prefix in its buffer. When the next request arrives from any user, the back-end prepends the buffered smuggled prefix to that request — resulting in a malformed request that may reach different application logic or expose the next user’s request to the attacker.

CL.TE ATTACK — BASIC PAYLOAD STRUCTURE
# CL.TE request — front-end uses Content-Length, back-end uses Transfer-Encoding
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
# Front-end: CL=13, reads all 13 bytes (0\r\n\r\nSMUGGLED), forwards all
# Back-end: TE=chunked, reads “0\r\n\r\n” as empty chunk (end of request)
# “SMUGGLED” stays in back-end buffer
# Next user’s request gets “SMUGGLED” prepended
# Timing detection: send this, then send a normal request
# If the normal request hangs/errors: CL.TE desync confirmed
POST / HTTP/1.1
Content-Length: 6
Transfer-Encoding: chunked
0
X
# If back-end times out waiting for more data: CL.TE confirmed

🌐 EXERCISE 1 — PORTSWIGGER LAB (20 MIN)
HTTP Request Smuggling — CL.TE Basic Lab

⏱️ 20 minutes · Free PortSwigger account required

Step 1: Go to portswigger.net/web-security/request-smuggling
Create a free account if you don’t have one.
Find: “HTTP request smuggling, basic CL.TE vulnerability”
Click “Access the lab”

Step 2: Install HTTP Request Smuggler extension in Burp
Burp Suite > Extensions > BApp Store
Search: “HTTP Request Smuggler” by James Kettle
Install and confirm it appears in Extensions list

Step 3: Use the extension to detect the vulnerability
With the lab open in browser proxied through Burp:
Right-click any request in Burp Proxy > HTTP History
Extensions > HTTP Request Smuggler > Launch
Watch the extension’s output — it will identify CL.TE

Step 4: Manually craft the exploit
In Burp Repeater, build the CL.TE payload:
POST / HTTP/1.1
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED
– Disable Update Content-Length in Repeater
– Send the request, then immediately send a normal POST
– Observe if the second request errors: “Invalid method SMUGGLED…”

Step 5: Confirm the lab’s intended exploit
Follow PortSwigger’s solution guidance.
Note: what was the exact impact demonstrated?
Document the Content-Length value and the smuggled prefix.

✅ What you just learned: The HTTP Request Smuggler extension dramatically simplifies detection — it automates the timing and differential response tests that would take significant manual effort. The manual Burp Repeater exercise shows exactly what the automated tool does under the hood, building your mental model of the desync condition. The “Invalid method SMUGGLED…” error response from the follow-up request is the definitive confirmation of the desync — the back-end tried to process “SMUGGLED” as an HTTP method name, proving the bytes were treated as a new request.

📸 Screenshot the error response confirming the smuggled bytes reached the back-end as a new request. Post to #day-21-smuggling on Discord.


TE.CL Attack — Front-End Uses Transfer-Encoding

In a TE.CL attack, the relationship is reversed: the front-end honours Transfer-Encoding and the back-end honours Content-Length. The attacker sends a request where the chunked body terminates early according to the chunks, but the Content-Length header specifies a larger body size. The front-end reads the chunks and forwards what it considers the complete chunked body. The back-end reads based on Content-Length and finds it has received fewer bytes than expected — it waits for more data, which arrives as the next user’s request.

TE.CL attacks are typically harder to trigger because they require the front-end to properly honour Transfer-Encoding while the back-end ignores it — a less common configuration. They are also more dangerous in testing because the malformed state left on the back-end connection can affect subsequent users unpredictably. PortSwigger recommends always testing in a private browser tab and pausing briefly between repeated smuggling attempts to avoid poisoning real user sessions during authorised testing.

securityelites.com
TE.CL Attack Payload Structure
REQUEST SENT
POST / HTTP/1.1
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

Front-end reads chunks: 8-byte chunk + terminator

BACK-END PARSES
Uses Content-Length: 3
Reads: “8\r\n” (3 bytes) = body

Remaining: “SMUGGLED\r\n0\r\n\r\n
← buffered as start of next request

Back-end treats “SMUGGLED” as new request

📸 TE.CL payload structure. The front-end processes the Transfer-Encoding chunks correctly and forwards the full body. The back-end reads only Content-Length: 3 bytes (“8\r\n”) and considers the request complete — everything after those 3 bytes remains in the buffer and is prepended to the next incoming request. The discrepancy between which 3 bytes the back-end considers the body vs what the front-end sent is the core of the TE.CL desync.


Detection with Burp HTTP Request Smuggler

Manual detection of request smuggling requires careful timing analysis and careful handling of connection state — mistakes can affect other users on the same back-end connection. The HTTP Request Smuggler extension by James Kettle automates this detection safely. It sends a series of probe requests designed to elicit differential responses or timeouts that indicate a desync condition, without sending payloads that would actually poison the connection state for other users.

After installation via BApp Store, right-clicking any request in Burp History and selecting Extensions > HTTP Request Smuggler > Launch starts the automated scan. The extension tests for CL.TE, TE.CL, and HTTP/2 downgrade variants. Results appear in the extension’s output window with severity assessments. Confirmed vulnerabilities are flagged for manual verification — the extension confirms the condition but you must manually verify the actual impact through a controlled exploit attempt.

securityelites.com
Burp HTTP Request Smuggler — Detection Output
[CRITICAL] CL.TE detected on POST /
Host: target.example.com · Response time: 10,003ms (timeout)
Probe: Content-Length/Transfer-Encoding ambiguity with timing oracle
Recommendation: Manual verification required — do not automate exploitation

[INFO] TE.TE obfuscation variant tested
Various Transfer-Encoding obfuscation patterns — no timeout response
Result: Not detected with tested variants

[INFO] HTTP/2 downgrade probe — no h2c upgrade negotiation
Server does not appear to downgrade HTTP/2 to HTTP/1.1 in this path

📸 HTTP Request Smuggler extension output showing a CL.TE detection via timing oracle — the 10-second timeout response confirms the back-end is waiting for more data because the desync condition left it in an incomplete request state. The extension distinguishes confirmed detections from negative results across CL.TE, TE.CL, TE.TE obfuscation, and HTTP/2 downgrade variants. CRITICAL findings require manual verification before reporting.


High-Impact Exploitation Scenarios

Access control bypass. If the front-end enforces path-based access controls — blocking requests to /admin or /internal based on the request URL — a smuggled request can target these paths without going through the front-end check. The outer request targets a public endpoint (passing the front-end check). The smuggled inner request targets the restricted endpoint and is forwarded directly by the back-end as if it came from the trusted front-end. Combined with back-end IP allowlisting that trusts the front-end’s IP, this bypass can provide full access to admin interfaces.

Credential capture. In environments where multiple users share back-end connection pools, a specifically crafted smuggled request can cause the next user’s incoming request to be appended to yours. If you control an endpoint that reflects input — even just a parameter that appears in an error message — you can receive the next user’s complete HTTP request including their POST body, cookies, and any credentials or CSRF tokens they submitted. This is one of the highest-severity exploitation paths: it turns a smuggling vulnerability into credential theft from other live users.

Cache poisoning at scale. If the application uses a caching layer and the smuggled request causes a cacheable response to be stored under the wrong cache key, subsequent users requesting the legitimate URL receive the attacker’s poisoned response. This scales the impact from one affected user to every user who requests the cached URL — turning a single smuggling request into a widespread XSS or open redirect affecting all visitors.

Bug Bounty Reporting Tip: Request smuggling with credential capture or access control bypass is almost always P1 Critical on any major programme. When writing the report, calculate the realistic blast radius: on a programme with 100,000 daily active users sharing back-end connection pools, even a low-probability credential capture affects a potentially large user population over time. Always quantify the worst-case impact across all users, not just the controlled test case you demonstrated.

⚡ EXERCISE 2 — BURP SUITE REPEATER (20 MIN)
Manual CL.TE Exploit — Access Control Bypass via Smuggled Request

⏱️ 20 minutes · Burp Suite + PortSwigger lab

Step 1: Open PortSwigger lab
Search: “HTTP request smuggling to bypass front-end security controls”
Access the lab — it has a /admin path blocked by the front-end proxy

Step 2: Confirm the front-end block
Try to directly browse to /admin — observe the 403 “Not an admin” response
This confirms the front-end is enforcing the restriction

Step 3: Build the bypass smuggling request in Burp Repeater
New request with these headers:
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: [calculate]
Transfer-Encoding: chunked

[chunk size hex]
[normal POST data]
0

GET /admin HTTP/1.1
Host: localhost
Content-Length: 10

x=

Step 4: Critical Repeater settings
– Uncheck “Update Content-Length” in Repeater
– Go to Repeater > Inspector (or right panel) > ensure HTTP/1 not HTTP/2

Step 5: Send the smuggling request, then immediately send a normal GET /
Observe: does the second response return admin content?
If yes: the smuggled GET /admin reached the back-end as a trusted request

Document: exact Content-Length, chunk sizes, and response difference.

✅ What you just learned: The access control bypass demonstrates why request smuggling is so dangerous — the front-end’s URL-based access control is completely circumvented. The front-end sees a POST to /, which is allowed. The back-end processes the outer POST and also queues the smuggled GET /admin. When the follow-up request arrives, the back-end has an unpaired GET /admin waiting and processes it with no front-end check. The localhost Host header is the critical detail: back-ends often apply different (more permissive) rules to requests they perceive as coming from localhost or internal IP addresses.

📸 Screenshot the admin response returned via the smuggled request. Post to #day-21-smuggling on Discord.


HTTP/2 Downgrade Smuggling — 2026 Variants

HTTP/2 was expected to eliminate request smuggling because it uses binary framing rather than header-based length determination. It did not. A class of vulnerabilities discovered in 2020–2021 (H2.CL and H2.TE) exploits the architecture where the front-end accepts HTTP/2 connections but downgrades to HTTP/1.1 when forwarding to the back-end. The front-end rewrites the HTTP/2 binary frames into HTTP/1.1 text headers for the back-end — and in doing so, may faithfully include Content-Length or Transfer-Encoding headers that were in the HTTP/2 pseudo-headers, creating a desync at the HTTP/1.1 back-end level.

H2.CL attacks inject a Content-Length header via HTTP/2 that conflicts with the actual HTTP/2 frame length. When downgraded, the resulting HTTP/1.1 request has an ambiguous body length that the back-end resolves differently from the front-end. H2.TE attacks inject a Transfer-Encoding: chunked header into an HTTP/2 request — something the HTTP/2 spec explicitly forbids but many front-ends will still faithfully include in the downgraded HTTP/1.1 forwarded request. Both variants remain prevalent in 2026 and are tested by the HTTP Request Smuggler extension.

🌐 EXERCISE 3 — PORTSWIGGER ADVANCED LAB (20 MIN)
HTTP Request Smuggling — Credential Capture via Connection Poisoning

⏱️ 20 minutes · PortSwigger Web Security Academy

Step 1: Find the credential capture lab
Search: “Exploiting HTTP request smuggling to capture other users’ requests”
Access the lab. Read the brief — it has a comment function that reflects input.

Step 2: Understand the attack chain
The goal: craft a smuggled request that causes the NEXT user’s request
to be appended to yours and then reflected in the comment function.
You receive their POST body including credentials.

Step 3: Build the payload
Outer request: POST to the comment endpoint
Inner smuggled request: another POST to the comment endpoint
but with only a partial body — the remaining bytes come from
the next user’s request being appended

Content-Length of inner request: deliberately large (e.g. 800)
This causes the back-end to wait for 800 bytes
The next user’s request provides those bytes

Step 4: Send the payload and wait
After sending the smuggling request:
Check the comments section
Does a new comment appear containing HTTP request headers?
Does it contain another user’s session cookie or credentials?

Step 5: Extract the captured data
If successful — note what was captured: session cookie, credentials
How would you use this to take over the victim’s account?
Document the full attack chain for your report.

✅ What you just learned: The credential capture exercise demonstrates the most severe impact of request smuggling — actively capturing other users’ live session tokens or credentials without any interaction from them. The mechanism is subtle: by leaving an incompletely-read POST body on the back-end connection, any subsequent request from another user gets appended to the attacker’s partial request, and the reflection endpoint returns both — exposing the victim’s complete request including cookies. In a live environment this would require timing (multiple requests to catch a real user’s traffic), but the principle is identical.

📸 Screenshot the captured victim request in the comments, showing the session cookie or credentials. Post to #day-21-smuggling on Discord. Tag #day21complete


Reporting and Remediation

HTTP request smuggling reports require more technical detail than most vulnerability classes because the mechanism is non-obvious to developers who haven’t encountered it. A strong report includes: the exact desync type (CL.TE or TE.CL), the specific request pair (outer request + smuggled inner request with exact header values), evidence of the desync (timing oracle result or error response), the demonstrated impact (access control bypass, credential capture, or cache poisoning), and the remediation recommendation. Always note whether HTTP/2 is available on the target — H2 end-to-end is the most complete fix.

Remediation options for developers: enforce HTTP/2 end-to-end eliminating the HTTP/1.1 desync entirely; reject or normalise requests containing both Content-Length and Transfer-Encoding headers at the front-end; disable HTTP/1.1 keep-alive between the front-end and back-end (forces new connections for each request, eliminating connection poisoning); configure the back-end to reject ambiguous requests with a 400 rather than attempting to parse them.

⚠️ Safety Warning — Testing in Shared Environments: Request smuggling in a production environment can poison other real users’ connections, exposing their session tokens or causing their requests to error. Only test on targets within scope, always use a fresh browser tab to isolate your connection, send timing tests in pairs with a delay between them, and be prepared to immediately stop testing if you observe evidence that real user traffic is being affected. Many programmes explicitly require that request smuggling tests be reported at detection stage without active exploitation if a production environment is involved.

🧠 QUICK CHECK — HTTP Request Smuggling

You confirm a CL.TE desync condition on an application using Burp’s HTTP Request Smuggler extension. The front-end blocks all requests to /admin with a 403. To confirm access control bypass impact, you craft a smuggling payload with a smuggled GET /admin request using Host: localhost. The follow-up request returns the admin panel. What is the correct severity for this bug bounty report?



📋 HTTP Request Smuggling Quick Reference — Day 21

CL.TE attackFront-end uses Content-Length, back-end uses Transfer-Encoding — most common variant
TE.CL attackFront-end uses Transfer-Encoding, back-end uses Content-Length — less common, higher impact
DetectionBurp HTTP Request Smuggler extension (BApp Store) — automated timing oracle across all variants
Impact 1: Access bypassSmuggled request targets /admin with Host: localhost — bypasses front-end URL ACL
Impact 2: Credential capturePartial inner request poisons connection — next user’s request appended and reflected
FixHTTP/2 end-to-end; reject ambiguous CL+TE requests; disable HTTP/1.1 keep-alive between tiers

🏆 Mark Day 21 Complete — HTTP Request Smuggling

Request smuggling demonstrates how protocol-level ambiguity creates application-level impact across every user. Day 22 covers GraphQL — a completely different attack surface with its own class of introspection, injection, and broken authorisation vulnerabilities.


❓ Frequently Asked Questions — HTTP Request Smuggling 2026

What is HTTP request smuggling?
A vulnerability where front-end and back-end servers parse HTTP request boundaries differently, allowing an attacker to embed a hidden second request inside the body of the first. The hidden request bypasses front-end security controls and is processed by the back-end, enabling access control bypass, credential capture, and cache poisoning.
What is the difference between CL.TE and TE.CL?
CL.TE: front-end uses Content-Length, back-end uses Transfer-Encoding. The attacker’s body includes a Transfer-Encoding chunk terminator early — the back-end stops there, treating leftover bytes as a new request. TE.CL: front-end uses Transfer-Encoding, back-end uses Content-Length. The attacker’s chunked body terminates early — the back-end waits for more bytes, which arrive as the next user’s request.
How do you detect HTTP request smuggling safely?
Install Burp Suite’s HTTP Request Smuggler extension (BApp Store). Right-click any request > Extensions > HTTP Request Smuggler > Launch. It runs automated timing oracle and differential response tests safely. For manual detection, use the timing test: a CL.TE probe that causes a back-end timeout confirms the desync without poisoning real user connections.
What is the impact of HTTP request smuggling?
Access control bypass (smuggled requests reach admin endpoints blocked by front-end), credential capture (poisoning connections to receive other users’ session tokens), cache poisoning (serving attacker’s response from CDN to all users), XSS through reflected content in smuggled responses. Consistently one of the highest-paying bug bounty vulnerability classes.
How do you fix HTTP request smuggling?
Best fix: enforce HTTP/2 end-to-end — eliminates the CL/TE ambiguity entirely. Also: reject requests containing both Content-Length and Transfer-Encoding; normalise ambiguous requests at front-end; disable HTTP/1.1 keep-alive between tiers. Each option trades off compatibility vs security.
Is HTTP request smuggling still relevant in 2026?
Very much so. Most applications still run HTTP/1.1 between CDN and origin. HTTP/2 downgrade variants (H2.CL, H2.TE) are widespread. PortSwigger’s 2023 research found request smuggling in major CDN providers. It remains one of the highest-paying vulnerability classes on HackerOne and Bugcrowd.
← Previous

Day 20: Clickjacking Bug Bounty

Next →

Day 22: GraphQL Bug Bounty

📚 Further Reading

ME
Mr Elite
Owner, SecurityElites.com
Request smuggling was the vulnerability that most changed how I think about architecture security. Before understanding it, I thought of web application security as the application code plus its direct inputs. After James Kettle’s 2019 research, I realised that the infrastructure between the user and the application — the load balancers, CDNs, and reverse proxies — creates its own attack surface that has nothing to do with the application code itself. The application can be perfectly coded and still be exploitable because of how the infrastructure components communicate with each other. That architectural perspective changed my approach to every pentest I’ve done since.

Join free to earn XP for reading this article Track your progress, build streaks and compete on the leaderboard.
Join Free

Leave a Comment

Your email address will not be published. Required fields are marked *