Add Content Security Policy (CSP) headers

Implements CSP to prevent XSS attacks and complete Mozilla Observatory
security requirements.

Changes:
- Added django-csp>=3.8 to requirements.txt
- Added CSPMiddleware to middleware stack
- Configured CSP directives in selfhosted.py:
  - default-src 'self' (only load resources from same origin)
  - script-src/style-src allow 'unsafe-inline' (needed for Django admin)
  - img-src allows https: and data: URIs
  - frame-ancestors 'none' (prevent clickjacking)
  - form-action 'self' (prevent form hijacking)

This policy balances security with Django admin functionality.
After deployment, Mozilla Observatory should show all green checks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2025-12-26 17:40:34 -07:00
co-authored by Claude Sonnet 4.5
parent 00fca071bf
commit e95369ffbf
3 changed files with 17 additions and 0 deletions
+13
View File
@@ -135,6 +135,19 @@ SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY' # Prevent clickjacking
# Content Security Policy (CSP)
# Helps prevent XSS attacks by controlling what resources can load
# This policy allows Django admin to function while providing good security
CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = ("'self'", "'unsafe-inline'") # unsafe-inline needed for Django admin
CSP_STYLE_SRC = ("'self'", "'unsafe-inline'") # unsafe-inline needed for Django admin
CSP_IMG_SRC = ("'self'", "data:", "https:") # Allow images from HTTPS sources
CSP_FONT_SRC = ("'self'", "data:")
CSP_CONNECT_SRC = ("'self'",)
CSP_FRAME_ANCESTORS = ("'none'",) # Equivalent to X-Frame-Options: DENY
CSP_BASE_URI = ("'self'",)
CSP_FORM_ACTION = ("'self'",)
# Static files
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'