From c18532d505d8f992c3a22a5f2ee1e8fc540f621d Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Fri, 13 Oct 2023 16:01:41 +0530 Subject: [PATCH] Allow worker-src in CSP + pick up connect-src whitelist from env --- .env.development | 3 +- .../initializers/content_security_policy.rb | 52 +++++++------------ 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/.env.development b/.env.development index 7a1aa45cd..41cb02167 100644 --- a/.env.development +++ b/.env.development @@ -16,5 +16,6 @@ SENTRY_SECURITY_HEADER_ENDPOINT= SESSION_TIMEOUT_IN_MINUTES=7200 JUNE_ANALYTICS_KEY= DISALLOWED_SIGN_UP_DOMAINS= -CSP_REPORT_ONLY=false SESSION_REDIS_URL=redis://localhost:6379/0/session +CSP_REPORT_ONLY=false +CSP_CONNECT_SRC_URIS="http://localhost:3035", "ws://localhost:3035" diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 98fcb2321..d07b96ae4 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -4,6 +4,22 @@ # For further information see the following documentation # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy +def connect_src_uris + ENV["CSP_CONNECT_SRC_URIS"].split(",") || [] +end + +def csp_reporting_uri + report_uri = Addressable::URI.parse(ENV["SENTRY_SECURITY_HEADER_ENDPOINT"]) + report_uri&.query_values = report_uri&.query_values&.merge(sentry_environment: ENV["SENTRY_CURRENT_ENV"]) + report_uri +end + +def report_only + return true if ENV["CSP_REPORT_ONLY"]&.downcase == "true" + return false if ENV["CSP_REPORT_ONLY"]&.downcase == "false" + true +end + Rails.application.config.content_security_policy do |policy| policy.default_src(:self, :https) policy.base_uri(:self, :https) @@ -12,39 +28,11 @@ policy.object_src(:none) policy.script_src(:self, :https, :unsafe_inline, :unsafe_eval) policy.style_src(:self, :https, :unsafe_inline) - policy.connect_src(:self, :https, "http://localhost:3035", "ws://localhost:3035") if Rails.env.development? - policy.connect_src( - :self, - "https://via.intercom.io", - "https://api.intercom.io", - "https://api.au.intercom.io", - "https://api.eu.intercom.io", - "https://api-iam.intercom.io", - "https://api-iam.eu.intercom.io", - "https://api-iam.au.intercom.io", - "https://api-ping.intercom.io", - "https://nexus-websocket-a.intercom.io", - "wss://nexus-websocket-a.intercom.io", - "https://nexus-websocket-b.intercom.io", - "wss://nexus-websocket-b.intercom.io", - "https://nexus-europe-websocket.intercom.io", - "wss://nexus-europe-websocket.intercom.io", - "https://nexus-australia-websocket.intercom.io", - "wss://nexus-australia-websocket.intercom.io", - "https://uploads.intercomcdn.com", - "https://uploads.intercomcdn.eu", - "https://uploads.au.intercomcdn.com", - "https://uploads.intercomusercontent.com" - ) - report_uri = Addressable::URI.parse(ENV["SENTRY_SECURITY_HEADER_ENDPOINT"]) - report_uri&.query_values = report_uri&.query_values&.merge(sentry_environment: ENV["SENTRY_CURRENT_ENV"]) - policy.report_uri(report_uri.to_s) + policy.worker_src(:self, :https, :blob) + policy.connect_src(:self, *connect_src_uris) + policy.report_uri(csp_reporting_uri.to_s) end Rails.application.config.content_security_policy_nonce_generator = ->(request) { Base64.strict_encode64(request.session.id.to_s) } Rails.application.config.content_security_policy_nonce_directives = %w[script-src] -Rails.application.config.content_security_policy_report_only = -> { - return true if ENV["CSP_REPORT_ONLY"]&.downcase == "true" - return false if ENV["CSP_REPORT_ONLY"]&.downcase == "false" - true -}.call +Rails.application.config.content_security_policy_report_only = report_only