11# frozen_string_literal: true
22
33require "set"
4+ require 'byebug'
45
56module SecureHeaders
67 module PolicyManagement
@@ -98,7 +99,19 @@ def self.included(base)
9899 STYLE_SRC_ATTR
99100 ] . flatten . freeze
100101
101- ALL_DIRECTIVES = ( DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 ) . uniq . sort
102+ # Experimental directives - these vary greatly in support
103+ # See MDN for details.
104+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
105+ TRUSTED_TYPES = :trusted_types
106+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for
107+ REQUIRE_TRUSTED_TYPES_FOR = :require_trusted_types_for
108+
109+ DIRECTIVES_EXPERIMENTAL = [
110+ TRUSTED_TYPES ,
111+ REQUIRE_TRUSTED_TYPES_FOR ,
112+ ] . flatten . freeze
113+
114+ ALL_DIRECTIVES = ( DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_EXPERIMENTAL ) . uniq . sort
102115
103116 # Think of default-src and report-uri as the beginning and end respectively,
104117 # everything else is in between.
@@ -121,6 +134,7 @@ def self.included(base)
121134 OBJECT_SRC => :source_list ,
122135 PLUGIN_TYPES => :media_type_list ,
123136 REQUIRE_SRI_FOR => :require_sri_for_list ,
137+ REQUIRE_TRUSTED_TYPES_FOR => :require_trusted_types_for_list ,
124138 REPORT_URI => :source_list ,
125139 PREFETCH_SRC => :source_list ,
126140 SANDBOX => :sandbox_list ,
@@ -130,6 +144,7 @@ def self.included(base)
130144 STYLE_SRC => :source_list ,
131145 STYLE_SRC_ELEM => :source_list ,
132146 STYLE_SRC_ATTR => :source_list ,
147+ TRUSTED_TYPES => :source_list ,
133148 WORKER_SRC => :source_list ,
134149 UPGRADE_INSECURE_REQUESTS => :boolean ,
135150 } . freeze
@@ -175,6 +190,7 @@ def self.included(base)
175190 ] . freeze
176191
177192 REQUIRE_SRI_FOR_VALUES = Set . new ( %w( script style ) )
193+ REQUIRE_TRUSTED_TYPES_FOR_VALUES = Set . new ( %w( script ) )
178194
179195 module ClassMethods
180196 # Public: generate a header name, value array that is user-agent-aware.
@@ -324,6 +340,8 @@ def validate_directive!(directive, value)
324340 validate_media_type_expression! ( directive , value )
325341 when :require_sri_for_list
326342 validate_require_sri_source_expression! ( directive , value )
343+ when :require_trusted_types_for_list
344+ validate_require_trusted_types_for_source_expression! ( directive , value )
327345 else
328346 raise ContentSecurityPolicyConfigError . new ( "Unknown directive #{ directive } " )
329347 end
@@ -368,6 +386,16 @@ def validate_require_sri_source_expression!(directive, require_sri_for_expressio
368386 end
369387 end
370388
389+ # Private: validates that a require trusted types for expression:
390+ # 1. is an array of strings
391+ # 2. is a subset of ["script"]
392+ def validate_require_trusted_types_for_source_expression! ( directive , require_trusted_types_for_expression )
393+ ensure_array_of_strings! ( directive , require_trusted_types_for_expression )
394+ unless require_trusted_types_for_expression . to_set . subset? ( REQUIRE_TRUSTED_TYPES_FOR_VALUES )
395+ 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 } ) )
396+ end
397+ end
398+
371399 # Private: validates that a source expression:
372400 # 1. is an array of strings
373401 # 2. does not contain any deprecated, now invalid values (inline, eval, self, none)
0 commit comments