module PandaPal module SecureHeaders def self.apply_defaults(config) @config = config # The default cookie headers aren't compatable with PandaPal cookies currenntly config.cookies = { samesite: { none: true } } if Rails.env.production? config.cookies[:secure] = true end # Need to allow LTI iframes config.x_frame_options = "ALLOWALL" config.x_content_type_options = "nosniff" config.x_xss_protection = "1; mode=block" config.referrer_policy = %w(origin-when-cross-origin strict-origin-when-cross-origin) config.csp ||= {} csp_entry(:default_src, %w['self']) csp_entry(:connect_src, %w['self']) csp_entry(:script_src, %w['self']) if Rails.env.development? # Allow webpack-dev-server to work csp_entry(:connect_src, "http://localhost:3035") csp_entry(:connect_src, "ws://localhost:3035") # Allow stuff like rack-mini-profiler to work in development: # https://github.com/MiniProfiler/rack-mini-profiler/issues/327 csp_entry(:script_src, "'unsafe-eval'") # React Devtools csp_entry(:script_src, "'unsafe-inline'") # Detect and permit Scout APM in Dev if MiscHelper.to_boolean(ENV['SCOUT_DEV_TRACE']) csp_entry(:default_src, 'https://scoutapm.com') csp_entry(:default_src, 'https://apm.scoutapp.com') csp_entry(:script_src, "'unsafe-inline'") csp_entry(:script_src, 'https://scoutapm.com') csp_entry(:script_src, 'https://apm.scoutapp.com') csp_entry(:connect_src, 'https://apm.scoutapp.com') csp_entry(:style_src, 'https://scoutapm.com') csp_entry(:style_src, 'https://apm.scoutapp.com') end end # Detect and permit Sentry if defined?(Raven) && Raven.configuration.server.present? csp_entry(:connect_src, Raven.configuration.server) # Report CSP Violations to Sentry unless config.csp[:report_uri].present? cfg = Raven.configuration config.csp[:report_uri] = ["#{cfg.scheme}://#{cfg.host}/api/#{cfg.project_id}/security/?sentry_key=#{cfg.public_key}"] unless config.csp[:report_uri].present? end end # Certain CSS-in-JS libraries inline the CSS, so we need to use unsafe-inline for them csp_entry(:style_src, %w('self' 'unsafe-inline' blob: https://fonts.googleapis.com)) csp_entry(:font_src, %w('self' data: https://fonts.gstatic.com)) @config = nil config end private def self.csp_entry(key, *values) values = values.flatten @config.csp[key] ||= [] @config.csp[key] |= values end end end