Securing your Django app

from man-in-the-middle attacks

Ventsislav Tashev

 

👨‍💻 Software Developer  @ HackSoft

👨🏼‍🎓 Studying Informatics @ NBU

❤️ Python & Django

Man-in-the-middle (MITM)

domain.com

http://domain.com

http://domain.com

HTTP 200

domain.com

http://domain.com

http://domain.com

HTTP 200

domain.com

http://domain.com

http://domain.com

HTTP 200

HTTP                  HTTPS

301 Moved Permanently
# settings.py

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True

domain.com

http://domain.com

https://domain.com

HTTP 301

domain.com

http://domain.com

https://domain.com

HTTP 301

301 is not enough.

 
  • The redirect happens once the HTTP request reaches the server. The MITM attacker enters before that.

301 is not enough.

 
  • The redirect happens once the HTTP request reaches the server. The MITM attacker enters before that.
  • Even if the browser is caches this redirect, it has a max-age of several weeks/months.

301 is not enough.

 
  • The redirect happens once the HTTP request reaches the server. The MITM attacker enters before that.
  • Even if the browser is caches this redirect, it has a max-age of several weeks/months.
  • We all know the common fix for the "the site is not working" is "reset your browser cache". This automatically re-exposes the user for the MITM threat.

301 is not enough.

 

HSTS

HTTP Strict Transport Security

HTTP Strict Transport Security, or HSTS, is a way of telling the browser to load your site over HTTPS only.

HTTP Strict Transport Security, or HSTS, is a way of telling the browser to load your site over HTTPS only.

 

Once a browser has seen the header on a website, it will only make HTTPS requests to that website.

HSTS directives

HSTS directives

  • max-age instructs the browser how long it should load your domain with encrypted connection (in seconds).

HSTS directives

  • max-age instructs the browser how long it should load your domain with encrypted connection (in seconds).
  • includeSubDomains includes all subdomains of your domain.

HSTS directives

  • max-age instructs the browser how long it should load your domain with encrypted connection (in seconds).
  • includeSubDomains includes all subdomains of your domain.
  • preload tells browsers to store your domain in a database of known strict-only domains. It can only be set on top level domains like example.com. Browsers opening URL’s on HSTS-preloaded domains will never make MITM-able HTTP requests. Once this flag is set, you submit your domain to all browsers through Google’s preload service. After acceptance, the next versions of each browser will include your domain.

Django’s warning security.W004 even says:

 

… enabling HSTS carelessly can cause serious, irreversible problems

Django’s warning security.W004 even says:

 

… enabling HSTS carelessly can cause serious, irreversible problems

 

 

  • If you prematurely activate it, you will block users making legitimate HTTP requests. The browser will lock them out until you remove the header and the max-age seconds have passed.
# settings.py

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True

SECURE_HSTS_SECONDS = 31536000  # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True

domain.com

https://domain.com

HTTP 200

Check HSTS registry for domain.com

 

http(s)://domain.com

Flow

  1. User types domain.com in the browser
  2. Browser checks its HSTS registry to check whether the domain is present there:
    • If it is found -> resolve to https
    • Otherwise   -> fallback to http
  3. Once the schema is determined -> perform the request
  4. The request hits the Django web server:
    • If the request is non-encrypted (http) -> HTTP 301
    • If the request is encrypted (https)         -> HTTP 200
  5. Return response to the client
    • If Strict-Transport-Security header is present in the response - cache the domain in the HSTS registry

Comparison

 
HSTS 301 Redirect

Comparison

 
HSTS 301 Redirect
Designed for Security URL Redirection

Comparison

 
HSTS 301 Redirect
Designed for Security URL Redirection
Covers The entire domain A specific URL

Comparison

 
HSTS 301 Redirect
Designed for Security URL Redirection
Covers The entire domain A specific URL
Cache Separate Browser

Comparison

 
HSTS 301 Redirect
Designed for Security URL Redirection
Covers The entire domain A specific URL
Cache Separate Browser
Max-age Years Weeks/months

HSTS is not perfect.

 

HSTS is not perfect.

 

 

 

  • If the domain is not present in the HSTS registry, a single HTTP request should be made in order to cache the domain in order to perform HTTPS-only requests in the future.

 

HSTS is not perfect.

 

 

 

  • If the domain is not present in the HSTS registry, a single HTTP request should be made in order to cache the domain in order to perform HTTPS-only requests in the future.

  • HTTPS requests can still be decrypted by the attacker, but he needs to be a lot more sophisticated in order to achieve that.

 

HSTS is not perfect.

 

HSTS is not perfect.

 

 

 

 

But it is a big security improvement!

 

Resources

Django MITM

By Ventsislav Tashev

Django MITM

How to prevent man-in-the-middle attacks in your Django application

  • 933