diff --git a/app/controllers/concerns/idv/document_capture_concern.rb b/app/controllers/concerns/idv/document_capture_concern.rb index 3eb49969f0f..cdbf634e6f0 100644 --- a/app/controllers/concerns/idv/document_capture_concern.rb +++ b/app/controllers/concerns/idv/document_capture_concern.rb @@ -3,26 +3,6 @@ module DocumentCaptureConcern def override_document_capture_step_csp return if params[:step] != 'document_capture' - if FeatureManagement.rails_csp_tooling_enabled? - override_document_capture_step_csp_with_rails_csp_tooling - else - override_document_capture_step_csp_with_secure_headers - end - end - - def override_document_capture_step_csp_with_secure_headers - SecureHeaders.append_content_security_policy_directives( - request, - # required to run wasm until wasm-eval is available - script_src: ['\'unsafe-eval\''], - # required because acuant styles its own elements with inline style attributes - style_src: ['\'unsafe-inline\''], - # required for retrieving image dimensions from uploaded images - img_src: ['blob:'], - ) - end - - def override_document_capture_step_csp_with_rails_csp_tooling policy = current_content_security_policy policy.script_src(*policy.script_src, :unsafe_eval) policy.style_src(*policy.style_src, :unsafe_inline) diff --git a/app/controllers/concerns/secure_headers_concern.rb b/app/controllers/concerns/secure_headers_concern.rb index 2cb05f90ea9..380b6c291a6 100644 --- a/app/controllers/concerns/secure_headers_concern.rb +++ b/app/controllers/concerns/secure_headers_concern.rb @@ -11,18 +11,6 @@ def apply_secure_headers_override end def override_form_action_csp(uris) - if FeatureManagement.rails_csp_tooling_enabled? - apply_secure_headers_override_with_rails_csp_tooling(uris) - else - apply_secure_headers_override_with_secure_headers(uris) - end - end - - def apply_secure_headers_override_with_secure_headers(uris) - override_content_security_policy_directives(form_action: uris) - end - - def apply_secure_headers_override_with_rails_csp_tooling(uris) policy = current_content_security_policy policy.form_action(*uris) request.content_security_policy = policy diff --git a/app/helpers/secure_headers_helper.rb b/app/helpers/secure_headers_helper.rb index 0c018da20d7..131c90333b8 100644 --- a/app/helpers/secure_headers_helper.rb +++ b/app/helpers/secure_headers_helper.rb @@ -1,10 +1,6 @@ module SecureHeadersHelper def backwards_compatible_javascript_tag(*args, **opts, &block) - if FeatureManagement.rails_csp_tooling_enabled? - javascript_tag(*args, opts.merge(nonce: true), &block) - else - nonced_javascript_tag(*args, **opts, &block) - end + javascript_tag(*args, opts.merge(nonce: true), &block) end def add_document_capture_image_urls_to_csp(request, urls) @@ -12,11 +8,7 @@ def add_document_capture_image_urls_to_csp(request, urls) URI(url).tap { |uri| uri.query = nil }.to_s end - if FeatureManagement.rails_csp_tooling_enabled? - add_document_capture_image_urls_to_csp_with_rails_csp_tooling(request, cleaned_urls) - else - add_document_capture_image_urls_to_csp_with_secure_headers(request, cleaned_urls) - end + add_document_capture_image_urls_to_csp_with_rails_csp_tooling(request, cleaned_urls) end def add_document_capture_image_urls_to_csp_with_secure_headers(request, urls) diff --git a/config/application.yml.default b/config/application.yml.default index d68d714db0f..bbc8f0c7d1f 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -174,7 +174,6 @@ push_notifications_enabled: false pwned_passwords_file_path: 'pwned_passwords/pwned_passwords.txt' rack_mini_profiler: false rack_timeout_service_timeout_seconds: 15 -rails_csp_tooling_enabled: true rails_mailer_previews_enabled: false reauthn_window: 120 recovery_code_length: 4 diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 98cc6aa2336..43da641dd41 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -1,67 +1,65 @@ require 'feature_management' -if FeatureManagement.rails_csp_tooling_enabled? - # rubocop:disable Metrics/BlockLength - Rails.application.config.content_security_policy do |policy| - connect_src = ["'self'", '*.nr-data.net', '*.google-analytics.com', 'us.acas.acuant.net'] +# rubocop:disable Metrics/BlockLength +Rails.application.config.content_security_policy do |policy| + connect_src = ["'self'", '*.nr-data.net', '*.google-analytics.com', 'us.acas.acuant.net'] - font_src = [:self, :data, IdentityConfig.store.asset_host.presence].compact + font_src = [:self, :data, IdentityConfig.store.asset_host.presence].compact - image_src = [ - "'self'", - 'data:', - 'login.gov', - IdentityConfig.store.asset_host.presence, - 'idscangoweb.acuant.com', - IdentityConfig.store.aws_region.presence && - "https://s3.#{IdentityConfig.store.aws_region}.amazonaws.com", - ].select(&:present?) + image_src = [ + "'self'", + 'data:', + 'login.gov', + IdentityConfig.store.asset_host.presence, + 'idscangoweb.acuant.com', + IdentityConfig.store.aws_region.presence && + "https://s3.#{IdentityConfig.store.aws_region}.amazonaws.com", + ].select(&:present?) - script_src = [ - :self, - 'js-agent.newrelic.com', - '*.nr-data.net', - 'dap.digitalgov.gov', - '*.google-analytics.com', - IdentityConfig.store.asset_host.presence, - ].compact + script_src = [ + :self, + 'js-agent.newrelic.com', + '*.nr-data.net', + 'dap.digitalgov.gov', + '*.google-analytics.com', + IdentityConfig.store.asset_host.presence, + ].compact - script_src = [:self, :unsafe_eval] if !Rails.env.production? + script_src = [:self, :unsafe_eval] if !Rails.env.production? - style_src = [:self, IdentityConfig.store.asset_host.presence].compact + style_src = [:self, IdentityConfig.store.asset_host.presence].compact - if ENV['WEBPACK_PORT'] - connect_src << "ws://localhost:#{ENV['WEBPACK_PORT']}" - script_src << "localhost:#{ENV['WEBPACK_PORT']}" - end - - if !IdentityConfig.store.disable_csp_unsafe_inline - script_src << :unsafe_inline - style_src << :unsafe_inline - end - - if IdentityConfig.store.rails_mailer_previews_enabled - style_src << :unsafe_inline - # CSP 2.0 only; overriden by x_frame_options in some browsers - policy.frame_ancestors :self - end + if ENV['WEBPACK_PORT'] + connect_src << "ws://localhost:#{ENV['WEBPACK_PORT']}" + script_src << "localhost:#{ENV['WEBPACK_PORT']}" + end - policy.default_src :self - policy.child_src :self # CSP 2.0 only; replaces frame_src - policy.form_action :self - policy.block_all_mixed_content true # CSP 2.0 only; - policy.connect_src(*connect_src.flatten.compact) - policy.font_src(*font_src) - policy.img_src(*image_src) - policy.media_src :self - policy.object_src :none - policy.script_src(*script_src) - policy.style_src(*style_src) - policy.base_uri :self + if !IdentityConfig.store.disable_csp_unsafe_inline + script_src << :unsafe_inline + style_src << :unsafe_inline end - # rubocop:enable Metrics/BlockLength - Rails.application.configure do - config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } - config.content_security_policy_nonce_directives = ['script-src'] + + if IdentityConfig.store.rails_mailer_previews_enabled + style_src << :unsafe_inline + # CSP 2.0 only; overriden by x_frame_options in some browsers + policy.frame_ancestors :self end + + policy.default_src :self + policy.child_src :self # CSP 2.0 only; replaces frame_src + policy.form_action :self + policy.block_all_mixed_content true # CSP 2.0 only; + policy.connect_src(*connect_src.flatten.compact) + policy.font_src(*font_src) + policy.img_src(*image_src) + policy.media_src :self + policy.object_src :none + policy.script_src(*script_src) + policy.style_src(*style_src) + policy.base_uri :self +end +# rubocop:enable Metrics/BlockLength +Rails.application.configure do + config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } + config.content_security_policy_nonce_directives = ['script-src'] end diff --git a/config/initializers/secure_headers.rb b/config/initializers/secure_headers.rb index 3aeab5662ac..fd81223e62b 100644 --- a/config/initializers/secure_headers.rb +++ b/config/initializers/secure_headers.rb @@ -1,18 +1,16 @@ require 'feature_management' -if FeatureManagement.rails_csp_tooling_enabled? - Rails.application.configure do - config.ssl_options = { - secure_cookies: true, - hsts: { preload: true, expires: 1.year, subdomains: true }, - } +Rails.application.configure do + config.ssl_options = { + secure_cookies: true, + hsts: { preload: true, expires: 1.year, subdomains: true }, + } - config.action_dispatch.default_headers.merge!( - 'X-Frame-Options' => 'DENY', - 'X-XSS-Protection' => '1; mode=block', - 'X-Download-Options' => 'noopen', - ) - end + config.action_dispatch.default_headers.merge!( + 'X-Frame-Options' => 'DENY', + 'X-XSS-Protection' => '1; mode=block', + 'X-Download-Options' => 'noopen', + ) end SecureHeaders::Configuration.default do |config| # rubocop:disable Metrics/BlockLength @@ -69,18 +67,15 @@ default_csp_config[:script_src] << "localhost:#{ENV['WEBPACK_PORT']}" end - if FeatureManagement.rails_csp_tooling_enabled? - config.csp = SecureHeaders::OPT_OUT - else - config.csp = default_csp_config - config.cookies = { - secure: true, # mark all cookies as "Secure" - httponly: true, # mark all cookies as "HttpOnly" - samesite: { - lax: true, # SameSitesetting. - }, - } - end + config.csp = SecureHeaders::OPT_OUT + + config.cookies = { + secure: true, # mark all cookies as "Secure" + httponly: true, # mark all cookies as "HttpOnly" + samesite: { + lax: true, # SameSite setting. + }, + } # Temporarily disabled until we configure pinning. See GitHub issue #1895. # config.hpkp = { diff --git a/lib/feature_management.rb b/lib/feature_management.rb index 9d78ffee3cd..a26e92bbe38 100644 --- a/lib/feature_management.rb +++ b/lib/feature_management.rb @@ -120,8 +120,4 @@ def self.voip_allowed_phones allowed_phones.map { |p| Phonelib.parse(p).e164 }.to_set end end - - def self.rails_csp_tooling_enabled? - IdentityConfig.store.rails_csp_tooling_enabled == true - end end diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 61e7a59b879..40144b7f3fb 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -257,7 +257,6 @@ def self.build_store(config_map) config.add(:pwned_passwords_file_path, type: :string) config.add(:rack_mini_profiler, type: :boolean) config.add(:rack_timeout_service_timeout_seconds, type: :integer) - config.add(:rails_csp_tooling_enabled, type: :boolean) config.add(:rails_mailer_previews_enabled, type: :boolean) config.add(:reauthn_window, type: :integer) config.add(:recovery_code_length, type: :integer)