diff --git a/lib/secure_headers/headers/content_security_policy_config.rb b/lib/secure_headers/headers/content_security_policy_config.rb index 3c477161..5d3c7550 100644 --- a/lib/secure_headers/headers/content_security_policy_config.rb +++ b/lib/secure_headers/headers/content_security_policy_config.rb @@ -35,6 +35,7 @@ def initialize(hash) @report_only = nil @report_uri = nil @require_sri_for = nil + @require_trusted_types_for = nil @sandbox = nil @script_nonce = nil @script_src = nil @@ -44,6 +45,7 @@ def initialize(hash) @style_src = nil @style_src_elem = nil @style_src_attr = nil + @trusted_types = nil @worker_src = nil @upgrade_insecure_requests = nil @disable_nonce_backwards_compatibility = nil diff --git a/lib/secure_headers/headers/policy_management.rb b/lib/secure_headers/headers/policy_management.rb index b81f3b0e..99825443 100644 --- a/lib/secure_headers/headers/policy_management.rb +++ b/lib/secure_headers/headers/policy_management.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "set" +require 'byebug' module SecureHeaders module PolicyManagement @@ -98,7 +99,19 @@ def self.included(base) STYLE_SRC_ATTR ].flatten.freeze - ALL_DIRECTIVES = (DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0).uniq.sort + # Experimental directives - these vary greatly in support + # See MDN for details. + # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types + TRUSTED_TYPES = :trusted_types + # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for + REQUIRE_TRUSTED_TYPES_FOR = :require_trusted_types_for + + DIRECTIVES_EXPERIMENTAL = [ + TRUSTED_TYPES, + REQUIRE_TRUSTED_TYPES_FOR, + ].flatten.freeze + + ALL_DIRECTIVES = (DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_EXPERIMENTAL).uniq.sort # Think of default-src and report-uri as the beginning and end respectively, # everything else is in between. @@ -121,6 +134,7 @@ def self.included(base) OBJECT_SRC => :source_list, PLUGIN_TYPES => :media_type_list, REQUIRE_SRI_FOR => :require_sri_for_list, + REQUIRE_TRUSTED_TYPES_FOR => :require_trusted_types_for_list, REPORT_URI => :source_list, PREFETCH_SRC => :source_list, SANDBOX => :sandbox_list, @@ -130,6 +144,7 @@ def self.included(base) STYLE_SRC => :source_list, STYLE_SRC_ELEM => :source_list, STYLE_SRC_ATTR => :source_list, + TRUSTED_TYPES => :source_list, WORKER_SRC => :source_list, UPGRADE_INSECURE_REQUESTS => :boolean, }.freeze @@ -175,6 +190,7 @@ def self.included(base) ].freeze REQUIRE_SRI_FOR_VALUES = Set.new(%w(script style)) + REQUIRE_TRUSTED_TYPES_FOR_VALUES = Set.new(%w(script)) module ClassMethods # Public: generate a header name, value array that is user-agent-aware. @@ -324,6 +340,8 @@ def validate_directive!(directive, value) validate_media_type_expression!(directive, value) when :require_sri_for_list validate_require_sri_source_expression!(directive, value) + when :require_trusted_types_for_list + validate_require_trusted_types_for_source_expression!(directive, value) else raise ContentSecurityPolicyConfigError.new("Unknown directive #{directive}") end @@ -368,6 +386,16 @@ def validate_require_sri_source_expression!(directive, require_sri_for_expressio end end + # Private: validates that a require trusted types for expression: + # 1. is an array of strings + # 2. is a subset of ["script"] + def validate_require_trusted_types_for_source_expression!(directive, require_trusted_types_for_expression) + ensure_array_of_strings!(directive, require_trusted_types_for_expression) + unless require_trusted_types_for_expression.to_set.subset?(REQUIRE_TRUSTED_TYPES_FOR_VALUES) + raise ContentSecurityPolicyConfigError.new(%(require-sri for must be a subset of #{REQUIRE_TRUSTED_TYPES_FOR_VALUES.to_a} but was #{require_trusted_types_for_expression})) + end + end + # Private: validates that a source expression: # 1. is an array of strings # 2. does not contain any deprecated, now invalid values (inline, eval, self, none) diff --git a/spec/lib/secure_headers/headers/content_security_policy_spec.rb b/spec/lib/secure_headers/headers/content_security_policy_spec.rb index c080283d..2b2ba4d5 100644 --- a/spec/lib/secure_headers/headers/content_security_policy_spec.rb +++ b/spec/lib/secure_headers/headers/content_security_policy_spec.rb @@ -141,6 +141,15 @@ module SecureHeaders expect(csp.value).to eq("default-src 'self'; require-sri-for script style") end + it "supports require-trusted-types-for directive" do + csp = ContentSecurityPolicy.new({require_trusted_types_for: %(script)}) + expect(csp.value).to eq("require-trusted-types-for script") + end + + it "does not support style for require-trusted-types-for directive" do + expect { ContentSecurityPolicy.new({require_trusted_types_for: %(script style)}) }.to raise_error(ContentSecurityPolicyConfigError) + end + it "includes prefetch-src" do csp = ContentSecurityPolicy.new(default_src: %w('self'), prefetch_src: %w(foo.com)) expect(csp.value).to eq("default-src 'self'; prefetch-src foo.com") @@ -180,6 +189,11 @@ module SecureHeaders csp = ContentSecurityPolicy.new({style_src: %w('self'), style_src_attr: %w('self')}) expect(csp.value).to eq("style-src 'self'; style-src-attr 'self'") end + + it "supports trusted-types directive" do + csp = ContentSecurityPolicy.new({trusted_types: %w(blahblahpolicy)}) + expect(csp.value).to eq("trusted-types blahblahpolicy") + end end end end diff --git a/spec/lib/secure_headers/headers/policy_management_spec.rb b/spec/lib/secure_headers/headers/policy_management_spec.rb index 1a9ac4eb..150e0b35 100644 --- a/spec/lib/secure_headers/headers/policy_management_spec.rb +++ b/spec/lib/secure_headers/headers/policy_management_spec.rb @@ -45,6 +45,7 @@ module SecureHeaders plugin_types: %w(application/x-shockwave-flash), prefetch_src: %w(fetch.com), require_sri_for: %w(script style), + require_trusted_types_for: %w(script), script_src: %w('self'), style_src: %w('unsafe-inline'), upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/ @@ -53,6 +54,7 @@ module SecureHeaders script_src_attr: %w(example.com), style_src_elem: %w(example.com), style_src_attr: %w(example.com), + trusted_types: %w(abcpolicy), report_uri: %w(https://example.com/uri-directive), } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy