| Index: third_party/WebKit/Source/core/frame/csp/CSPDirectiveListTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveListTest.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveListTest.cpp
|
| index 86f819efed137e93a3c26eb22bd2d840b3417a89..5546fc54d3d4ced6dfafab95209867cb3be182d4 100644
|
| --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveListTest.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveListTest.cpp
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "core/frame/csp/CSPDirectiveList.h"
|
|
|
| +#include "core/frame/SubresourceIntegrity.h"
|
| #include "core/frame/csp/ContentSecurityPolicy.h"
|
| #include "core/frame/csp/SourceListDirective.h"
|
| #include "platform/loader/fetch/ResourceRequest.h"
|
| @@ -165,7 +166,7 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceNoNonce) {
|
| createList(test.list, ContentSecurityPolicyHeaderTypeReport);
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowScriptFromSource(
|
| - scriptSrc, String(), ParserInserted,
|
| + scriptSrc, String(), IntegrityMetadataSet(), ParserInserted,
|
| ResourceRequest::RedirectStatus::NoRedirect,
|
| SecurityViolationReportingPolicy::SuppressReporting));
|
|
|
| @@ -174,7 +175,7 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceNoNonce) {
|
| createList(test.list, ContentSecurityPolicyHeaderTypeEnforce);
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowScriptFromSource(
|
| - scriptSrc, String(), ParserInserted,
|
| + scriptSrc, String(), IntegrityMetadataSet(), ParserInserted,
|
| ResourceRequest::RedirectStatus::NoRedirect,
|
| SecurityViolationReportingPolicy::SuppressReporting));
|
| }
|
| @@ -222,8 +223,8 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
|
| ContentSecurityPolicyHeaderTypeReport);
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowScriptFromSource(
|
| - resource, String(test.nonce), ParserInserted,
|
| - ResourceRequest::RedirectStatus::NoRedirect,
|
| + resource, String(test.nonce), IntegrityMetadataSet(),
|
| + ParserInserted, ResourceRequest::RedirectStatus::NoRedirect,
|
| SecurityViolationReportingPolicy::SuppressReporting));
|
|
|
| // Enforce 'script-src'
|
| @@ -231,8 +232,8 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
|
| ContentSecurityPolicyHeaderTypeEnforce);
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowScriptFromSource(
|
| - resource, String(test.nonce), ParserInserted,
|
| - ResourceRequest::RedirectStatus::NoRedirect,
|
| + resource, String(test.nonce), IntegrityMetadataSet(),
|
| + ParserInserted, ResourceRequest::RedirectStatus::NoRedirect,
|
| SecurityViolationReportingPolicy::SuppressReporting));
|
|
|
| // Report-only 'style-src'
|
| @@ -258,8 +259,8 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
|
| ContentSecurityPolicyHeaderTypeReport);
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowScriptFromSource(
|
| - resource, String(test.nonce), ParserInserted,
|
| - ResourceRequest::RedirectStatus::NoRedirect,
|
| + resource, String(test.nonce), IntegrityMetadataSet(),
|
| + ParserInserted, ResourceRequest::RedirectStatus::NoRedirect,
|
| SecurityViolationReportingPolicy::SuppressReporting));
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowStyleFromSource(
|
| @@ -272,8 +273,8 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
|
| ContentSecurityPolicyHeaderTypeEnforce);
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowScriptFromSource(
|
| - resource, String(test.nonce), ParserInserted,
|
| - ResourceRequest::RedirectStatus::NoRedirect,
|
| + resource, String(test.nonce), IntegrityMetadataSet(),
|
| + ParserInserted, ResourceRequest::RedirectStatus::NoRedirect,
|
| SecurityViolationReportingPolicy::SuppressReporting));
|
| EXPECT_EQ(test.expected,
|
| directiveList->allowStyleFromSource(
|
| @@ -283,6 +284,103 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
|
| }
|
| }
|
|
|
| +TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) {
|
| + struct TestCase {
|
| + const char* list;
|
| + const char* url;
|
| + const char* integrity;
|
| + bool expected;
|
| + } cases[] = {
|
| + // Doesn't affect lists without hashes.
|
| + {"https://example.com", "https://example.com/file", "sha256-yay", true},
|
| + {"https://example.com", "https://example.com/file", "sha256-boo", true},
|
| + {"https://example.com", "https://example.com/file", "", true},
|
| + {"https://example.com", "https://not.example.com/file", "sha256-yay",
|
| + false},
|
| + {"https://example.com", "https://not.example.com/file", "sha256-boo",
|
| + false},
|
| + {"https://example.com", "https://not.example.com/file", "", false},
|
| +
|
| + // Doesn't affect URLs that match the whitelist.
|
| + {"https://example.com 'sha256-yay'", "https://example.com/file",
|
| + "sha256-yay", true},
|
| + {"https://example.com 'sha256-yay'", "https://example.com/file",
|
| + "sha256-boo", true},
|
| + {"https://example.com 'sha256-yay'", "https://example.com/file", "",
|
| + true},
|
| +
|
| + // Does affect URLs that don't match the whitelist.
|
| + {"https://example.com 'sha256-yay'", "https://not.example.com/file",
|
| + "sha256-yay", true},
|
| + {"https://example.com 'sha256-yay'", "https://not.example.com/file",
|
| + "sha256-boo", false},
|
| + {"https://example.com 'sha256-yay'", "https://not.example.com/file", "",
|
| + false},
|
| +
|
| + // Both algorithm and digest must match.
|
| + {"'sha256-yay'", "https://a.com/file", "sha384-yay", false},
|
| +
|
| + // Sha-1 is not supported, but -384 and -512 are.
|
| + {"'sha1-yay'", "https://a.com/file", "sha1-yay", false},
|
| + {"'sha384-yay'", "https://a.com/file", "sha384-yay", true},
|
| + {"'sha512-yay'", "https://a.com/file", "sha512-yay", true},
|
| +
|
| + // Unknown (or future) hash algorithms don't work.
|
| + {"'asdf256-yay'", "https://a.com/file", "asdf256-yay", false},
|
| +
|
| + // But they also don't interfere.
|
| + {"'sha256-yay'", "https://a.com/file", "sha256-yay asdf256-boo", true},
|
| +
|
| + // Additional whitelisted hashes in the CSP don't interfere.
|
| + {"'sha256-yay' 'sha384-boo'", "https://a.com/file", "sha256-yay", true},
|
| + {"'sha256-yay' 'sha384-boo'", "https://a.com/file", "sha384-boo", true},
|
| +
|
| + // All integrity hashes must appear in the CSP (and match).
|
| + {"'sha256-yay'", "https://a.com/file", "sha256-yay sha384-boo", false},
|
| + {"'sha384-boo'", "https://a.com/file", "sha256-yay sha384-boo", false},
|
| + {"'sha256-yay' 'sha384-boo'", "https://a.com/file",
|
| + "sha256-yay sha384-yay", false},
|
| + {"'sha256-yay' 'sha384-boo'", "https://a.com/file",
|
| + "sha256-boo sha384-boo", false},
|
| + {"'sha256-yay' 'sha384-boo'", "https://a.com/file",
|
| + "sha256-yay sha384-boo", true},
|
| +
|
| + // At least one integrity hash must be present.
|
| + {"'sha256-yay'", "https://a.com/file", "", false},
|
| + };
|
| +
|
| + for (const auto& test : cases) {
|
| + SCOPED_TRACE(testing::Message()
|
| + << "List: `" << test.list << "`, URL: `" << test.url
|
| + << "`, Integrity: `" << test.integrity << "`");
|
| + KURL resource = KURL(KURL(), test.url);
|
| +
|
| + IntegrityMetadataSet integrityMetadata;
|
| + ASSERT_EQ(SubresourceIntegrity::IntegrityParseValidResult,
|
| + SubresourceIntegrity::parseIntegrityAttribute(test.integrity,
|
| + integrityMetadata));
|
| +
|
| + // Report-only 'script-src'
|
| + Member<CSPDirectiveList> directiveList =
|
| + createList(String("script-src ") + test.list,
|
| + ContentSecurityPolicyHeaderTypeReport);
|
| + EXPECT_EQ(test.expected,
|
| + directiveList->allowScriptFromSource(
|
| + resource, String(), integrityMetadata, ParserInserted,
|
| + ResourceRequest::RedirectStatus::NoRedirect,
|
| + SecurityViolationReportingPolicy::SuppressReporting));
|
| +
|
| + // Enforce 'script-src'
|
| + directiveList = createList(String("script-src ") + test.list,
|
| + ContentSecurityPolicyHeaderTypeEnforce);
|
| + EXPECT_EQ(test.expected,
|
| + directiveList->allowScriptFromSource(
|
| + resource, String(), integrityMetadata, ParserInserted,
|
| + ResourceRequest::RedirectStatus::NoRedirect,
|
| + SecurityViolationReportingPolicy::SuppressReporting));
|
| + }
|
| +}
|
| +
|
| TEST_F(CSPDirectiveListTest, allowRequestWithoutIntegrity) {
|
| struct TestCase {
|
| const char* list;
|
|
|