Commit d4ce559e authored by Alfonso Castaño's avatar Alfonso Castaño Committed by Commit Bot

Refactor AllowTrustedTypePolicy to provide violation information

Previously, AllowTrustedTypePolicy only returned whether the violation
should be considered as a type error. Now, an enum is added to report
if which type of violation occurred. This enum also gets set in case
of a report-only violation (in which case the method returns true).

Bug: chromium:1142804
Change-Id: I7f5c53ce30ad9c81ef3e3f5a1ae62234eab5ac53
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2517061Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarAndy Paicu <andypaicu@chromium.org>
Reviewed-by: default avatarDaniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: default avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Alfonso Castaño <alcastano@google.com>
Cr-Commit-Position: refs/heads/master@{#827227}
parent 88f2dd7f
......@@ -855,15 +855,31 @@ bool ContentSecurityPolicy::AllowWorkerContextFromSource(
url, RedirectStatus::kNoRedirect);
}
bool ContentSecurityPolicy::AllowTrustedTypePolicy(const String& policy_name,
bool is_duplicate) const {
// The return value indicates whether the policy is allowed or not.
// If the return value is false, the out-parameter violation_details indicates
// the type of the violation, and if the return value is true,
// it indicates if a report-only violation occurred.
bool ContentSecurityPolicy::AllowTrustedTypePolicy(
const String& policy_name,
bool is_duplicate,
AllowTrustedTypePolicyDetails& violation_details) const {
bool is_allowed = true;
violation_details = AllowTrustedTypePolicyDetails::kAllowed;
for (const auto& policy : policies_) {
if (!CheckHeaderTypeMatches(CheckHeaderType::kCheckAll,
policy->HeaderType())) {
continue;
}
is_allowed &= policy->AllowTrustedTypePolicy(policy_name, is_duplicate);
auto new_violation_details = AllowTrustedTypePolicyDetails::kAllowed;
bool new_allowed = policy->AllowTrustedTypePolicy(policy_name, is_duplicate,
new_violation_details);
// Report the first violation that is enforced.
// If there is none, report the first violation that is report-only.
if ((is_allowed && !new_allowed) ||
violation_details == AllowTrustedTypePolicyDetails::kAllowed) {
violation_details = new_violation_details;
}
is_allowed &= new_allowed;
}
return is_allowed;
......
......@@ -213,6 +213,13 @@ class CORE_EXPORT ContentSecurityPolicy final
kCheckReportOnly
};
// Helper type for the method AllowTrustedTypePolicy.
enum AllowTrustedTypePolicyDetails {
kAllowed,
kDisallowedName,
kDisallowedDuplicateName
};
static const size_t kMaxSampleLength = 40;
ContentSecurityPolicy();
......@@ -289,8 +296,10 @@ class CORE_EXPORT ContentSecurityPolicy final
CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowWorkerContextFromSource(const KURL&) const;
bool AllowTrustedTypePolicy(const String& policy_name,
bool is_duplicate) const;
bool AllowTrustedTypePolicy(
const String& policy_name,
bool is_duplicate,
AllowTrustedTypePolicyDetails& violation_details) const;
// Passing 'String()' into the |nonce| arguments in the following methods
// represents an unnonced resource load.
......
......@@ -1060,8 +1060,16 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesNoDirective) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("", ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesSimpleDirective) {
......@@ -1076,28 +1084,65 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesWhitespace) {
csp->DidReceiveHeader("trusted-types one\ntwo\rthree",
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("two", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("three", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("four", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("one", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("four", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("two", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("three", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("four", false, violation_details));
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("one", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("four", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesEmpty) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types", ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_FALSE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName);
EXPECT_FALSE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesStar) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_FALSE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesStarMix) {
......@@ -1105,12 +1150,30 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesStarMix) {
csp->DidReceiveHeader("trusted-types abc * def",
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("abc", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("def", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("ghi", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("abc", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("def", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("ghi", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(csp->AllowTrustedTypePolicy("abc", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("def", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("ghi", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("abc", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("def", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("ghi", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeDupe) {
......@@ -1118,8 +1181,16 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeDupe) {
csp->DidReceiveHeader("trusted-types somepolicy 'allow-duplicates'",
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeDupeStar) {
......@@ -1127,8 +1198,16 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeDupeStar) {
csp->DidReceiveHeader("trusted-types * 'allow-duplicates'",
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesReserved) {
......@@ -1136,26 +1215,68 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesReserved) {
csp->DidReceiveHeader("trusted-types one \"two\" 'three'",
ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("one", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
// Quoted strings are considered 'reserved':
EXPECT_FALSE(csp->AllowTrustedTypePolicy("two", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("\"two\"", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("three", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("'three'", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("two", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("\"two\"", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("three", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("'three'", true));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("two", false, violation_details));
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName);
EXPECT_FALSE(
csp->AllowTrustedTypePolicy("\"two\"", false, violation_details));
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("three", false, violation_details));
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName);
EXPECT_FALSE(
csp->AllowTrustedTypePolicy("'three'", false, violation_details));
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("two", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("\"two\"", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("three", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("'three'", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesReportingStar) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kReport,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeReportingSimple) {
......@@ -1163,8 +1284,15 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypeReportingSimple) {
csp->DidReceiveHeader("trusted-types a b c",
ContentSecurityPolicyType::kReport,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeEnforce) {
......@@ -1233,8 +1361,15 @@ TEST_F(ContentSecurityPolicyTest, DefaultPolicy) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce,
ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("default", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("default", true));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(csp->AllowTrustedTypePolicy("default", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("default", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
TEST_F(ContentSecurityPolicyTest, DirectiveNameCaseInsensitive) {
......@@ -1338,8 +1473,16 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) {
example_url, nonce, IntegrityMetadataSet(), kParserInserted, example_url,
ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", true, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(
csp->AllowTrustedTypePolicy("somepolicy", false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_TRUE(csp->AllowInline(ContentSecurityPolicy::InlineType::kScript,
element, source, nonce, context_url,
ordinal_number));
......
......@@ -758,10 +758,15 @@ bool CSPDirectiveList::AllowFromSource(
return result;
}
bool CSPDirectiveList::AllowTrustedTypePolicy(const String& policy_name,
bool is_duplicate) const {
if (!trusted_types_ || trusted_types_->Allows(policy_name, is_duplicate))
bool CSPDirectiveList::AllowTrustedTypePolicy(
const String& policy_name,
bool is_duplicate,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails& violation_details)
const {
if (!trusted_types_ ||
trusted_types_->Allows(policy_name, is_duplicate, violation_details)) {
return true;
}
ReportViolation(
"trusted-types", ContentSecurityPolicy::DirectiveType::kTrustedTypes,
......
......@@ -86,8 +86,11 @@ class CORE_EXPORT CSPDirectiveList final
const IntegrityMetadataSet& = IntegrityMetadataSet(),
ParserDisposition = kParserInserted) const;
bool AllowTrustedTypePolicy(const String& policy_name,
bool is_duplicate) const;
bool AllowTrustedTypePolicy(
const String& policy_name,
bool is_duplicate,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails& violation_details)
const;
bool AllowDynamic(ContentSecurityPolicy::DirectiveType) const;
bool AllowDynamicWorker() const;
......
......@@ -67,14 +67,28 @@ bool StringListDirective::AllowOrProcessValue(const String& src) {
return IsPolicyName(src);
}
bool StringListDirective::Allows(const String& value, bool is_duplicate) {
if (is_duplicate && !allow_duplicates_)
return false;
if (is_duplicate && value == "default")
return false;
if (!IsPolicyName(value))
return false;
return allow_any_ || list_.Contains(value);
bool StringListDirective::Allows(
const String& value,
bool is_duplicate,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails& violation_details) {
if (is_duplicate && !allow_duplicates_) {
violation_details = ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName;
} else if (is_duplicate && value == "default") {
violation_details = ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName;
} else if (!IsPolicyName(value)) {
violation_details =
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName;
} else if (!(allow_any_ || list_.Contains(value))) {
violation_details =
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kDisallowedName;
} else {
violation_details =
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed;
}
return violation_details ==
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed;
}
void StringListDirective::Trace(Visitor* visitor) const {
......
......@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_STRING_LIST_DIRECTIVE_H_
#include "base/macros.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
......@@ -19,7 +20,10 @@ class CORE_EXPORT StringListDirective final : public CSPDirective {
const String& value,
ContentSecurityPolicy*);
void Trace(Visitor*) const override;
bool Allows(const String& string_piece, bool is_duplicate);
bool Allows(
const String& string_piece,
bool is_duplicate,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails& violation_details);
bool IsAllowDuplicates() const { return allow_duplicates_; }
private:
......
......@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive_list.h"
namespace blink {
......@@ -40,6 +41,7 @@ TEST_F(StringListDirectiveTest, TestAllowLists) {
{"* 'none'", "default none abc", "", false},
{"'allow-duplicates' 'none'", "", "default none abc", true},
};
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details;
for (const auto& test_case : test_cases) {
StringListDirective directive("trusted-types", test_case.directive,
......@@ -51,8 +53,20 @@ TEST_F(StringListDirectiveTest, TestAllowLists) {
SCOPED_TRACE(testing::Message()
<< " trusted-types " << test_case.directive
<< "; allow: " << value);
EXPECT_TRUE(directive.Allows(value, false));
EXPECT_EQ(directive.Allows(value, true), test_case.allow_dupes);
EXPECT_TRUE(directive.Allows(value, false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
EXPECT_EQ(directive.Allows(value, true, violation_details),
test_case.allow_dupes);
if (test_case.allow_dupes) {
EXPECT_EQ(
violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed);
} else {
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
}
}
Vector<String> not_allowed;
......@@ -61,8 +75,20 @@ TEST_F(StringListDirectiveTest, TestAllowLists) {
SCOPED_TRACE(testing::Message()
<< " trusted-types " << test_case.directive
<< "; do not allow: " << value);
EXPECT_FALSE(directive.Allows(value, false));
EXPECT_FALSE(directive.Allows(value, true));
EXPECT_FALSE(directive.Allows(value, false, violation_details));
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedName);
EXPECT_FALSE(directive.Allows(value, true, violation_details));
if (!test_case.allow_dupes || value == "default") {
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName);
} else {
EXPECT_EQ(violation_details,
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedName);
}
}
}
}
......
......@@ -46,21 +46,23 @@ TrustedTypePolicy* TrustedTypePolicyFactory::createPolicy(
}
UseCounter::Count(GetExecutionContext(),
WebFeature::kTrustedTypesCreatePolicy);
if (RuntimeEnabledFeatures::TrustedDOMTypesEnabled(GetExecutionContext()) &&
GetExecutionContext()->GetContentSecurityPolicy() &&
!GetExecutionContext()
GetExecutionContext()->GetContentSecurityPolicy()) {
ContentSecurityPolicy::AllowTrustedTypePolicyDetails violation_details =
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::kAllowed;
bool disallowed = !GetExecutionContext()
->GetContentSecurityPolicy()
->AllowTrustedTypePolicy(policy_name,
policy_map_.Contains(policy_name))) {
->AllowTrustedTypePolicy(
policy_name, policy_map_.Contains(policy_name),
violation_details);
if (disallowed) {
// For a better error message, we'd like to disambiguate between
// "disallowed" and "disallowed because of a duplicate name". Instead of
// piping the reason through all the layers, we'll just check whether it
// had also been disallowed as a non-duplicate name.
// "disallowed" and "disallowed because of a duplicate name".
bool disallowed_because_of_duplicate_name =
policy_map_.Contains(policy_name) &&
GetExecutionContext()
->GetContentSecurityPolicy()
->AllowTrustedTypePolicy(policy_name, false);
violation_details ==
ContentSecurityPolicy::AllowTrustedTypePolicyDetails::
kDisallowedDuplicateName;
const String message =
disallowed_because_of_duplicate_name
? "Policy with name \"" + policy_name + "\" already exists."
......@@ -68,6 +70,7 @@ TrustedTypePolicy* TrustedTypePolicyFactory::createPolicy(
exception_state.ThrowTypeError(message);
return nullptr;
}
}
UseCounter::Count(GetExecutionContext(),
WebFeature::kTrustedTypesPolicyCreated);
if (policy_name == "default") {
......
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