Commit 5d1d3d63 authored by Antonio Sartori's avatar Antonio Sartori Committed by Commit Bot

Add 'require-trusted-types-for' directive to network CSP code

The Content Security Policies code under services/network and the
relative mojo types still misses support for a few CSP directives. We
need to support all CSP directives in order to use it as a replacement
to the Blink types, and also if we want to add Content Security
Policies to the Policy Container (see attached bugs).

This CL implements support for the directive
'require-trusted-types-for'.

Bug: 1021462,1149272
Change-Id: I32880e8b3e35f1db4acf92a40e5d167a5f76870a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2539906Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828637}
parent b37c2342
...@@ -49,6 +49,8 @@ network::mojom::ContentSecurityPolicyPtr BuildContentSecurityPolicy( ...@@ -49,6 +49,8 @@ network::mojom::ContentSecurityPolicyPtr BuildContentSecurityPolicy(
for (const blink::WebString& endpoint : policy_in.report_endpoints) for (const blink::WebString& endpoint : policy_in.report_endpoints)
policy->report_endpoints.push_back(endpoint.Utf8()); policy->report_endpoints.push_back(endpoint.Utf8());
policy->require_trusted_types_for = policy_in.require_trusted_types_for;
return policy; return policy;
} }
......
...@@ -728,6 +728,21 @@ std::vector<std::string> ParsePluginTypes( ...@@ -728,6 +728,21 @@ std::vector<std::string> ParsePluginTypes(
return out; return out;
} }
// Parse the 'required-trusted-types-for' directive.
// https://w3c.github.io/webappsec-trusted-types/dist/spec/#require-trusted-types-for-csp-directive
//
// TODO(https://crbug.com/1149293): Add a warning when parsing invalid values.
network::mojom::CSPRequireTrustedTypesFor ParseRequireTrustedTypesFor(
base::StringPiece value) {
for (const auto expression : base::SplitStringPiece(
value, base::kWhitespaceASCII, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY)) {
if (expression == "'script'")
return network::mojom::CSPRequireTrustedTypesFor::Script;
}
return network::mojom::CSPRequireTrustedTypesFor::None;
}
// Parses a reporting directive. // Parses a reporting directive.
// https://w3c.github.io/webappsec-csp/#directives-reporting // https://w3c.github.io/webappsec-csp/#directives-reporting
// TODO(lfg): The report-to should be treated as a single token according to the // TODO(lfg): The report-to should be treated as a single token according to the
...@@ -879,12 +894,16 @@ void AddContentSecurityPolicyFromHeader(base::StringPiece header, ...@@ -879,12 +894,16 @@ void AddContentSecurityPolicyFromHeader(base::StringPiece header,
ParsePluginTypes(directive.second, out->parsing_errors); ParsePluginTypes(directive.second, out->parsing_errors);
break; break;
case CSPDirectiveName::RequireTrustedTypesFor:
out->require_trusted_types_for =
ParseRequireTrustedTypesFor(directive.second);
break;
// We check the following three directives so that we do not trigger a // We check the following three directives so that we do not trigger a
// warning because of an unrecognized directive. However, we skip // warning because of an unrecognized directive. However, we skip
// parsing them for now since we do not need these directives here (they // parsing them for now since we do not need these directives here (they
// are parsed and enforced in the blink CSP parser). // are parsed and enforced in the blink CSP parser).
case CSPDirectiveName::BlockAllMixedContent: case CSPDirectiveName::BlockAllMixedContent:
case CSPDirectiveName::RequireTrustedTypesFor:
case CSPDirectiveName::TrustedTypes: case CSPDirectiveName::TrustedTypes:
break; break;
......
...@@ -635,6 +635,42 @@ TEST(ContentSecurityPolicy, ParsePluginTypes) { ...@@ -635,6 +635,42 @@ TEST(ContentSecurityPolicy, ParsePluginTypes) {
} }
} }
TEST(ContentSecurityPolicy, ParseRequireTrustedTypesFor) {
struct {
const char* input;
network::mojom::CSPRequireTrustedTypesFor expected;
} cases[]{
{
"require-trusted-types-for",
network::mojom::CSPRequireTrustedTypesFor::None,
},
{
"require-trusted-types-for 'script'",
network::mojom::CSPRequireTrustedTypesFor::Script,
},
{
"require-trusted-types-for 'wasm' 'script'",
network::mojom::CSPRequireTrustedTypesFor::Script,
},
{
"require-trusted-types-for 'script' 'wasm' 'script'",
network::mojom::CSPRequireTrustedTypesFor::Script,
},
{
"require-trusted-types-for 'wasm'",
network::mojom::CSPRequireTrustedTypesFor::None,
},
};
for (const auto& testCase : cases) {
std::vector<mojom::ContentSecurityPolicyPtr> policies =
ParseCSP(testCase.input);
EXPECT_EQ(policies[0]->directives.size(), 0u);
EXPECT_EQ(policies[0]->parsing_errors.size(), 0u);
EXPECT_EQ(policies[0]->require_trusted_types_for, testCase.expected);
}
}
TEST(ContentSecurityPolicy, ParseReportEndpoint) { TEST(ContentSecurityPolicy, ParseReportEndpoint) {
// report-uri directive. // report-uri directive.
{ {
......
...@@ -127,6 +127,11 @@ enum CSPDirectiveName { ...@@ -127,6 +127,11 @@ enum CSPDirectiveName {
WorkerSrc, WorkerSrc,
}; };
enum CSPRequireTrustedTypesFor {
None = 0,
Script = 1,
};
struct ContentSecurityPolicy { struct ContentSecurityPolicy {
map<CSPDirectiveName, CSPSourceList> directives; map<CSPDirectiveName, CSPSourceList> directives;
...@@ -160,6 +165,11 @@ struct ContentSecurityPolicy { ...@@ -160,6 +165,11 @@ struct ContentSecurityPolicy {
// allowed. // allowed.
array<string>? plugin_types; array<string>? plugin_types;
// The parsed value of the directive 'require-trusted-types-for'.
// https://w3c.github.io/webappsec-trusted-types/dist/spec/#require-trusted-types-for-csp-directive
CSPRequireTrustedTypesFor require_trusted_types_for =
CSPRequireTrustedTypesFor.None;
// An array containing a set of errors occurred while parsing the CSP header. // An array containing a set of errors occurred while parsing the CSP header.
array<string> parsing_errors; array<string> parsing_errors;
}; };
......
...@@ -81,6 +81,7 @@ struct WebContentSecurityPolicy { ...@@ -81,6 +81,7 @@ struct WebContentSecurityPolicy {
WebVector<WebString> report_endpoints; WebVector<WebString> report_endpoints;
WebString header; WebString header;
bool use_reporting_api; bool use_reporting_api;
network::mojom::CSPRequireTrustedTypesFor require_trusted_types_for;
}; };
} // namespace blink } // namespace blink
......
...@@ -272,7 +272,8 @@ WebContentSecurityPolicy ConvertToPublic( ...@@ -272,7 +272,8 @@ WebContentSecurityPolicy ConvertToPublic(
policy->upgrade_insecure_requests, policy->upgrade_insecure_requests,
std::move(policy->report_endpoints), std::move(policy->report_endpoints),
policy->header->header_value, policy->header->header_value,
policy->use_reporting_api}; policy->use_reporting_api,
policy->require_trusted_types_for};
} }
} // namespace } // namespace
......
...@@ -133,6 +133,7 @@ blink::ContentSecurityPolicyPtr ConvertToBlink( ...@@ -133,6 +133,7 @@ blink::ContentSecurityPolicyPtr ConvertToBlink(
? base::Optional<WTF::Vector<WTF::String>>( ? base::Optional<WTF::Vector<WTF::String>>(
ConvertToBlink(std::move(policy_in->plugin_types.value()))) ConvertToBlink(std::move(policy_in->plugin_types.value())))
: base::nullopt, : base::nullopt,
policy_in->require_trusted_types_for,
ConvertToBlink(std::move(policy_in->parsing_errors))); ConvertToBlink(std::move(policy_in->parsing_errors)));
} }
......
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