HTTPS and HSTS on Apache/mod_wsgi and Django

2019-05-13 17:41发布

问题:

I'm setting up site-wide HTTPS for my Django 1.8 project. I am not experienced in web security.

I'm setting up HTTP to HTTPS redirect and HSTS.

Right now, I was configuring this on my Apache/mod_wsgi Web Server (I'm using a PaaS so I configure it through the .htaccess file on the WSGI root):

wsgi/.htaccess

# Redirect HTTP to HTTPS

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

# Add HSTS header
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"

# Deny rendering inside an iframe
Header always set X-Frame-Options DENY

As per the Django official docs SSL recommendations, I'm securing the cookies in my production settings:

settings/prod.py

...
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
...

Note: I'm not setting SECURE_PROXY_SSL_HEADER = (“HTTP_X_FORWARDED_PROTO”, “https”) yet, because I'm not sure yet if the PaaS is proxying and stripping this header between the proxy and the web container.

Django (as of 1.8) now comes with it's security middleware(from old django-secure), which implements SSL redirects, and handles HSTS header and other nice things.

Should I let Django handle all of the HTTPS redirect/HSTS configurations, or do it at the web server level? What are the security/performance implications of each choice?

References read/used:

https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security

https://garron.net/crypto/hsts/hsts-2013.pdf

https://cipherli.st/

https://mozilla.github.io/server-side-tls/ssl-config-generator/

https://security.stackexchange.com/questions/8964/trying-to-make-a-django-based-site-use-https-only-not-sure-if-its-secure

http://www.marinamele.com/2014/09/security-on-django-app-https-everywhere.html

https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html

https://docs.djangoproject.com/en/1.8/topics/security/

回答1:

It's been a while since you've asked the question. Anyway, I faced similar doubts. The documentation is ambiguous whether we should enable HSTS at the app level or on a web server:

HSTS may either be configured with SECURE_HSTS_SECONDS, SECURE_HSTS_INCLUDE_SUBDOMAINS, and SECURE_HSTS_PRELOAD, or on the Web server.

The deployment checklist (manage.py check --deploy) suggests to set SECURE_HSTS_SECONDS on production.

On the other hand, Django book states:

HSTS is usually configured on the web server.

Considering security, both server set up and django middleware do the same thing. They set up "Strict-Transport-Security" in response Header. I believe that web servers have a better performance than django middleware, though I haven't tested it.

Also, Two Scoops of Django suggests that it is better to put HTTPS redirects settings to a web server:

Performance-wise, it’s better to do this at the web server level (p. 347)