Django's SuspiciousOperation Invalid HTTP_HOST header

If you're using Nginx to forward requests to Django running on Gunicorn/Apache/uWSGI, you can use the following to block bad requests. Thanks to @PaulM for the suggestion.

upstream app_server {
    server unix:/tmp/gunicorn_mydomain.com.sock fail_timeout=0;
}

server {

    ...

    ## Deny illegal Host headers
    if ($host !~* ^(mydomain.com|www.mydomain.com)$ ) {
        return 444;
    }

    location  / {
        proxy_pass               http://app_server;
        ...
    }

}

If your ALLOWED_HOSTS is set correctly, then it is possible someone is probing your site for the vulnerability by spoofing the header.

There is discussion right now by the Django developers to change this from a 500 internal server error to a 400 response. See this ticket.


When using Nginx you could set up you servers in a way only requests to the hosts you want get to Django in the first place. That should give you no SuspiciousOperation errors anymore.

server {
    # default server

    listen 80;
    server_name _ default;

    return 444;
}
server {
    # redirects

    listen 80;
    server_name example.com old.stuff.example.com;

    return 301 http://www.example.com$request_uri;
}
server {
    # app

    listen 80;
    server_name www.example.com; # only hosts in ALLOWED_HOSTS here

    location  / {
        # ...
    }
    # ... your config/proxy stuff
}

Tags:

Django