Report this

What is the reason for this report?

Invalid Host Header '/run/gunicorn.sock'

Posted on September 12, 2020
mspe

By mspe

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' 'https://www.example.com'

*   Trying IP_ADDRESS:443...
* Connected to www.example.com (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: CN=example.com
*  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
<
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>
* Connection #0 to host example.com left intact```

Here’s my Nginx conf:

server {
        server_name www.example.com "";

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

        if ($host !~* ^(example.com|www.example.com)$){
            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 = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80;
        server_name www.example.com "";
    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?



This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

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.

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! Regards, Bobby

Heya,

here is more information on this topic in hopes that someone might find it helpful

The cURL request you’re performing seems unusual since it includes the Unix socket in the ‘Host’ header. Typically, the ‘Host’ header should contain the domain name, not a path to a Unix socket. The error “400 Bad Request” from Nginx is appropriate because the ‘Host’ header value is invalid for an HTTP request.

Your Nginx configuration is generally correct for serving a site via Gunicorn using a Unix socket, but let’s address your concerns:

1. Handling the ‘Host’ Header

The ‘Host’ header is expected to be a domain name, not a file path. If you’re receiving requests with invalid ‘Host’ headers, you can tighten your Nginx configuration to handle these better.

Your current configuration has this check:

if ($host !~* ^(example.com|www.example.com)$){
    return 444;
}

This is good for rejecting requests with unexpected ‘Host’ values. However, the if directive in Nginx is generally discouraged due to unpredictable behavior. Instead, you can rely on server_name and default server blocks to handle unrecognized domains:

server {
    listen 80 default_server;
    listen 443 ssl http2 default_server;
    server_name _;
    return 444;
}

This configuration will drop requests that don’t match any known server block.

2. Concerns About Security

The 400 errors you’re seeing in your logs for requests with an invalid ‘Host’ header are not necessarily indicative of a security issue. It’s common for web servers to receive malformed or malicious requests. As long as your server is correctly rejecting these requests (as it seems to be), this behavior is part of normal internet “background noise.”

However, ensure you follow security best practices:

  • Keep Nginx and all server software up to date.
  • Regularly review your Nginx logs for any unusual patterns that might indicate more targeted attacks.
  • Implement firewalls and rate-limiting where appropriate.
  • Consider using a Web Application Firewall (WAF) if you’re concerned about application-level attacks.

3. Testing Your Configuration

For testing, you can make a more standard cURL request, ensuring the ‘Host’ header is a domain, not a socket path:

curl --verbose -k https://www.example.com

4. SSL Certificate Configuration

Ensure your SSL certificates are correctly set up for HTTPS connections. Since you’re using Certbot, it should handle the configuration and renewal of these certificates.

Conclusion

Your Nginx setup appears to be generally fine, but it’s always good to remain vigilant and review your configurations and logs regularly. The errors you’re seeing are likely normal and not a cause for concern as long as your server responds to them appropriately.

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.