From d771718799f6889cb76db031b0af14d192bbc93b Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 3 Jul 2025 14:09:00 -0400 Subject: [PATCH] Add environment variables for CSP configuration across different environments --- docker-compose.dev.yml | 1 + docker-compose.yml | 1 + docker/ploughshares/app.py | 38 ++++++++++++++++++++++++++++++++------ stack.production.yml | 2 ++ stack.staging.yml | 2 ++ 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 0938214..6ac9618 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -17,6 +17,7 @@ services: - POSTGRES_DB=ploughshares - POSTGRES_USER=ploughshares - POSTGRES_PASSWORD=ploughshares_password + - APP_ENV=development depends_on: db: condition: service_healthy diff --git a/docker-compose.yml b/docker-compose.yml index fe29ad7..55fa330 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: - POSTGRES_USER=ploughshares - POSTGRES_PASSWORD=ploughshares_password - APP_VERSION=0.1.2 + - APP_ENV=development depends_on: db: condition: service_healthy diff --git a/docker/ploughshares/app.py b/docker/ploughshares/app.py index f449748..13b3b7a 100644 --- a/docker/ploughshares/app.py +++ b/docker/ploughshares/app.py @@ -36,7 +36,12 @@ app.secret_key = 'supersecretkey' app.config['UPLOAD_FOLDER'] = 'uploads' app.config['VERSION'] = VERSION +# Get domain configuration from environment +APP_DOMAIN = os.environ.get('APP_DOMAIN', '') +APP_ENV = os.environ.get('APP_ENV', 'development') + # Configure security headers with Talisman +# Base CSP settings csp = { 'default-src': "'none'", 'script-src': ["'self'", @@ -53,6 +58,23 @@ csp = { 'form-action': "'self'" } +# Add domain-specific CSP settings if domain is provided +if APP_DOMAIN: + logger.info(f"Configuring CSP for domain: {APP_DOMAIN}") + # Add domain to connect-src if needed + if APP_DOMAIN not in csp['connect-src']: + if isinstance(csp['connect-src'], list): + csp['connect-src'].append(APP_DOMAIN) + else: + csp['connect-src'] = [csp['connect-src'], APP_DOMAIN] + + # Update form-action to include the domain + if isinstance(csp['form-action'], list): + if APP_DOMAIN not in csp['form-action']: + csp['form-action'].append(APP_DOMAIN) + else: + csp['form-action'] = [csp['form-action'], APP_DOMAIN] + permissions_policy = { 'accelerometer': '()', 'camera': '()', @@ -64,21 +86,25 @@ permissions_policy = { 'usb': '()' } +# Determine if HTTPS should be forced based on environment +force_https = APP_ENV != 'development' +logger.info(f"Environment: {APP_ENV}, Force HTTPS: {force_https}") + # Initialize Talisman talisman = Talisman( app, content_security_policy=csp, content_security_policy_nonce_in=['script-src'], feature_policy=permissions_policy, - force_https=True, - force_https_permanent=True, - strict_transport_security=True, - strict_transport_security_preload=True, + force_https=force_https, + force_https_permanent=force_https, + strict_transport_security=force_https, + strict_transport_security_preload=force_https, strict_transport_security_max_age=31536000, - strict_transport_security_include_subdomains=True, + strict_transport_security_include_subdomains=force_https, referrer_policy='strict-origin-when-cross-origin', frame_options='DENY', - session_cookie_secure=True, + session_cookie_secure=force_https, session_cookie_http_only=True ) diff --git a/stack.production.yml b/stack.production.yml index 499a493..02bf6a7 100644 --- a/stack.production.yml +++ b/stack.production.yml @@ -32,6 +32,8 @@ services: - POSTGRES_DB=ploughshares - POSTGRES_USER=ploughshares - POSTGRES_PASSWORD=ploughshares_password + - APP_DOMAIN=https://ploughshares.nixc.us + - APP_ENV=production networks: - traefik - ploughshares-internal diff --git a/stack.staging.yml b/stack.staging.yml index 0785f0f..ac658b2 100644 --- a/stack.staging.yml +++ b/stack.staging.yml @@ -29,6 +29,8 @@ services: - POSTGRES_DB=ploughshares - POSTGRES_USER=ploughshares - POSTGRES_PASSWORD_FILE=/run/secrets/db_password_staging + - APP_DOMAIN=https://staging-ploughshares.nixc.us + - APP_ENV=staging networks: - traefik - ploughshares-internal