From d433708f86c404b35d1da9e698fb47728e350cbf Mon Sep 17 00:00:00 2001 From: Sajeyks Date: Fri, 6 Nov 2026 15:27:27 +0300 Subject: [PATCH] Add production HTTPS and proxy settings - Session and CSRF cookies are secure-only unless DEBUG is on. - TRUST_X_FORWARDED_PROTO honours X-Forwarded-Proto from a TLS terminating ingress. Without it, Django 4+ fails the CSRF origin check on every form POST. - CSRF_TRUSTED_ORIGINS, SECURE_SSL_REDIRECT and SECURE_HSTS_SECONDS are configurable and off by default. HSTS for subdomains and preload are left to ungleich, since they affect all of *.ungleich.ch. --- dal/settings.py | 14 ++++++++++++++ env.sample | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/dal/settings.py b/dal/settings.py index 414c1d5..c38415f 100644 --- a/dal/settings.py +++ b/dal/settings.py @@ -49,6 +49,20 @@ MAILERS = { ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) +# --- HTTPS / proxy ----------------------------------------------------------- +# Behind a TLS-terminating proxy (e.g. a Kubernetes ingress) Django sees plain +# HTTP. Only enable this if the proxy always sets X-Forwarded-Proto. +if config('TRUST_X_FORWARDED_PROTO', default=False, cast=bool): + SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') + +# Full origins (scheme included), e.g. https://account.ungleich.ch +CSRF_TRUSTED_ORIGINS = config('CSRF_TRUSTED_ORIGINS', default='', cast=Csv()) + +SESSION_COOKIE_SECURE = config('SESSION_COOKIE_SECURE', default=not DEBUG, cast=bool) +CSRF_COOKIE_SECURE = config('CSRF_COOKIE_SECURE', default=not DEBUG, cast=bool) +SECURE_SSL_REDIRECT = config('SECURE_SSL_REDIRECT', default=False, cast=bool) +SECURE_HSTS_SECONDS = config('SECURE_HSTS_SECONDS', default=0, cast=int) + INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', diff --git a/env.sample b/env.sample index f3cb002..692a7bf 100644 --- a/env.sample +++ b/env.sample @@ -14,6 +14,14 @@ LOG_LEVEL=INFO # root log level; output goes to stdout #DJANGO_LOG_LEVEL=INFO #LDAP3_LOG=False # ldap3 protocol logging (very verbose) +# --- HTTPS / proxy ------------------------------------------------------------ +#TRUST_X_FORWARDED_PROTO=False # True behind a TLS-terminating ingress +#CSRF_TRUSTED_ORIGINS="" # comma separated, e.g. https://account.ungleich.ch +#SESSION_COOKIE_SECURE= # default: True unless DEBUG +#CSRF_COOKIE_SECURE= # default: True unless DEBUG +#SECURE_SSL_REDIRECT=False # usually done by the ingress +#SECURE_HSTS_SECONDS=0 # read Django's HSTS docs before raising + # --- LDAP ------------------------------------------------------------------- # Space separated; the first reachable server is used (failover). LDAPSERVER="ldap://ldap1.ungleich.ch ldap://ldap2.ungleich.ch"