Add trusted types directive
This commit is contained in:
Родитель
7f89df2daf
Коммит
01f009154d
|
@ -35,6 +35,7 @@ module SecureHeaders
|
||||||
@report_only = nil
|
@report_only = nil
|
||||||
@report_uri = nil
|
@report_uri = nil
|
||||||
@require_sri_for = nil
|
@require_sri_for = nil
|
||||||
|
@require_trusted_types_for = nil
|
||||||
@sandbox = nil
|
@sandbox = nil
|
||||||
@script_nonce = nil
|
@script_nonce = nil
|
||||||
@script_src = nil
|
@script_src = nil
|
||||||
|
@ -44,6 +45,7 @@ module SecureHeaders
|
||||||
@style_src = nil
|
@style_src = nil
|
||||||
@style_src_elem = nil
|
@style_src_elem = nil
|
||||||
@style_src_attr = nil
|
@style_src_attr = nil
|
||||||
|
@trusted_types = nil
|
||||||
@worker_src = nil
|
@worker_src = nil
|
||||||
@upgrade_insecure_requests = nil
|
@upgrade_insecure_requests = nil
|
||||||
@disable_nonce_backwards_compatibility = nil
|
@disable_nonce_backwards_compatibility = nil
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "set"
|
require "set"
|
||||||
|
require 'byebug'
|
||||||
|
|
||||||
module SecureHeaders
|
module SecureHeaders
|
||||||
module PolicyManagement
|
module PolicyManagement
|
||||||
|
@ -98,7 +99,19 @@ module SecureHeaders
|
||||||
STYLE_SRC_ATTR
|
STYLE_SRC_ATTR
|
||||||
].flatten.freeze
|
].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,
|
# Think of default-src and report-uri as the beginning and end respectively,
|
||||||
# everything else is in between.
|
# everything else is in between.
|
||||||
|
@ -121,6 +134,7 @@ module SecureHeaders
|
||||||
OBJECT_SRC => :source_list,
|
OBJECT_SRC => :source_list,
|
||||||
PLUGIN_TYPES => :media_type_list,
|
PLUGIN_TYPES => :media_type_list,
|
||||||
REQUIRE_SRI_FOR => :require_sri_for_list,
|
REQUIRE_SRI_FOR => :require_sri_for_list,
|
||||||
|
REQUIRE_TRUSTED_TYPES_FOR => :require_trusted_types_for_list,
|
||||||
REPORT_URI => :source_list,
|
REPORT_URI => :source_list,
|
||||||
PREFETCH_SRC => :source_list,
|
PREFETCH_SRC => :source_list,
|
||||||
SANDBOX => :sandbox_list,
|
SANDBOX => :sandbox_list,
|
||||||
|
@ -130,6 +144,7 @@ module SecureHeaders
|
||||||
STYLE_SRC => :source_list,
|
STYLE_SRC => :source_list,
|
||||||
STYLE_SRC_ELEM => :source_list,
|
STYLE_SRC_ELEM => :source_list,
|
||||||
STYLE_SRC_ATTR => :source_list,
|
STYLE_SRC_ATTR => :source_list,
|
||||||
|
TRUSTED_TYPES => :source_list,
|
||||||
WORKER_SRC => :source_list,
|
WORKER_SRC => :source_list,
|
||||||
UPGRADE_INSECURE_REQUESTS => :boolean,
|
UPGRADE_INSECURE_REQUESTS => :boolean,
|
||||||
}.freeze
|
}.freeze
|
||||||
|
@ -175,6 +190,7 @@ module SecureHeaders
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
REQUIRE_SRI_FOR_VALUES = Set.new(%w(script style))
|
REQUIRE_SRI_FOR_VALUES = Set.new(%w(script style))
|
||||||
|
REQUIRE_TRUSTED_TYPES_FOR_VALUES = Set.new(%w(script))
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
# Public: generate a header name, value array that is user-agent-aware.
|
# Public: generate a header name, value array that is user-agent-aware.
|
||||||
|
@ -324,6 +340,8 @@ module SecureHeaders
|
||||||
validate_media_type_expression!(directive, value)
|
validate_media_type_expression!(directive, value)
|
||||||
when :require_sri_for_list
|
when :require_sri_for_list
|
||||||
validate_require_sri_source_expression!(directive, value)
|
validate_require_sri_source_expression!(directive, value)
|
||||||
|
when :require_trusted_types_for_list
|
||||||
|
validate_require_trusted_types_for_source_expression!(directive, value)
|
||||||
else
|
else
|
||||||
raise ContentSecurityPolicyConfigError.new("Unknown directive #{directive}")
|
raise ContentSecurityPolicyConfigError.new("Unknown directive #{directive}")
|
||||||
end
|
end
|
||||||
|
@ -368,6 +386,16 @@ module SecureHeaders
|
||||||
end
|
end
|
||||||
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:
|
# Private: validates that a source expression:
|
||||||
# 1. is an array of strings
|
# 1. is an array of strings
|
||||||
# 2. does not contain any deprecated, now invalid values (inline, eval, self, none)
|
# 2. does not contain any deprecated, now invalid values (inline, eval, self, none)
|
||||||
|
|
|
@ -141,6 +141,15 @@ module SecureHeaders
|
||||||
expect(csp.value).to eq("default-src 'self'; require-sri-for script style")
|
expect(csp.value).to eq("default-src 'self'; require-sri-for script style")
|
||||||
end
|
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
|
it "includes prefetch-src" do
|
||||||
csp = ContentSecurityPolicy.new(default_src: %w('self'), prefetch_src: %w(foo.com))
|
csp = ContentSecurityPolicy.new(default_src: %w('self'), prefetch_src: %w(foo.com))
|
||||||
expect(csp.value).to eq("default-src 'self'; prefetch-src 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')})
|
csp = ContentSecurityPolicy.new({style_src: %w('self'), style_src_attr: %w('self')})
|
||||||
expect(csp.value).to eq("style-src 'self'; style-src-attr 'self'")
|
expect(csp.value).to eq("style-src 'self'; style-src-attr 'self'")
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,6 +45,7 @@ module SecureHeaders
|
||||||
plugin_types: %w(application/x-shockwave-flash),
|
plugin_types: %w(application/x-shockwave-flash),
|
||||||
prefetch_src: %w(fetch.com),
|
prefetch_src: %w(fetch.com),
|
||||||
require_sri_for: %w(script style),
|
require_sri_for: %w(script style),
|
||||||
|
require_trusted_types_for: %w(script),
|
||||||
script_src: %w('self'),
|
script_src: %w('self'),
|
||||||
style_src: %w('unsafe-inline'),
|
style_src: %w('unsafe-inline'),
|
||||||
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
|
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),
|
script_src_attr: %w(example.com),
|
||||||
style_src_elem: %w(example.com),
|
style_src_elem: %w(example.com),
|
||||||
style_src_attr: %w(example.com),
|
style_src_attr: %w(example.com),
|
||||||
|
trusted_types: %w(abcpolicy),
|
||||||
|
|
||||||
report_uri: %w(https://example.com/uri-directive),
|
report_uri: %w(https://example.com/uri-directive),
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче