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

Add raw directive values to mojo CSP types

This CL stores the raw values of the parsed Content Security Policies
directives into the mojo types. This is yet another step to align the
mojo types to Blink's CSP implementation, where the raw values are
used for reporting and for console messages.

Bug: 1021462,1149272,1149926
Change-Id: Iee34cba2fad3a98a483a5e0e9898ce90a5754ea1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2546541
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832282}
parent 963f5e34
...@@ -40,6 +40,10 @@ network::mojom::ContentSecurityPolicyPtr BuildContentSecurityPolicy( ...@@ -40,6 +40,10 @@ network::mojom::ContentSecurityPolicyPtr BuildContentSecurityPolicy(
policy_in.header.Utf8(), policy_in.disposition, policy_in.source); policy_in.header.Utf8(), policy_in.disposition, policy_in.source);
policy->use_reporting_api = policy_in.use_reporting_api; policy->use_reporting_api = policy_in.use_reporting_api;
for (const auto& directive : policy_in.raw_directives) {
auto name = network::ToCSPDirectiveName(directive.name.Utf8());
policy->raw_directives[name] = directive.value.Utf8();
}
for (const auto& directive : policy_in.directives) { for (const auto& directive : policy_in.directives) {
auto name = network::ToCSPDirectiveName(directive.name.Utf8()); auto name = network::ToCSPDirectiveName(directive.name.Utf8());
policy->directives[name] = BuildCSPSourceList(directive.source_list); policy->directives[name] = BuildCSPSourceList(directive.source_list);
......
...@@ -302,8 +302,10 @@ DirectivesMap ParseHeaderValue(base::StringPiece header) { ...@@ -302,8 +302,10 @@ DirectivesMap ParseHeaderValue(base::StringPiece header) {
// 5. Let directive value be the result of splitting token on ASCII // 5. Let directive value be the result of splitting token on ASCII
// whitespace. // whitespace.
base::StringPiece value; base::StringPiece value;
if (pos != std::string::npos) if (pos != std::string::npos) {
value = directive.substr(pos + 1); value = base::TrimString(directive.substr(pos + 1),
base::kWhitespaceASCII, base::TRIM_ALL);
}
// 6. Let directive be a new directive whose name is directive name, // 6. Let directive be a new directive whose name is directive name,
// and value is directive value. // and value is directive value.
...@@ -858,28 +860,36 @@ void AddContentSecurityPolicyFromHeader(base::StringPiece header, ...@@ -858,28 +860,36 @@ void AddContentSecurityPolicyFromHeader(base::StringPiece header,
continue; continue;
} }
if (!base::ranges::all_of(directive.second, IsDirectiveValueCharacter)) { CSPDirectiveName directive_name =
ToCSPDirectiveName(directive.first.as_string());
if (directive_name == CSPDirectiveName::Unknown) {
out->parsing_errors.emplace_back(base::StringPrintf( out->parsing_errors.emplace_back(base::StringPrintf(
"The value for the Content-Security-Policy directive '%s' contains " "Unrecognized Content-Security-Policy directive '%s'.",
"one or more invalid characters. Non-whitespace characters outside "
"ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, "
"section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.",
directive.first.as_string().c_str())); directive.first.as_string().c_str()));
continue; continue;
} }
CSPDirectiveName directive_name =
ToCSPDirectiveName(directive.first.as_string());
// A directive with this name has already been parsed. Skip further // A directive with this name has already been parsed. Skip further
// directives per // directives per
// https://www.w3.org/TR/CSP3/#parse-serialized-policy. // https://www.w3.org/TR/CSP3/#parse-serialized-policy.
if (out->directives.count(directive_name)) { if (out->raw_directives.count(directive_name)) {
out->parsing_errors.emplace_back(base::StringPrintf( out->parsing_errors.emplace_back(base::StringPrintf(
"Ignoring duplicate Content-Security-Policy directive '%s'.", "Ignoring duplicate Content-Security-Policy directive '%s'.",
directive.first.as_string().c_str())); directive.first.as_string().c_str()));
continue; continue;
} }
out->raw_directives[directive_name] = directive.second.as_string();
if (!base::ranges::all_of(directive.second, IsDirectiveValueCharacter)) {
out->parsing_errors.emplace_back(base::StringPrintf(
"The value for the Content-Security-Policy directive '%s' contains "
"one or more invalid characters. Non-whitespace characters outside "
"ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, "
"section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.",
directive.first.as_string().c_str()));
continue;
}
if (type == mojom::ContentSecurityPolicyType::kReport && if (type == mojom::ContentSecurityPolicyType::kReport &&
!SupportedInReportOnly(directive_name)) { !SupportedInReportOnly(directive_name)) {
...@@ -969,9 +979,6 @@ void AddContentSecurityPolicyFromHeader(base::StringPiece header, ...@@ -969,9 +979,6 @@ void AddContentSecurityPolicyFromHeader(base::StringPiece header,
&(out->report_endpoints)); &(out->report_endpoints));
break; break;
case CSPDirectiveName::Unknown: case CSPDirectiveName::Unknown:
out->parsing_errors.emplace_back(base::StringPrintf(
"Unrecognized Content-Security-Policy directive '%s'.",
directive.first.as_string().c_str()));
break; break;
} }
} }
......
...@@ -148,6 +148,10 @@ struct CSPTrustedTypes { ...@@ -148,6 +148,10 @@ struct CSPTrustedTypes {
}; };
struct ContentSecurityPolicy { struct ContentSecurityPolicy {
// The raw, unparsed values of the specified CSP directives. Needed for
// reporting.
map<CSPDirectiveName, string> raw_directives;
map<CSPDirectiveName, CSPSourceList> directives; map<CSPDirectiveName, CSPSourceList> directives;
// Spec: https://www.w3.org/TR/upgrade-insecure-requests/ // Spec: https://www.w3.org/TR/upgrade-insecure-requests/
......
...@@ -71,6 +71,13 @@ struct WebContentSecurityPolicyDirective { ...@@ -71,6 +71,13 @@ struct WebContentSecurityPolicyDirective {
WebContentSecurityPolicySourceList source_list; WebContentSecurityPolicySourceList source_list;
}; };
// TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly
// from blink.
struct WebContentSecurityPolicyRawDirective {
WebString name;
WebString value;
};
// TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly // TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly
// from blink. // from blink.
struct WebCSPTrustedTypes { struct WebCSPTrustedTypes {
...@@ -84,6 +91,7 @@ struct WebCSPTrustedTypes { ...@@ -84,6 +91,7 @@ struct WebCSPTrustedTypes {
struct WebContentSecurityPolicy { struct WebContentSecurityPolicy {
network::mojom::ContentSecurityPolicyType disposition; network::mojom::ContentSecurityPolicyType disposition;
network::mojom::ContentSecurityPolicySource source; network::mojom::ContentSecurityPolicySource source;
WebVector<WebContentSecurityPolicyRawDirective> raw_directives;
WebVector<WebContentSecurityPolicyDirective> directives; WebVector<WebContentSecurityPolicyDirective> directives;
bool upgrade_insecure_requests; bool upgrade_insecure_requests;
bool block_all_mixed_content; bool block_all_mixed_content;
......
...@@ -277,8 +277,17 @@ WebContentSecurityPolicy ConvertToPublic( ...@@ -277,8 +277,17 @@ WebContentSecurityPolicy ConvertToPublic(
ConvertToPublic(std::move(directive.value))}; ConvertToPublic(std::move(directive.value))};
} }
WebVector<WebContentSecurityPolicyRawDirective> raw_directives(
policy->raw_directives.size());
i = 0;
for (auto& directive : policy->raw_directives) {
raw_directives[i++] = {ConvertToPublic(directive.key),
std::move(directive.value)};
}
return {policy->header->type, return {policy->header->type,
policy->header->source, policy->header->source,
std::move(raw_directives),
std::move(directives), std::move(directives),
policy->upgrade_insecure_requests, policy->upgrade_insecure_requests,
policy->block_all_mixed_content, policy->block_all_mixed_content,
......
...@@ -114,6 +114,18 @@ WTF::HashMap<blink::CSPDirectiveName, blink::CSPSourceListPtr> ConvertToBlink( ...@@ -114,6 +114,18 @@ WTF::HashMap<blink::CSPDirectiveName, blink::CSPSourceListPtr> ConvertToBlink(
return out; return out;
} }
WTF::HashMap<blink::CSPDirectiveName, String> ConvertToBlink(
base::flat_map<CSPDirectiveName, std::string> directives) {
WTF::HashMap<blink::CSPDirectiveName, String> out;
for (auto& list : directives) {
out.insert(ConvertToBlink(list.first),
String::FromUTF8(std::move(list.second)));
}
return out;
}
WTF::Vector<WTF::String> ConvertToBlink(std::vector<std::string> in) { WTF::Vector<WTF::String> ConvertToBlink(std::vector<std::string> in) {
WTF::Vector<WTF::String> out; WTF::Vector<WTF::String> out;
for (auto& el : in) for (auto& el : in)
...@@ -132,6 +144,7 @@ blink::CSPTrustedTypesPtr ConvertToBlink(CSPTrustedTypesPtr trusted_types) { ...@@ -132,6 +144,7 @@ blink::CSPTrustedTypesPtr ConvertToBlink(CSPTrustedTypesPtr trusted_types) {
blink::ContentSecurityPolicyPtr ConvertToBlink( blink::ContentSecurityPolicyPtr ConvertToBlink(
ContentSecurityPolicyPtr policy_in) { ContentSecurityPolicyPtr policy_in) {
return blink::ContentSecurityPolicy::New( return blink::ContentSecurityPolicy::New(
ConvertToBlink(std::move(policy_in->raw_directives)),
ConvertToBlink(std::move(policy_in->directives)), ConvertToBlink(std::move(policy_in->directives)),
policy_in->upgrade_insecure_requests, policy_in->treat_as_public_address, policy_in->upgrade_insecure_requests, policy_in->treat_as_public_address,
policy_in->block_all_mixed_content, policy_in->sandbox, policy_in->block_all_mixed_content, policy_in->sandbox,
......
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