Invalid Host Header '/run/gunicorn.sock'

Posted September 12, 2020 1.2k views

Recently I’ve noticed some errors in relation to the above which are causing concern to whether actionable data is being retrieved.

Here’s what I get on a cURL:

$ curl --verbose -k --header 'Host: /run/gunicorn.sock' ''

*   Trying IP_ADDRESS:443...
* Connected to (IP_ADDRESS) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN, server accepted to use h2
* Server certificate:
*  subject:
*  start date: Sep  2 23:25:50 2020 GMT
*  expire date: Dec  1 23:25:50 2020 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x66e0f0)
> GET / HTTP/2
> Host: /run/gunicorn.sock
> user-agent: curl/7.71.1
> accept: */*
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 400
< server: nginx/1.16.1
< date: Sat, 12 Sep 2020 14:09:38 GMT
< content-type: text/html
< content-length: 157
<head><title>400 Bad Request</title></head>
<center><h1>400 Bad Request</h1></center>
* Connection #0 to host left intact```

Here’s my Nginx conf:

server {
        server_name "";

        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
                root /home/username/;

        if ($host !~* ^(|$){
            return 444;

        location / {
                include proxy_params;
                proxy_set_header Host $host;
                proxy_pass http://unix:/run/gunicorn.sock;

    listen 443 ssl http2;
    # *Cerbot managed files*

server {
    if ($host = {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80;
        server_name "";
    return 404; # managed by Certbot

I’ve managed to get it to reject the majority of these type of requests (where host headers are IP addresses or words) but it seems that this one keeps getting through. Is there any additional information / fix for these type of attacks and whether I should be concerned to a genuine security issue?

edited by bobbyiliev

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Submit an Answer
1 answer

Hi there @mspe,

As /run/gunicorn.sock is not really a valid host, the request is not really being handled and it is not reaching the Nginx server block, so I believe that this is not really a security issue.

What I would usually do, is to set up a default Nginx server block which drops any request that do not match my server block hosts:

server {
    listen 80 default_server;
    return 444;

Though this would still result in a 400 Bad Request error if you pass an invalid host in the request header.

Hope that this helps!

  • Hi @bobbyiliev

    Thanks for the response, I probably should of mentioned that the nginx configuration is /etc/nginx/sites-enabled/mydomain which when I put that server block in that file it says there are conflicts. Is this because of /etc/nginx/sites-enabled/default? Would listen 80; server_name; return 404; in my config file not do achieve this result? If there’s no actionable security issue and the patch will still return the same result then it seems redundant looking for a fix.

    Just as the cURL requests to & closed to connections but leaves it intact.

    Many Thanks,

    • Hey there Matt,

      Yes indeed, I believe that you are absolutely right. Having the if condition in your server block would do the same.

      As you already have a default server block, there is no need to use the server block that I’ve shared.