From 7aa89c48d730450d6fc49d79c830bfb4ffdbc5ba Mon Sep 17 00:00:00 2001 From: sudip-khanal Date: Wed, 27 May 2026 15:01:19 +0545 Subject: [PATCH 1/2] feat(settings): add csrf trusted origins and cookie domains - Add SESSION_COOKIE_DOMAIN and CSRF_COOKIE_DOMAIN - Add ADDITIONAL_TRUSTED_ORIGINS configuration. - Update Django trusted origins and proxy/security headers. - Update Helm and docker-compose environment variables. --- .../templates/config/configmap.yaml | 3 ++ deploy/helm/ifrcgo-helm/values.yaml | 3 ++ docker-compose.yml | 2 + main/settings.py | 43 ++++++++++++++++--- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/deploy/helm/ifrcgo-helm/templates/config/configmap.yaml b/deploy/helm/ifrcgo-helm/templates/config/configmap.yaml index d8818b779..cde1f93d1 100644 --- a/deploy/helm/ifrcgo-helm/templates/config/configmap.yaml +++ b/deploy/helm/ifrcgo-helm/templates/config/configmap.yaml @@ -34,6 +34,9 @@ data: ELASTIC_SEARCH_INDEX: {{ .Values.env.ELASTIC_SEARCH_INDEX | quote }} DOCKER_HOST_IP: {{ .Values.env.DOCKER_HOST_IP | quote }} DJANGO_ADDITIONAL_ALLOWED_HOSTS: {{ .Values.env.DJANGO_ADDITIONAL_ALLOWED_HOSTS | quote }} + ADDITIONAL_TRUSTED_ORIGINS: {{ .Values.env.ADDITIONAL_TRUSTED_ORIGINS | quote }} + SESSION_COOKIE_DOMAIN: {{ .Values.env.SESSION_COOKIE_DOMAIN | quote }} + CSRF_COOKIE_DOMAIN: {{ .Values.env.CSRF_COOKIE_DOMAIN | quote }} GO_ENVIRONMENT: {{ .Values.env.GO_ENVIRONMENT | quote }} API_FQDN: {{ .Values.env.API_FQDN | quote }} FRONTEND_URL: {{ .Values.env.FRONTEND_URL | quote }} diff --git a/deploy/helm/ifrcgo-helm/values.yaml b/deploy/helm/ifrcgo-helm/values.yaml index a1dc9a04b..4a0fee4e2 100644 --- a/deploy/helm/ifrcgo-helm/values.yaml +++ b/deploy/helm/ifrcgo-helm/values.yaml @@ -39,6 +39,9 @@ env: DJANGO_DEBUG: '' DOCKER_HOST_IP: '' DJANGO_ADDITIONAL_ALLOWED_HOSTS: '' + ADDITIONAL_TRUSTED_ORIGINS: '' + SESSION_COOKIE_DOMAIN: '' + CSRF_COOKIE_DOMAIN: '' GO_ENVIRONMENT: '' API_FQDN: '' FRONTEND_URL: '' diff --git a/docker-compose.yml b/docker-compose.yml index 09c8614b0..e6b10c09b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,8 @@ x-server: &base_server_setup PLAYWRIGHT_SERVER_URL: ${PLAYWRIGHT_SERVER_URL:-ws://playwright:3000/} GO_WEB_INTERNAL_URL: ${GO_WEB_INTERNAL_URL:-http://host.docker.internal:3000} DJANGO_ADDITIONAL_ALLOWED_HOSTS: ${DJANGO_ADDITIONAL_ALLOWED_HOSTS:-host.docker.internal,127.0.0.1,localhost} + SESSION_COOKIE_DOMAIN: ${SESSION_COOKIE_DOMAIN:-localhost} + CSRF_COOKIE_DOMAIN: ${CSRF_COOKIE_DOMAIN:-localhost} DEBUG_EMAIL: ${DEBUG_EMAIL:-true} MOLNIX_API_BASE: ${MOLNIX_API_BASE:-https://api.ifrc-staging.rpm.molnix.com/api/} ERP_API_ENDPOINT: ${ERP_API_ENDPOINT:-https://ifrctintapim001.azure-api.net/GoAPI/ExtractGoEmergency} diff --git a/main/settings.py b/main/settings.py index 30c59cbae..f716f56e9 100644 --- a/main/settings.py +++ b/main/settings.py @@ -29,7 +29,9 @@ DJANGO_STATIC_URL=(str, "/static/"), DJANGO_ADDITIONAL_ALLOWED_HOSTS=(list, []), # Eg: api.go.ifrc.org, goadmin.ifrc.org, dsgocdnapi.azureedge.net GO_ENVIRONMENT=(str, "development"), # staging, production - # + SESSION_COOKIE_DOMAIN=str, + CSRF_COOKIE_DOMAIN=str, + ADDITIONAL_TRUSTED_ORIGINS=(list, []), API_FQDN=str, # https://goadmin.ifrc.org FRONTEND_URL=str, # https://go.ifrc.org GO_WEB_INTERNAL_URL=(str, None), # http://host.docker.internal @@ -178,8 +180,8 @@ def parse_domain(*env_keys: str) -> str: # NOTE: Used in local development to point to the frontend service from within go-api container # Default to GO_WEB_URL if GO_WEB_INTERNAL_URL is not provided GO_WEB_INTERNAL_URL = parse_domain("GO_WEB_INTERNAL_URL", "FRONTEND_URL") -FRONTEND_URL = urlparse(GO_WEB_URL).hostname # FIXME: Deprecated. Slowly remove this from codebase +FRONTEND_URL = urlparse(GO_WEB_URL).hostname # FIXME: Deprecated. Slowly remove this from codebase PLAYWRIGHT_SERVER_URL = env("PLAYWRIGHT_SERVER_URL") INTERNAL_IPS = ["127.0.0.1"] @@ -470,10 +472,39 @@ def parse_domain(*env_keys: str) -> str: IFRC_TRANSLATION_DOMAIN = env("IFRC_TRANSLATION_DOMAIN") IFRC_TRANSLATION_HEADER_API_KEY = env("IFRC_TRANSLATION_HEADER_API_KEY") -# Needed to generate correct https links when running behind a reverse proxy -# when SSL is terminated at the proxy -USE_X_FORWARDED_HOST = True -SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_SCHEME", "https") + +# -- Security Headers -- +GO_TRUSTED_ORIGINS = [ + GO_WEB_URL, + GO_API_URL, + *env("ADDITIONAL_TRUSTED_ORIGINS"), +] + +SESSION_COOKIE_NAME = f"GO-{GO_ENVIRONMENT}-SESSIONID" +CSRF_COOKIE_NAME = f"GO-{GO_ENVIRONMENT}-CSRFTOKEN" +SECURE_BROWSER_XSS_FILTER = True +SECURE_CONTENT_TYPE_NOSNIFF = True +X_FRAME_OPTIONS = "DENY" +CSP_DEFAULT_SRC = ["'self'"] +SECURE_REFERRER_POLICY = "same-origin" + +if urlparse(GO_API_URL).scheme == "https": + SESSION_COOKIE_NAME = f"__Secure-{SESSION_COOKIE_NAME}" + SESSION_COOKIE_SECURE = True + SESSION_COOKIE_HTTPONLY = True + CSRF_COOKIE_SECURE = True + SECURE_HSTS_SECONDS = 30 # TODO: Increase this slowly + SECURE_HSTS_INCLUDE_SUBDOMAINS = True + SECURE_HSTS_PRELOAD = True + SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") + +CSRF_TRUSTED_ORIGINS = GO_TRUSTED_ORIGINS + +# https://docs.djangoproject.com/en/4.2/ref/settings/#std:setting-SESSION_COOKIE_DOMAIN +SESSION_COOKIE_DOMAIN = env("SESSION_COOKIE_DOMAIN") +# https://docs.djangoproject.com/en/4.2/ref/settings/#csrf-cookie-domain +CSRF_COOKIE_DOMAIN = env("CSRF_COOKIE_DOMAIN") + # Storage MEDIA_URL = env("DJANGO_MEDIA_URL") From 87de9daf8ddbda4915ba13a0a1b7d9371dc3ae63 Mon Sep 17 00:00:00 2001 From: sudip-khanal Date: Wed, 27 May 2026 16:01:22 +0545 Subject: [PATCH 2/2] fixup! feat(settings): add csrf trusted origins and cookie domains --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6ae7df824..1dc21848a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6ae7df824005d88816bac3670c6c7f07cadef138 +Subproject commit 1dc21848a52d25770830643276f939072bf8631b