A => qwertywar/csp.py +14 -0
@@ 0,0 1,14 @@
+def content_security_policy_self(get_response):
+ '''Django doesn't have content-security-policy options with built-in
+ middleware, so write one. There's a full-featured 3rd-party csp middleware
+ project, but no need to add a dependency for this site's very simple policy.
+ '''
+
+ def set_csp_self(request):
+ response = get_response(request)
+ response['Content-Security-Policy'] = (
+ "default-src 'self'; "
+ "style-src 'self' 'unsafe-inline'" )
+ return response
+
+ return set_csp_self
M settings.py +13 -0
@@ 27,9 27,11 @@ INSTALLED_APPS = [
'django.contrib.staticfiles'
]
MIDDLEWARE = [
+ 'qwertywar.csp.content_security_policy_self',
'django.middleware.common.CommonMiddleware', # for append slash and prepend www
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ 'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
]
@@ 57,3 59,14 @@ ALLOWED_HOSTS = [
# For Heroku
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
+
+# https://observatory.mozilla.org/ is a handy site for checking http security
+SECURE_BROWSER_XSS_FILTER = True
+SECURE_CONTENT_TYPE_NOSNIFF = True
+if not DEBUG:
+ # ssl redirect is a pain during development
+ SECURE_SSL_REDIRECT = True
+
+SECURE_HSTS_INCLUDE_SUBDOMAINS = True
+SECURE_HSTS_PRELOAD = True
+SECURE_HSTS_SECONDS = 360