Changeset 286853 in webkit
- Timestamp:
- Dec 10, 2021, 8:56:55 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 20 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt (modified) (2 diffs)
-
LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-sri_hash.sub-expected.txt (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/loader/DocumentThreadableLoader.cpp (modified) (1 diff)
-
Source/WebCore/loader/ResourceCryptographicDigest.cpp (modified) (2 diffs)
-
Source/WebCore/loader/SubresourceIntegrity.cpp (modified) (1 diff)
-
Source/WebCore/loader/SubresourceIntegrity.h (modified) (1 diff)
-
Source/WebCore/loader/cache/CachedResourceLoader.cpp (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicy.cpp (modified) (3 diffs)
-
Source/WebCore/page/csp/ContentSecurityPolicy.h (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicySourceList.h (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp (modified) (1 diff)
-
Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r286848 r286853 1 2021-12-10 Patrick Griffis <pgriffis@igalia.com> 2 3 CSP: Allow external scripts with SRI hashes matching CSP 4 https://bugs.webkit.org/show_bug.cgi?id=233911 5 6 Reviewed by Kate Cheney. 7 8 Update tests to accept base64 with extra padding. 9 10 * http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt: 11 * http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html: 12 1 13 2021-12-10 Alan Bujtas <zalan@apple.com> 2 14 -
trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests-expected.txt
r259900 r286853 12 12 CONSOLE MESSAGE: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. 13 13 CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-/Vet2Rva6wwsny8xybL+=bQal0Gtf0FZW7EOVqqg+Hna=''. It will be ignored. 14 CONSOLE MESSAGE: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy.15 CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA==''. It will be ignored.16 14 CONSOLE MESSAGE: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. 17 15 CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA===''. It will be ignored. … … 54 52 PASS "SHA-256 hash with SHA-512 prefix" did not run inline script. 55 53 PASS "Malformed SHA-256 hash (equal sign in disallowed position)" did not run inline script. 56 PASS "SHA-256 hash with one extraneous equal sign" did notrun inline script.54 PASS "SHA-256 hash with one extraneous equal sign" did run inline script. 57 55 PASS "SHA-256 hash with two extraneous equal signs" did not run inline script. 58 56 PASS "Malformed hash source" did not run inline script. -
trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html
r275917 r286853 160 160 script: encodeURIComponent("didRunInlineScript = true;"), 161 161 hashSource: "'sha256-/vET2rVA6WWSNY8XYBl+BqAL0gTF0fzw7eovQQG+hNA=='", 162 expectedResult: DoNotRunInlineScript,162 expectedResult: RunInlineScript, 163 163 }, 164 164 { -
trunk/LayoutTests/imported/w3c/ChangeLog
r286847 r286853 1 2021-12-10 Patrick Griffis <pgriffis@igalia.com> 2 3 CSP: Allow external scripts with SRI hashes matching CSP 4 https://bugs.webkit.org/show_bug.cgi?id=233911 5 6 Reviewed by Kate Cheney. 7 8 Update expectations with more passes. 9 10 * web-platform-tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy-expected.txt: 11 * web-platform-tests/content-security-policy/script-src/script-src-sri_hash.sub-expected.txt: 12 1 13 2021-12-10 Manuel Rego Casasnovas <rego@igalia.com> 2 14 -
trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-report-only-policy-works-with-external-hash-policy-expected.txt
r284254 r286853 1 1 2 FAIL Should fire securitypolicyviolation event assert_equals: expected "report" but got "enforce" 3 FAIL External script in a script tag with matching SRI hash should run. assert_true: External script ran. expected true got false 2 PASS Should fire securitypolicyviolation event 3 PASS External script in a script tag with matching SRI hash should run. 4 4 -
trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-sri_hash.sub-expected.txt
r267651 r286853 3 3 4 4 PASS Load all the tests. 5 FAIL matching integrity assert_unreached: Script should load! http://localhost:8800/content-security-policy/script-src/simpleSourcedScript.js Reached unreachable code 6 FAIL multiple matching integrity assert_unreached: Script should load! http://localhost:8800/content-security-policy/script-src/simpleSourcedScript.js Reached unreachable code 5 PASS matching integrity 6 PASS multiple matching integrity 7 7 PASS no integrity 8 FAIL matching plus unsupported integrity assert_unreached: Script should load! http://localhost:8800/content-security-policy/script-src/simpleSourcedScript.js Reached unreachable code 8 PASS matching plus unsupported integrity 9 9 PASS mismatched integrity 10 10 PASS multiple mismatched integrity … … 12 12 FAIL crossorigin no integrity but allowed host assert_unreached: Script should load! http://127.0.0.1:8800/content-security-policy/script-src/crossoriginScript.js Reached unreachable code 13 13 FAIL crossorigin mismatched integrity but allowed host assert_unreached: Script should load! http://127.0.0.1:8800/content-security-policy/script-src/crossoriginScript.js Reached unreachable code 14 FAIL External script in a script tag with matching SRI hash should run. assert_true: External script ran. expected true got false 14 PASS External script in a script tag with matching SRI hash should run. 15 15 -
trunk/Source/WebCore/ChangeLog
r286851 r286853 1 2021-12-10 Patrick Griffis <pgriffis@igalia.com> 2 3 CSP: Allow external scripts with SRI hashes matching CSP 4 https://bugs.webkit.org/show_bug.cgi?id=233911 5 6 Reviewed by Kate Cheney. 7 8 This is a change in CSP3 that allows loading external 9 scripts that have SRI hashes matching CSP hashes. 10 https://www.w3.org/TR/CSP3/#external-hash 11 12 ResourceCryptographicDigest was changed to not validate padding 13 during base64 decoding which is harmless and fixes parsing the 14 hashes used in WPT's script-src-sri_hash.sub.html. 15 16 * loader/DocumentThreadableLoader.cpp: 17 (WebCore::DocumentThreadableLoader::isAllowedByContentSecurityPolicy): 18 * loader/ResourceCryptographicDigest.cpp: 19 (WebCore::parseCryptographicDigestImpl): 20 (WebCore::decodeEncodedResourceCryptographicDigest): 21 * loader/SubresourceIntegrity.cpp: 22 (WebCore::parseIntegrityMetadata): 23 * loader/SubresourceIntegrity.h: 24 * loader/cache/CachedResourceLoader.cpp: 25 (WebCore::CachedResourceLoader::allowedByContentSecurityPolicy const): 26 * page/csp/ContentSecurityPolicy.cpp: 27 (WebCore::ContentSecurityPolicy::allScriptPoliciesAllow const): 28 (WebCore::parseSubResourceIntegrityIntoDigests): 29 (WebCore::ContentSecurityPolicy::allowResourceFromSource const): 30 (WebCore::ContentSecurityPolicy::allowScriptFromSource const): 31 * page/csp/ContentSecurityPolicy.h: 32 * page/csp/ContentSecurityPolicyDirectiveList.cpp: 33 (WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForScript const): 34 * page/csp/ContentSecurityPolicyDirectiveList.h: 35 * page/csp/ContentSecurityPolicySourceList.cpp: 36 (WebCore::ContentSecurityPolicySourceList::matchesAll const): 37 * page/csp/ContentSecurityPolicySourceList.h: 38 * page/csp/ContentSecurityPolicySourceListDirective.cpp: 39 (WebCore::ContentSecurityPolicySourceListDirective::containsAllHashes const): 40 * page/csp/ContentSecurityPolicySourceListDirective.h: 41 1 42 2021-12-10 Alan Bujtas <zalan@apple.com> 2 43 -
trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp
r286094 r286853 686 686 return contentSecurityPolicy().allowConnectToSource(url, redirectResponseReceived, preRedirectURL); 687 687 case ContentSecurityPolicyEnforcement::EnforceScriptSrcDirective: 688 return contentSecurityPolicy().allowScriptFromSource(url, redirectResponseReceived, preRedirectURL );688 return contentSecurityPolicy().allowScriptFromSource(url, redirectResponseReceived, preRedirectURL, m_options.integrity); 689 689 } 690 690 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/loader/ResourceCryptographicDigest.cpp
r278758 r286853 72 72 StringView hashValue(beginHashValue, buffer.position() - beginHashValue); 73 73 74 if (auto digest = base64Decode(hashValue , Base64DecodeOptions::ValidatePadding))74 if (auto digest = base64Decode(hashValue)) 75 75 return ResourceCryptographicDigest { *algorithm, WTFMove(*digest) }; 76 76 … … 126 126 std::optional<ResourceCryptographicDigest> decodeEncodedResourceCryptographicDigest(const EncodedResourceCryptographicDigest& encodedDigest) 127 127 { 128 if (auto digest = base64Decode(encodedDigest.digest , Base64DecodeOptions::ValidatePadding))128 if (auto digest = base64Decode(encodedDigest.digest)) 129 129 return ResourceCryptographicDigest { encodedDigest.algorithm, WTFMove(*digest) }; 130 130 -
trunk/Source/WebCore/loader/SubresourceIntegrity.cpp
r278702 r286853 97 97 } 98 98 99 st atic std::optional<Vector<EncodedResourceCryptographicDigest>> parseIntegrityMetadata(const String& integrityMetadata)99 std::optional<Vector<EncodedResourceCryptographicDigest>> parseIntegrityMetadata(const String& integrityMetadata) 100 100 { 101 101 if (integrityMetadata.isEmpty()) -
trunk/Source/WebCore/loader/SubresourceIntegrity.h
r251582 r286853 34 34 bool matchIntegrityMetadata(const CachedResource&, const String& integrityMetadata); 35 35 String integrityMismatchDescription(const CachedResource&, const String& integrityMetadata); 36 std::optional<Vector<EncodedResourceCryptographicDigest>> parseIntegrityMetadata(const String& integrityMetadata); 36 37 37 38 } -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp
r286094 r286853 502 502 #endif 503 503 case CachedResource::Type::Script: 504 if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, redirectResponseReceived, preRedirectURL ))504 if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, redirectResponseReceived, preRedirectURL, options.integrity)) 505 505 return false; 506 506 break; -
trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
r286772 r286853 53 53 #include "SecurityPolicyViolationEvent.h" 54 54 #include "Settings.h" 55 #include "SubresourceIntegrity.h" 55 56 #include <JavaScriptCore/ScriptCallStack.h> 56 57 #include <JavaScriptCore/ScriptCallStackFactory.h> … … 340 341 auto violatedDirectiveForNonParserInsertedScript = policy.get()->violatedDirectiveForParserInsertedScript(parserInserted); 341 342 auto violatedDirectiveForScriptNonce = policy.get()->violatedDirectiveForScriptNonce(nonce); 342 auto violatedDirectiveForScriptSrc = policy.get()->violatedDirectiveForScript(url, false );343 auto violatedDirectiveForScriptSrc = policy.get()->violatedDirectiveForScript(url, false, { }); 343 344 auto [foundHashInEnforcedPolicies, foundHashInReportOnlyPolicies] = findHashOfContentInPolicies(&ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash, scriptContent, m_hashAlgorithmsForInlineScripts); 344 345 … … 641 642 } 642 643 643 bool ContentSecurityPolicy::allowScriptFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived, const URL& preRedirectURL) const 644 static Vector<ResourceCryptographicDigest> parseSubResourceIntegrityIntoDigests(const String& subResourceIntegrity) 645 { 646 auto encodedDigests = parseIntegrityMetadata(subResourceIntegrity); 647 Vector<ResourceCryptographicDigest> decodedDigests; 648 649 if (!encodedDigests.has_value()) 650 return { }; 651 652 for (const auto& encodedDigest : encodedDigests.value()) { 653 auto decodedDigest = decodeEncodedResourceCryptographicDigest(encodedDigest); 654 if (decodedDigest.has_value()) 655 decodedDigests.append(decodedDigest.value()); 656 } 657 658 return decodedDigests; 659 } 660 661 bool ContentSecurityPolicy::allowScriptFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived, const URL& preRedirectURL, const String& subResourceIntegrity) const 644 662 { 645 663 if (shouldPerformEarlyCSPCheck()) 646 664 return true; 647 648 return allowResourceFromSource(url, redirectResponseReceived, ContentSecurityPolicyDirectiveNames::scriptSrc, &ContentSecurityPolicyDirectiveList::violatedDirectiveForScript, preRedirectURL); 665 if (LegacySchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol().toStringWithoutCopying())) 666 return true; 667 668 String sourceURL; 669 const auto& blockedURL = !preRedirectURL.isNull() ? preRedirectURL : url; 670 TextPosition sourcePosition(OrdinalNumber::beforeFirst(), OrdinalNumber()); 671 auto handleViolatedDirective = [&] (const ContentSecurityPolicyDirective& violatedDirective) { 672 String consoleMessage = consoleMessageForViolation(ContentSecurityPolicyDirectiveNames::scriptSrc, violatedDirective, blockedURL, "Refused to load"); 673 reportViolation(ContentSecurityPolicyDirectiveNames::scriptSrc, violatedDirective, blockedURL.string(), consoleMessage, sourceURL, StringView(), sourcePosition); 674 }; 675 676 auto subResourceIntegrityDigests = parseSubResourceIntegrityIntoDigests(subResourceIntegrity); 677 return allPoliciesAllow(WTFMove(handleViolatedDirective), &ContentSecurityPolicyDirectiveList::violatedDirectiveForScript, url, redirectResponseReceived == RedirectResponseReceived::Yes, subResourceIntegrityDigests); 649 678 } 650 679 -
trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h
r286772 r286853 114 114 115 115 enum class RedirectResponseReceived { No, Yes }; 116 WEBCORE_EXPORT bool allowScriptFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No, const URL& preRedirectURL = URL() ) const;116 WEBCORE_EXPORT bool allowScriptFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No, const URL& preRedirectURL = URL(), const String& = nullString()) const; 117 117 bool allowImageFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No, const URL& preRedirectURL = URL()) const; 118 118 bool allowStyleFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No, const URL& preRedirectURL = URL()) const; -
trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp
r286150 r286853 388 388 } 389 389 390 const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScript(const URL& url, bool didReceiveRedirectResponse ) const390 const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScript(const URL& url, bool didReceiveRedirectResponse, const Vector<ResourceCryptographicDigest>& subResourceIntegrityDigests) const 391 391 { 392 392 auto* operativeDirective = this->operativeDirective(m_scriptSrc.get(), ContentSecurityPolicyDirectiveNames::scriptSrcElem); 393 394 if (operativeDirective->containsAllHashes(subResourceIntegrityDigests)) 395 return nullptr; 396 393 397 if (checkSource(operativeDirective, url, didReceiveRedirectResponse)) 394 398 return nullptr; -
trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h
r286150 r286853 76 76 const ContentSecurityPolicyDirective* violatedDirectiveForObjectSource(const URL&, bool didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone) const; 77 77 const ContentSecurityPolicyDirective* violatedDirectiveForPluginType(const String& type, const String& typeAttribute) const; 78 const ContentSecurityPolicyDirective* violatedDirectiveForScript(const URL&, bool didReceiveRedirectResponse ) const;78 const ContentSecurityPolicyDirective* violatedDirectiveForScript(const URL&, bool didReceiveRedirectResponse, const Vector<ResourceCryptographicDigest>&) const; 79 79 const ContentSecurityPolicyDirective* violatedDirectiveForStyle(const URL&, bool didReceiveRedirectResponse) const; 80 80 -
trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp
r286772 r286853 156 156 } 157 157 158 bool ContentSecurityPolicySourceList::matchesAll(const Vector<ContentSecurityPolicyHash>& hashes) const 159 { 160 if (hashes.isEmpty()) 161 return false; 162 163 for (auto& hash : hashes) { 164 if (!m_hashes.contains(hash)) 165 return false; 166 } 167 168 return true; 169 } 170 158 171 bool ContentSecurityPolicySourceList::matches(const String& nonce) const 159 172 { -
trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h
r286150 r286853 46 46 bool matches(const URL&, bool didReceiveRedirectResponse) const; 47 47 bool matches(const Vector<ContentSecurityPolicyHash>&) const; 48 bool matchesAll(const Vector<ContentSecurityPolicyHash>&) const; 48 49 bool matches(const String& nonce) const; 49 50 -
trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp
r284959 r286853 53 53 } 54 54 55 bool ContentSecurityPolicySourceListDirective::containsAllHashes(const Vector<ContentSecurityPolicyHash>& hashes) const 56 { 57 return m_sourceList.matchesAll(hashes); 58 } 59 55 60 bool ContentSecurityPolicySourceListDirective::allows(const Vector<ContentSecurityPolicyHash>& hashes) const 56 61 { -
trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h
r286150 r286853 41 41 bool allows(const URL&, bool didReceiveRedirectResponse, ShouldAllowEmptyURLIfSourceListIsNotNone); 42 42 bool allows(const Vector<ContentSecurityPolicyHash>&) const; 43 bool containsAllHashes(const Vector<ContentSecurityPolicyHash>&) const; 43 44 bool allowUnsafeHashes(const Vector<ContentSecurityPolicyHash>&) const; 44 45 bool allows(const String& nonce) const;
Note:
See TracChangeset
for help on using the changeset viewer.