Django, Nginx, Invalid HTTP_HOST header

From time to time, I get an email from my Django server complaining about “Invalid HTTP_HOST” and looking like some hacker is trying to mess with my gunicorn sock. Here is the relevant part of the email:

Invalid HTTP_HOST header: u'/webapps/MY_SITE/run/gunicorn.sock:'. The domain name provided is not valid according to RFC 1034/1035.

Request repr():
<WSGIRequest
path:/arlo/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{},
META:{'HTTP_ACCEPT': '*/*',
 'HTTP_CONNECTION': 'close',
 'HTTP_USER_AGENT': 'masscan/1.0 (https://github.com/robertdavidgraham/masscan)',
 'HTTP_X_FORWARDED_FOR': '120.88.152.6',
 'PATH_INFO': u'/arlo/',
 'QUERY_STRING': '',
 'RAW_URI': '/arlo/',
 'REMOTE_ADDR': '',
 'REQUEST_METHOD': 'GET',
 'SCRIPT_NAME': u'',
 'SERVER_NAME': '/webapps/MY_SITE/run/gunicorn.sock',
 'SERVER_PORT': '',
 'SERVER_PROTOCOL': 'HTTP/1.0',
 'SERVER_SOFTWARE': 'gunicorn/19.6.0',

How is this hacker getting the path to my gunicorn sock?

It turns out this is happening because I am using $http_host in my nginx config file:

upstream wsgi_server {
 server unix:/webapps/MY_SITE/run/gunicorn.sock fail_timeout=0;
}

server {
 listen 80;
 server_name MY_DOMAIN_NAME;

 location / {
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
     if (!-f $request_filename) {
        proxy_pass http://wsgi_server;
        break;
     }
 }

when a request is made to the server and the HTTP Host is empty, nginx sets the HTTP host to the gunicorn sock.

I can generate this error using curl:

curl -H "HOST:" MY_DOMAIN_NAME -0 -v

This sends a request without a HTTP Host. The -0 causes curl to use HTTP version 1.0. If you do not set this, the request will use HTTP version 1.1, which will cause the request to be rejected immediately and not generate the error.

The solution is to replace $http_host with $host (as pointed out on Stackoverflow). When HTTP Host is missing, $host will take on the value of the “server_name” directive. This is a valid domain name and is the one that should be used.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s