Challenge Overview#
- Challenge name: Exploiting HTTP request smuggling to reveal front-end request rewriting
- Category: HTTP Request Smuggling
- Level: Practitioner
- Objective: Smuggle a request to the back-end server that reveals the header that is added by the front-end server. Then smuggle a request to the back-end server that includes the added header, accesses the admin panel, and deletes the user
carlos.
1. Fundamental Concepts#
In contemporary cloud and enterprise architectures, edge reverse proxies (such as Nginx, Cloudflare, HAProxy, and AWS Application Load Balancers) do not merely route traffic passively. They frequently rewrite incoming HTTP requests before forwarding them to upstream backend servers. This rewriting process standardizes headers, terminates TLS, and injects critical metadata concerning the client’s identity and connection state.
1.1. Front-End Request Rewriting & The Hidden Header Problem#
- Client Identification Headers: To inform internal applications of the true client IP address, front-end proxies append custom headers (e.g.,
X-Forwarded-For,X-Real-IP, or proprietary headers likeX-Custom-IP-Authorization). - Implicit Trust & Authorization: Back-end application servers operate under an implicit trust model, assuming that internal network traffic has already been vetted by the perimeter proxy. The back-end inspects these injected headers to enforce IP-based access control, allowing administrative actions only when the header specifies a trusted loopback address (
127.0.0.1). - The Dual Access Barrier: An external attacker faces two fundamental obstacles:
- The exact header name used by the proxy is unknown and often randomly generated or proprietary.
- If an attacker attempts to inject the header directly in an external request, the front-end proxy overwrites or strips it with the attacker’s public IP address before forwarding.
1.2. The CL.TE Desynchronization Mechanism#
- Protocol Discrepancy: Under HTTP/1.1 (RFC 7230), message body boundaries are defined by
Content-Length(fixed byte count) orTransfer-Encoding: chunked(hex-encoded chunks terminated by0\r\n\r\n). - Desynchronization Model: In a CL.TE vulnerability, the Front-end processes requests using
Content-Length, while the Back-end parses usingTransfer-Encoding: chunked. By placing a chunked terminator (0\r\n\r\n) inside the body, the back-end concludes Request 1 early, leaving the remaining payload in the TCP receive buffer to be prepended to the subsequent request.
The Header Reflection Paradigm: By smuggling a partial POST request targeting an input-reflecting endpoint (such as a search feature) with an oversized Content-Length, the back-end is forced to treat the next legitimate incoming request—including all headers injected during front-end rewriting—as the body parameter. When the back-end renders the search results, the proxy’s internal secret headers are reflected directly in the HTML response.
2. Attack Model & Architecture#
The attack model operates in two distinct phases: Phase 1 exploits request smuggling to reveal the secret front-end rewriting header, and Phase 2 leverages the discovered header to forge local administrative authorization.
| |
2.1. Attack Data Flow Analysis#
- Step 1 - Reflection Gadget Discovery: The attacker discovers an endpoint that echoes user input. In this application, submitting
POST /with parametersearch=123reflects'123'directly within<h1>search headers. - Step 2 - Vulnerability Confirmation: Using both timing delay techniques (
Content-Length: 3causing timeout) and differential response testing (smuggling'G'to trigger GPOST404 Not Found), the application is confirmed vulnerable to CL.TE request smuggling. - Step 3 - Header Leak Trapping: A partial request is smuggled targeting the search endpoint:
POST /withContent-Length: 300and a trailing body parameter'search='. The outer request terminates at0\r\n\r\n, leaving the search request pending in the back-end buffer. - Step 4 - Parameter Absorption & Information Disclosure: When the subsequent request arrives, the front-end injects its internal client IP header. The back-end, waiting for 300 bytes of search body data, consumes the entire head of the incoming request into the search parameter, reflecting
X-Gkxtgp-Ip: 116.193.75.6in the HTML response. - Step 5 - Administrative Authorization Bypass: With the proprietary header identified, the attacker crafts a smuggled request to
/admincontainingX-Gkxtgp-Ip: 127.0.0.1. Because the payload resides inside the HTTP body of the outer request, the front-end proxy does not inspect or overwrite it. The back-end executes the request under local trust, revealing the user management panel. - Step 6 - Privileged Execution: The smuggled path is updated to
POST /admin/delete?username=carlos HTTP/1.1withX-Gkxtgp-Ip: 127.0.0.1, executing the deletion and returning anHTTP 302 Foundredirect.
2.2. Root Causes#
- HTTP Parser Discrepancy: The edge proxy and origin server disagree on request framing boundaries under RFC 7230, enabling transport-layer desynchronization.
- Insecure Perimeter Header Trust: The back-end relies exclusively on an unauthenticated HTTP header (
X-Gkxtgp-Ip) to authorize administrative actions, lacking cryptographic session validation. - Input Reflection Primitive: The application reflects unvalidated POST parameters directly into server-rendered HTML, providing an oracle to extract piped socket data.
3. Vulnerability Exploitation#
The exploitation process was executed through a structured, multi-stage methodology utilizing Burp Suite Repeater.
3.1. Baseline Connectivity & Protocol Downgrade#
An initial baseline request to '/' was captured in Burp Suite Repeater. The target environment negotiated HTTP/2 by default, returning an HTTP/2 200 OK response with public blog posts.

To test for HTTP/1.1 message boundary parsing discrepancies, the protocol was downgraded to HTTP/1.1, and the Update Content-Length setting was unchecked in Burp Repeater.
3.2. Probing & Confirming CL.TE Desynchronization#
To confirm CL.TE vulnerability, a timing probe was submitted with Content-Length: 3 and Transfer-Encoding: chunked:
| |
The front-end forwarded only the first 3 bytes (1\r\n). The back-end, processing the request as chunked, hung waiting for the chunk data and terminator, ultimately triggering an HTTP/1.1 500 Internal Server Error: "Communication timed out".

Next, a differential response probe was transmitted appending a single 'G' character after the terminating chunk (Content-Length: 12):
| |
The initial transmission completed normally with an HTTP/1.1 200 OK response:

Sending an immediate follow-up request returned an HTTP/1.1 404 Not Found response containing JSON "Not Found". The smuggled 'G' byte prepended to the incoming request line to form GPOST /, decisively confirming CL.TE desynchronization.

3.3. Identifying the Input Reflection Gadget#
The blog search function was evaluated by dispatching a POST / request with parameter search=123. The response rendered 0 search results for '123', proving that inputs supplied to the search parameter are echoed back into the response body.

3.4. Trapping & Revealing Front-End Rewritten Headers#
A header extraction payload was constructed. The smuggled request targeted POST / with an intentionally inflated Content-Length: 300, terminating with an open search= parameter:
| |
The first request primed the back-end socket buffer while returning an HTTP/1.1 200 OK response:

When the follow-up request was dispatched, the front-end rewrote it with internal metadata. The back-end absorbed the first 293 bytes of the incoming request into the search parameter. The HTML response reflected the front-end’s secret internal header: X-Gkxtgp-Ip: 116.193.75.6.

3.5. Bypassing Administrative Controls#
With the header identified as X-Gkxtgp-Ip, an administrative access payload was crafted. The smuggled request targeted POST /admin, injecting X-Gkxtgp-Ip: 127.0.0.1, with Content-Length: 5 and body 'tuki' to cleanly isolate incoming requests:
| |
The initial transmission primed the administrative payload into the back-end socket buffer:

Transmitting the second request triggered the execution of POST /admin under local loopback trust. The back-end rendered the Admin Panel, displaying the user list and exposing the deletion endpoint: /admin/delete?username=carlos.

3.6. Executing User Deletion & Lab Verification#
The smuggled request line was modified to invoke the deletion routine: POST /admin/delete?username=carlos HTTP/1.1 (outer Content-Length: 154):
| |
The first transmission primed the deletion request into the socket buffer:

The second transmission executed the deletion. The back-end responded with an HTTP/1.1 302 Found redirecting to /admin, confirming Carlos was successfully deleted:

The PortSwigger Web Security Academy confirmation banner verified successful completion of the lab:

4. Remediation & Prevention#
Remediating request smuggling and preventing unauthorized access through header manipulation requires defense-in-depth across the network, proxy, and application layers.
4.1. End-to-End HTTP/2 Architecture#
- Unified Binary Framing: Enforce HTTP/2 or HTTP/3 consistently from the client edge to the reverse proxy and through to internal application servers. HTTP/2 eliminates text-based delimitation parsing ambiguities by establishing frame lengths at the binary framing layer.
- Disable Protocol Downgrading: Avoid protocol downgrading at reverse proxies. Translating incoming HTTP/2 binary frames into HTTP/1.1 cleartext streams when forwarding upstream introduces message framing discrepancies that enable request smuggling.
4.2. Reverse Proxy Hardening & Normalization#
- Ambiguous Framing Rejection: Configure reverse proxies (e.g., Nginx, HAProxy, Envoy) to reject any request containing both
Content-LengthandTransfer-Encodingheaders with an immediateHTTP 400 Bad Request. - Header Normalization: Strictly normalize HTTP/1.1 headers before proxying upstream. Strip obfuscated
Transfer-Encodingheaders and enforce RFC 7230 Section 3.3.3 compliance.
4.3. Application-Tier Defense-in-Depth#
- Zero-Trust Header Architecture: Never rely on client-controllable or proxy-injected headers (such as
X-Forwarded-Foror custom IP headers) for authorization decisions without cryptographically verifiable identities (e.g., mutual TLS or signed JWTs). - Native Application RBAC: Administrative endpoints must require cryptographic session authentication and enforce Role-Based Access Control (RBAC) directly inside application code, rather than delegating security to network boundary filters.
- Connection Pool Isolation: Avoid reusing persistent backend TCP connections across different client security boundaries, preventing queued smuggled request fragments from contaminating subsequent client sessions.
