Commit 77accef8 authored by Antonio Sartori's avatar Antonio Sartori Committed by Chromium LUCI CQ

CSP: Use map for CSP source list directives in blink

This is a small refactoring of the code in
blink::CSPDirectiveList. Instead of storing the source list directives
as separate members, we put them in a map.

This is part of a project to harmonize the CSP code in Blink and in
services/network, and will make it easier to synchronize Content
Security Policies between the two.

Bug: 1021462,1149272
Change-Id: I5936d73aa0cb83530565c88341395a51a092cfba
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2593641
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843450}
parent c7a895f3
...@@ -1180,32 +1180,31 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) { ...@@ -1180,32 +1180,31 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
return; return;
} }
network::mojom::blink::CSPSourceListPtr source_list = nullptr;
switch (type) { switch (type) {
case CSPDirectiveName::BaseURI: case CSPDirectiveName::BaseURI:
base_uri_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
return; return;
case CSPDirectiveName::BlockAllMixedContent: case CSPDirectiveName::BlockAllMixedContent:
EnforceStrictMixedContentChecking(name, value); EnforceStrictMixedContentChecking(name, value);
return; return;
case CSPDirectiveName::ChildSrc: case CSPDirectiveName::ChildSrc:
child_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::ConnectSrc: case CSPDirectiveName::ConnectSrc:
connect_src_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
return; return;
case CSPDirectiveName::DefaultSrc: case CSPDirectiveName::DefaultSrc:
default_src_ = CSPSourceListParse(name, value, policy_); source_list = CSPSourceListParse(name, value, policy_);
// TODO(mkwst) It seems unlikely that developers would use different // TODO(mkwst) It seems unlikely that developers would use different
// algorithms for scripts and styles. We may want to combine the // algorithms for scripts and styles. We may want to combine the
// usesScriptHashAlgorithms() and usesStyleHashAlgorithms. // usesScriptHashAlgorithms() and usesStyleHashAlgorithms.
policy_->UsesScriptHashAlgorithms(HashAlgorithmsUsed(default_src_.get())); policy_->UsesScriptHashAlgorithms(HashAlgorithmsUsed(source_list.get()));
policy_->UsesStyleHashAlgorithms(HashAlgorithmsUsed(default_src_.get())); policy_->UsesStyleHashAlgorithms(HashAlgorithmsUsed(source_list.get()));
directives_.insert(type, std::move(source_list));
return; return;
case CSPDirectiveName::FontSrc: case CSPDirectiveName::FontSrc:
font_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::FormAction: case CSPDirectiveName::FormAction:
form_action_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
return; return;
case CSPDirectiveName::FrameAncestors: case CSPDirectiveName::FrameAncestors:
// Remove frame-ancestors directives in meta policies, per // Remove frame-ancestors directives in meta policies, per
...@@ -1213,26 +1212,16 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) { ...@@ -1213,26 +1212,16 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
if (header_->source == ContentSecurityPolicySource::kMeta) { if (header_->source == ContentSecurityPolicySource::kMeta) {
policy_->ReportInvalidDirectiveInMeta(name); policy_->ReportInvalidDirectiveInMeta(name);
} else { } else {
frame_ancestors_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
} }
return; return;
case CSPDirectiveName::FrameSrc: case CSPDirectiveName::FrameSrc:
frame_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::ImgSrc: case CSPDirectiveName::ImgSrc:
img_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::ManifestSrc: case CSPDirectiveName::ManifestSrc:
manifest_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::MediaSrc: case CSPDirectiveName::MediaSrc:
media_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::NavigateTo: case CSPDirectiveName::NavigateTo:
navigate_to_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::ObjectSrc: case CSPDirectiveName::ObjectSrc:
object_src_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
return; return;
case CSPDirectiveName::PluginTypes: case CSPDirectiveName::PluginTypes:
plugin_types_ = CSPPluginTypesParse(value, policy_); plugin_types_ = CSPPluginTypesParse(value, policy_);
...@@ -1241,7 +1230,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) { ...@@ -1241,7 +1230,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
if (!policy_->ExperimentalFeaturesEnabled()) if (!policy_->ExperimentalFeaturesEnabled())
policy_->ReportUnsupportedDirective(name); policy_->ReportUnsupportedDirective(name);
else else
prefetch_src_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
return; return;
case CSPDirectiveName::ReportTo: case CSPDirectiveName::ReportTo:
if (base::FeatureList::IsEnabled(network::features::kReporting)) if (base::FeatureList::IsEnabled(network::features::kReporting))
...@@ -1260,32 +1249,18 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) { ...@@ -1260,32 +1249,18 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
ApplySandboxPolicy(name, value); ApplySandboxPolicy(name, value);
return; return;
case CSPDirectiveName::ScriptSrc: case CSPDirectiveName::ScriptSrc:
script_src_ = CSPSourceListParse(name, value, policy_);
policy_->UsesScriptHashAlgorithms(HashAlgorithmsUsed(script_src_.get()));
return;
case CSPDirectiveName::ScriptSrcAttr: case CSPDirectiveName::ScriptSrcAttr:
script_src_attr_ = CSPSourceListParse(name, value, policy_);
policy_->UsesScriptHashAlgorithms(
HashAlgorithmsUsed(script_src_attr_.get()));
return;
case CSPDirectiveName::ScriptSrcElem: case CSPDirectiveName::ScriptSrcElem:
script_src_elem_ = CSPSourceListParse(name, value, policy_); source_list = CSPSourceListParse(name, value, policy_);
policy_->UsesScriptHashAlgorithms( policy_->UsesScriptHashAlgorithms(HashAlgorithmsUsed(source_list.get()));
HashAlgorithmsUsed(script_src_elem_.get())); directives_.insert(type, std::move(source_list));
return; return;
case CSPDirectiveName::StyleSrc: case CSPDirectiveName::StyleSrc:
style_src_ = CSPSourceListParse(name, value, policy_);
policy_->UsesStyleHashAlgorithms(HashAlgorithmsUsed(style_src_.get()));
return;
case CSPDirectiveName::StyleSrcAttr: case CSPDirectiveName::StyleSrcAttr:
style_src_attr_ = CSPSourceListParse(name, value, policy_);
policy_->UsesStyleHashAlgorithms(
HashAlgorithmsUsed(style_src_attr_.get()));
return;
case CSPDirectiveName::StyleSrcElem: case CSPDirectiveName::StyleSrcElem:
style_src_elem_ = CSPSourceListParse(name, value, policy_); source_list = CSPSourceListParse(name, value, policy_);
policy_->UsesStyleHashAlgorithms( policy_->UsesStyleHashAlgorithms(HashAlgorithmsUsed(source_list.get()));
HashAlgorithmsUsed(style_src_elem_.get())); directives_.insert(type, std::move(source_list));
return; return;
case CSPDirectiveName::TreatAsPublicAddress: case CSPDirectiveName::TreatAsPublicAddress:
ApplyTreatAsPublicAddress(); ApplyTreatAsPublicAddress();
...@@ -1300,7 +1275,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) { ...@@ -1300,7 +1275,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
NOTREACHED(); NOTREACHED();
return; return;
case CSPDirectiveName::WorkerSrc: case CSPDirectiveName::WorkerSrc:
worker_src_ = CSPSourceListParse(name, value, policy_); directives_.insert(type, CSPSourceListParse(name, value, policy_));
return; return;
} }
} }
...@@ -1362,83 +1337,17 @@ CSPOperativeDirective CSPDirectiveList::OperativeDirective( ...@@ -1362,83 +1337,17 @@ CSPOperativeDirective CSPDirectiveList::OperativeDirective(
return CSPOperativeDirective{CSPDirectiveName::Unknown, nullptr}; return CSPOperativeDirective{CSPDirectiveName::Unknown, nullptr};
} }
const network::mojom::blink::CSPSourceList* directive;
if (original_type == CSPDirectiveName::Unknown) { if (original_type == CSPDirectiveName::Unknown) {
original_type = type; original_type = type;
} }
switch (type) { const auto directive = directives_.find(type);
case CSPDirectiveName::BaseURI:
directive = base_uri_.get();
break;
case CSPDirectiveName::DefaultSrc:
directive = default_src_.get();
break;
case CSPDirectiveName::FrameAncestors:
directive = frame_ancestors_.get();
break;
case CSPDirectiveName::FormAction:
directive = form_action_.get();
break;
case CSPDirectiveName::NavigateTo:
directive = navigate_to_.get();
break;
case CSPDirectiveName::ChildSrc:
directive = child_src_.get();
break;
case CSPDirectiveName::ConnectSrc:
directive = connect_src_.get();
break;
case CSPDirectiveName::FontSrc:
directive = font_src_.get();
break;
case CSPDirectiveName::ImgSrc:
directive = img_src_.get();
break;
case CSPDirectiveName::ManifestSrc:
directive = manifest_src_.get();
break;
case CSPDirectiveName::MediaSrc:
directive = media_src_.get();
break;
case CSPDirectiveName::ObjectSrc:
directive = object_src_.get();
break;
case CSPDirectiveName::PrefetchSrc:
directive = prefetch_src_.get();
break;
case CSPDirectiveName::ScriptSrc:
directive = script_src_.get();
break;
case CSPDirectiveName::ScriptSrcAttr:
directive = script_src_attr_.get();
break;
case CSPDirectiveName::ScriptSrcElem:
directive = script_src_elem_.get();
break;
case CSPDirectiveName::StyleSrc:
directive = style_src_.get();
break;
case CSPDirectiveName::StyleSrcAttr:
directive = style_src_attr_.get();
break;
case CSPDirectiveName::StyleSrcElem:
directive = style_src_elem_.get();
break;
case CSPDirectiveName::FrameSrc:
directive = frame_src_.get();
break;
case CSPDirectiveName::WorkerSrc:
directive = worker_src_.get();
break;
default:
return CSPOperativeDirective{CSPDirectiveName::Unknown, nullptr};
}
// if the directive does not exist, rely on the fallback directive // if the directive does not exist, rely on the fallback directive
return directive ? CSPOperativeDirective{type, directive} return (directive != directives_.end())
: OperativeDirective(FallbackDirective(type, original_type), ? CSPOperativeDirective{type, directive->value.get()}
original_type); : OperativeDirective(FallbackDirective(type, original_type),
original_type);
} }
network::mojom::blink::ContentSecurityPolicyPtr network::mojom::blink::ContentSecurityPolicyPtr
...@@ -1450,27 +1359,7 @@ CSPDirectiveList::ExposeForNavigationalChecks() const { ...@@ -1450,27 +1359,7 @@ CSPDirectiveList::ExposeForNavigationalChecks() const {
policy->use_reporting_api = use_reporting_api_; policy->use_reporting_api = use_reporting_api_;
policy->report_endpoints = report_endpoints_; policy->report_endpoints = report_endpoints_;
policy->header = header_.Clone(); policy->header = header_.Clone();
policy->directives = mojo::Clone(directives_);
if (child_src_) {
policy->directives.Set(CSPDirectiveName::ChildSrc, child_src_.Clone());
}
if (default_src_) {
policy->directives.Set(CSPDirectiveName::DefaultSrc, default_src_.Clone());
}
if (form_action_) {
policy->directives.Set(CSPDirectiveName::FormAction, form_action_.Clone());
}
if (frame_src_) {
policy->directives.Set(CSPDirectiveName::FrameSrc, frame_src_.Clone());
}
if (navigate_to_) {
policy->directives.Set(CSPDirectiveName::NavigateTo, navigate_to_.Clone());
}
policy->upgrade_insecure_requests = upgrade_insecure_requests_; policy->upgrade_insecure_requests = upgrade_insecure_requests_;
return policy; return policy;
...@@ -1483,8 +1372,10 @@ bool CSPDirectiveList::IsObjectRestrictionReasonable() const { ...@@ -1483,8 +1372,10 @@ bool CSPDirectiveList::IsObjectRestrictionReasonable() const {
} }
bool CSPDirectiveList::IsBaseRestrictionReasonable() const { bool CSPDirectiveList::IsBaseRestrictionReasonable() const {
return base_uri_ && const auto base_uri = directives_.find(CSPDirectiveName::BaseURI);
(CSPSourceListIsNone(*base_uri_) || CSPSourceListIsSelf(*base_uri_)); return (base_uri != directives_.end()) &&
(CSPSourceListIsNone(*base_uri->value) ||
CSPSourceListIsSelf(*base_uri->value));
} }
bool CSPDirectiveList::IsScriptRestrictionReasonable() const { bool CSPDirectiveList::IsScriptRestrictionReasonable() const {
......
...@@ -134,18 +134,9 @@ class CORE_EXPORT CSPDirectiveList final ...@@ -134,18 +134,9 @@ class CORE_EXPORT CSPDirectiveList final
bool AllowHash(const network::mojom::blink::CSPHashSource& hash_value, bool AllowHash(const network::mojom::blink::CSPHashSource& hash_value,
const ContentSecurityPolicy::InlineType inline_type) const; const ContentSecurityPolicy::InlineType inline_type) const;
// Export a subset of the Policy. The primary goal of this method is to make // Export the policies. The primary goal of this method is to make
// the embedders aware of the directives that affect navigation, as the // the embedders aware of the directives that affect navigation, as the
// embedder is responsible for navigational enforcement. // embedder is responsible for navigational enforcement.
// It currently contains the following ones:
// * default-src
// * child-src
// * frame-src
// * form-action
// * upgrade-insecure-requests
// * navigate-to
// The exported directives only contains sources that affect navigation. For
// instance it doesn't contains 'unsafe-inline' or 'unsafe-eval'
network::mojom::blink::ContentSecurityPolicyPtr ExposeForNavigationalChecks() network::mojom::blink::ContentSecurityPolicyPtr ExposeForNavigationalChecks()
const; const;
...@@ -295,27 +286,8 @@ class CORE_EXPORT CSPDirectiveList final ...@@ -295,27 +286,8 @@ class CORE_EXPORT CSPDirectiveList final
bool upgrade_insecure_requests_; bool upgrade_insecure_requests_;
base::Optional<Vector<String>> plugin_types_; base::Optional<Vector<String>> plugin_types_;
network::mojom::blink::CSPSourceListPtr base_uri_; HashMap<CSPDirectiveName, network::mojom::blink::CSPSourceListPtr>
network::mojom::blink::CSPSourceListPtr child_src_; directives_;
network::mojom::blink::CSPSourceListPtr connect_src_;
network::mojom::blink::CSPSourceListPtr default_src_;
network::mojom::blink::CSPSourceListPtr font_src_;
network::mojom::blink::CSPSourceListPtr form_action_;
network::mojom::blink::CSPSourceListPtr frame_ancestors_;
network::mojom::blink::CSPSourceListPtr frame_src_;
network::mojom::blink::CSPSourceListPtr img_src_;
network::mojom::blink::CSPSourceListPtr media_src_;
network::mojom::blink::CSPSourceListPtr manifest_src_;
network::mojom::blink::CSPSourceListPtr object_src_;
network::mojom::blink::CSPSourceListPtr prefetch_src_;
network::mojom::blink::CSPSourceListPtr script_src_;
network::mojom::blink::CSPSourceListPtr script_src_attr_;
network::mojom::blink::CSPSourceListPtr script_src_elem_;
network::mojom::blink::CSPSourceListPtr style_src_;
network::mojom::blink::CSPSourceListPtr style_src_attr_;
network::mojom::blink::CSPSourceListPtr style_src_elem_;
network::mojom::blink::CSPSourceListPtr worker_src_;
network::mojom::blink::CSPSourceListPtr navigate_to_;
network::mojom::blink::CSPTrustedTypesPtr trusted_types_; network::mojom::blink::CSPTrustedTypesPtr trusted_types_;
network::mojom::blink::CSPRequireTrustedTypesFor require_trusted_types_for_; network::mojom::blink::CSPRequireTrustedTypesFor require_trusted_types_for_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment