A website served via HTTP is vulnerable to Man In The Middle (MITM) attacks: a hacker can get between your browser and the server responding to the browser’s requests. The response or request can be amended for malicious intent. A Man could get In The Middle after an unsuspecting user connects to a nefarious network e.g. when joining a cafe’s wifi or after a cheeky connection to a neighbor’s unprotected network: these may be honey traps.
And this is the outcome:
This can be avoided by serving exclusively on HTTPS as the content will no longer be in plain text for the MITM to read and mutate. Django supports this via
SECURE_SSL_REDIRECT – so Django will redirect any HTTP request to HTTPS. However, this is an incomplete solution:
- a MITM could intercepts the “redirect to HTTPS” response and change it.
- a MITM could upgrade your HTTP request to HTTPS: the user has a HTTP request that terminates at the MITM and the MITM upgrades the request to HTTPS: data would be plainly readable by the bad actor.
There is a solution to that in HTTP Strict Transport Security protection: the browser blocks HTTP requests to your website and instead use HTTPS.
Django facilitates that via the
SECURE_HSTS_SECONDS setting. When first setting the value it’s worth using a small value like 3600 (1 hour) to check it works as expected, as once the browser sees the HSTS header it will respect it until the specified time is met, meaning if your website has misconfigured HTTPS certificates then you cannot rollback to HTTP while you fix it.
It’s also advisable to set
SECURE_HSTS_INCLUDE_SUBDOMAINS so the browser uses HTST for all subdomains and not just the current one. It would be a shame to protect http://example.com but not http://www.example.com.
So concretely the following change will help protect your Django website against Man In The Middle attacks:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', ... ] SECURE_HSTS_SECONDS = 3600 SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_ settings required
django.middleware.security.SecurityMiddleware to be present in
MIDDLEWARE otherwise they will do nothing.
Does your website have security vulnerabilities?
Over time it’s easy for security vulnerabilities and tech debt to slip into your codebase. I can check for Man In The Middle vulnerability and many others for for free you at django.doctor. I’m a Django code improvement bot:
If you would prefer security holes not make it into your codebase, I also review pull requests: