This commit is contained in:
Jack McCracken 2022-05-04 15:37:38 -04:00
Родитель 7f89df2daf
Коммит 01f009154d
4 изменённых файлов: 47 добавлений и 1 удалений

Просмотреть файл

@ -35,6 +35,7 @@ module SecureHeaders
@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 @@ module SecureHeaders
@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

Просмотреть файл

@ -1,6 +1,7 @@
# frozen_string_literal: true
require "set"
require 'byebug'
module SecureHeaders
module PolicyManagement
@ -98,7 +99,19 @@ module SecureHeaders
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 @@ module SecureHeaders
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 @@ module SecureHeaders
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 @@ module SecureHeaders
].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 @@ module SecureHeaders
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 @@ module SecureHeaders
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)

Просмотреть файл

@ -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

Просмотреть файл

@ -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),
}