Request Smuggling on Docker
How Request Smuggling Manifests in Docker
Request smuggling exploits differences in how front‑end and back‑end components interpret the HTTP message boundaries, most commonly the clash between Content‑Length and Transfer‑Encoding headers. In a Docker‑based architecture this often appears when a containerized reverse proxy (e.g., nginx, Traefik, or Envoy) sits in front of an application container. If the proxy and the application disagree on where one request ends and the next begins, an attacker can inject a second request that is interpreted as part of the first, bypassing authentication, rate limits, or WAF rules.
Typical Docker‑specific patterns include:
- Sidecar proxy pattern: A Docker Compose file defines a
webservice (nginx) and anapiservice (Node.js/Python). The nginx container forwards traffic tohttp://api:8080. If nginx is configured to pass through the rawTransfer‑Encoding: chunkedheader while the backend treats the body as length‑based, a crafted request like:
POST /api/data HTTP/1.1
Host: example.com
Content-Length: 13
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: example.com
may be seen by nginx as a single request (due to the chunked encoding) but the backend may finish reading after the Content‑Length of 13 bytes, leaving the second GET /admin in the buffer to be processed as the next request—potentially without any authentication headers.
Another Docker‑specific vector is the use of docker run --network host or publishing ports with -p 80:80 on the same host where multiple containers listen on different ports. A misconfigured EXPOSE or accidental binding of the backend directly to the host interface can allow an attacker to bypass the front‑end proxy entirely, turning a smuggling attempt into a direct request to the backend.
Finally, Docker’s built‑in healthcheck endpoint (often exposed on /_health) can be abused if the healthcheck service does not enforce strict HTTP parsing; a smuggling payload that lands on the healthcheck port may trigger internal actions (e.g., restart loops) that are not visible through the main API.
Docker‑Specific Detection
Detecting request smuggling in a Dockerized environment requires observing inconsistencies between the front‑end proxy and the backend application. middleBrick performs unauthenticated black‑box checks that map directly to these inconsistencies:
- It sends a series of crafted requests that vary
Content‑LengthandTransfer‑Encodingheaders, looking for cases where the response status code or body differs from expectations. - It checks for delayed responses that indicate the second request was processed out‑of‑band (a classic sign of desync).
- It probes for exposed internal ports (e.g., healthcheck, debug endpoints) that might be reachable only when the front‑end proxy mis‑interprets message boundaries.
To run a scan against a Docker‑deployed API, you can use the middleBrick CLI:
middlebrick scan https://api.example.com
The output includes a finding such as:
| Check | Severity | Description |
|---|---|---|
| Request Smuggling (CL‑TE) | High | Front‑end proxy accepted Transfer‑Encoding: chunked while backend used Content‑Length, allowing a second request to be processed without authentication. |
| Exposed Internal Port | Medium | Port 9229 (Node.js debug) reachable via the host network; could be reached after a smuggling desync. |