Title: [284959] trunk
Revision
284959
Author
katherine_che...@apple.com
Date
2021-10-27 14:34:04 -0700 (Wed, 27 Oct 2021)

Log Message

REGRESSION (r284650-284661): [iOS15 Sim] imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html is a text failure
https://bugs.webkit.org/show_bug.cgi?id=232120
<rdar://problem/84529888>

Reviewed by Brent Fulgham.

LayoutTests/imported/w3c:

* web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms-expected.txt:

Source/WebCore:

Flaky test was caused by a race condition between 2 error messages in
the test. To fix the flakiness, this patch fixes a bug so the test
will now pass.

This adds support for multiple CSP policies with different hashes for the
same script, e.g. one for sha256 and one for sha384. Instead of
sending the hash from one algorithm to check against all policies, we
now send hashes from all specified algorithms and make sure each
policy allows at least one of them.

* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::findHashOfContentInPolicies const):
* page/csp/ContentSecurityPolicyDirectiveList.cpp:
(WebCore::checkUnsafeHashes):
(WebCore::checkHashes):
(WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashScript const):
(WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashStyle const):
(WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash const):
(WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleHash const):
(WebCore::checkHash): Deleted.
* page/csp/ContentSecurityPolicyDirectiveList.h:
* page/csp/ContentSecurityPolicySourceList.cpp:
(WebCore::ContentSecurityPolicySourceList::matches const):
* page/csp/ContentSecurityPolicySourceList.h:
* page/csp/ContentSecurityPolicySourceListDirective.cpp:
(WebCore::ContentSecurityPolicySourceListDirective::allows const):
(WebCore::ContentSecurityPolicySourceListDirective::allowUnsafeHashes const):
* page/csp/ContentSecurityPolicySourceListDirective.h:

LayoutTests:

* platform/ios-wk2/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (284958 => 284959)


--- trunk/LayoutTests/ChangeLog	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/LayoutTests/ChangeLog	2021-10-27 21:34:04 UTC (rev 284959)
@@ -1,3 +1,13 @@
+2021-10-27  Kate Cheney  <katherine_che...@apple.com>
+
+        REGRESSION (r284650-284661): [iOS15 Sim] imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html is a text failure
+        https://bugs.webkit.org/show_bug.cgi?id=232120
+        <rdar://problem/84529888>
+
+        Reviewed by Brent Fulgham.
+
+        * platform/ios-wk2/TestExpectations:
+
 2021-10-27  Simon Fraser  <simon.fra...@apple.com>
 
         Preserve image diff precision until display time

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (284958 => 284959)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-27 21:34:04 UTC (rev 284959)
@@ -1,3 +1,13 @@
+2021-10-27  Kate Cheney  <katherine_che...@apple.com>
+
+        REGRESSION (r284650-284661): [iOS15 Sim] imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html is a text failure
+        https://bugs.webkit.org/show_bug.cgi?id=232120
+        <rdar://problem/84529888>
+
+        Reviewed by Brent Fulgham.
+
+        * web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms-expected.txt:
+
 2021-10-27  Chris Dumez  <cdu...@apple.com>
 
         _javascript_ URL result should be treated as UTF-8 bytes

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms-expected.txt (284958 => 284959)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms-expected.txt	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms-expected.txt	2021-10-27 21:34:04 UTC (rev 284959)
@@ -1,3 +1,3 @@
 
-FAIL Test that script executes if allowed by proper hash values assert_true: expected true got false
+PASS Test that script executes if allowed by proper hash values
 

Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (284958 => 284959)


--- trunk/LayoutTests/platform/ios-wk2/TestExpectations	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations	2021-10-27 21:34:04 UTC (rev 284959)
@@ -2238,8 +2238,6 @@
 
 webkit.org/b/232099 imported/w3c/web-platform-tests/websockets/Close-1000.any.html [ Pass Crash ]
 
-webkit.org/b/232120 imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html [ Pass Failure DumpJSConsoleLogInStdErr ]
-
 webkit.org/b/225528 http/wpt/fetch/fetch-response-body-stop-in-worker.html [ Pass Crash ]
 
 webkit.org/b/232252 [ Release ] imported/w3c/web-platform-tests/webrtc/RTCDtlsTransport-state.html [ Pass Failure ]

Modified: trunk/Source/WebCore/ChangeLog (284958 => 284959)


--- trunk/Source/WebCore/ChangeLog	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/ChangeLog	2021-10-27 21:34:04 UTC (rev 284959)
@@ -1,3 +1,40 @@
+2021-10-27  Kate Cheney  <katherine_che...@apple.com>
+
+        REGRESSION (r284650-284661): [iOS15 Sim] imported/w3c/web-platform-tests/content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html is a text failure
+        https://bugs.webkit.org/show_bug.cgi?id=232120
+        <rdar://problem/84529888>
+
+        Reviewed by Brent Fulgham.
+
+        Flaky test was caused by a race condition between 2 error messages in
+        the test. To fix the flakiness, this patch fixes a bug so the test
+        will now pass.
+
+        This adds support for multiple CSP policies with different hashes for the
+        same script, e.g. one for sha256 and one for sha384. Instead of
+        sending the hash from one algorithm to check against all policies, we
+        now send hashes from all specified algorithms and make sure each
+        policy allows at least one of them.
+
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::ContentSecurityPolicy::findHashOfContentInPolicies const):
+        * page/csp/ContentSecurityPolicyDirectiveList.cpp:
+        (WebCore::checkUnsafeHashes):
+        (WebCore::checkHashes):
+        (WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashScript const):
+        (WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashStyle const):
+        (WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash const):
+        (WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleHash const):
+        (WebCore::checkHash): Deleted.
+        * page/csp/ContentSecurityPolicyDirectiveList.h:
+        * page/csp/ContentSecurityPolicySourceList.cpp:
+        (WebCore::ContentSecurityPolicySourceList::matches const):
+        * page/csp/ContentSecurityPolicySourceList.h:
+        * page/csp/ContentSecurityPolicySourceListDirective.cpp:
+        (WebCore::ContentSecurityPolicySourceListDirective::allows const):
+        (WebCore::ContentSecurityPolicySourceListDirective::allowUnsafeHashes const):
+        * page/csp/ContentSecurityPolicySourceListDirective.h:
+
 2021-10-27  Chris Dumez  <cdu...@apple.com>
 
         _javascript_ URL result should be treated as UTF-8 bytes

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp	2021-10-27 21:34:04 UTC (rev 284959)
@@ -371,15 +371,16 @@
     auto encodedContent = encodingToUse.encode(content, UnencodableHandling::Entities);
     bool foundHashInEnforcedPolicies = false;
     bool foundHashInReportOnlyPolicies = false;
+    Vector<ContentSecurityPolicyHash> hashes;
     for (auto algorithm : algorithms) {
-        ContentSecurityPolicyHash hash = cryptographicDigestForBytes(algorithm, encodedContent.data(), encodedContent.size());
-        if (!foundHashInEnforcedPolicies && allPoliciesWithDispositionAllow(ContentSecurityPolicy::Disposition::Enforce, predicate, hash))
-            foundHashInEnforcedPolicies = true;
-        if (!foundHashInReportOnlyPolicies && allPoliciesWithDispositionAllow(ContentSecurityPolicy::Disposition::ReportOnly, predicate, hash))
-            foundHashInReportOnlyPolicies = true;
-        if (foundHashInEnforcedPolicies && foundHashInReportOnlyPolicies)
-            break;
+        auto hash = cryptographicDigestForBytes(algorithm, encodedContent.data(), encodedContent.size());
+        hashes.append(hash);
     }
+    if (!foundHashInEnforcedPolicies && allPoliciesWithDispositionAllow(ContentSecurityPolicy::Disposition::Enforce, predicate, hashes))
+        foundHashInEnforcedPolicies = true;
+    if (!foundHashInReportOnlyPolicies && allPoliciesWithDispositionAllow(ContentSecurityPolicy::Disposition::ReportOnly, predicate, hashes))
+        foundHashInReportOnlyPolicies = true;
+
     return { foundHashInEnforcedPolicies, foundHashInReportOnlyPolicies };
 }
 

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp	2021-10-27 21:34:04 UTC (rev 284959)
@@ -56,9 +56,9 @@
     return !directive || directive->allowInline();
 }
 
-static inline bool checkUnsafeHashes(ContentSecurityPolicySourceListDirective* directive, const ContentSecurityPolicyHash& hash)
+static inline bool checkUnsafeHashes(ContentSecurityPolicySourceListDirective* directive, const Vector<ContentSecurityPolicyHash>& hashes)
 {
-    return !directive || directive->allowUnsafeHashes(hash);
+    return !directive || directive->allowUnsafeHashes(hashes);
 }
 
 static inline bool checkNonParserInsertedScripts(ContentSecurityPolicySourceListDirective* directive, ParserInserted parserInserted)
@@ -74,9 +74,9 @@
     return !directive || directive->allows(url, didReceiveRedirectResponse, shouldAllowEmptyURLIfSourceListEmpty);
 }
 
-static inline bool checkHash(ContentSecurityPolicySourceListDirective* directive, const ContentSecurityPolicyHash& hash)
+static inline bool checkHashes(ContentSecurityPolicySourceListDirective* directive, const Vector<ContentSecurityPolicyHash>& hashes)
 {
-    return !directive || directive->allows(hash);
+    return !directive || directive->allows(hashes);
 }
 
 static inline bool checkNonce(ContentSecurityPolicySourceListDirective* directive, const String& nonce)
@@ -190,18 +190,18 @@
     return operativeDirective;
 }
 
-const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashScript(const ContentSecurityPolicyHash& hash) const
+const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashScript(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
     auto* operativeDirective = this->operativeDirective(m_scriptSrc.get(), ContentSecurityPolicyDirectiveNames::scriptSrc);
-    if (checkUnsafeHashes(operativeDirective, hash))
+    if (checkUnsafeHashes(operativeDirective, hashes))
         return nullptr;
     return operativeDirective;
 }
 
-const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashStyle(const ContentSecurityPolicyHash& hash) const
+const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashStyle(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
     auto* operativeDirective = this->operativeDirective(m_styleSrc.get(), ContentSecurityPolicyDirectiveNames::scriptSrc);
-    if (checkUnsafeHashes(operativeDirective, hash))
+    if (checkUnsafeHashes(operativeDirective, hashes))
         return nullptr;
     return operativeDirective;
 }
@@ -247,18 +247,18 @@
     return operativeDirective;
 }
 
-const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash(const ContentSecurityPolicyHash& hash) const
+const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
     auto* operativeDirective = this->operativeDirective(m_scriptSrc.get(), ContentSecurityPolicyDirectiveNames::scriptSrc);
-    if (checkHash(operativeDirective, hash))
+    if (checkHashes(operativeDirective, hashes))
         return nullptr;
     return operativeDirective;
 }
 
-const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleHash(const ContentSecurityPolicyHash& hash) const
+const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleHash(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
     auto* operativeDirective = this->operativeDirective(m_styleSrc.get(), ContentSecurityPolicyDirectiveNames::styleSrc);
-    if (checkHash(operativeDirective, hash))
+    if (checkHashes(operativeDirective, hashes))
         return nullptr;
     return operativeDirective;
 }

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h	2021-10-27 21:34:04 UTC (rev 284959)
@@ -52,10 +52,10 @@
     const ContentSecurityPolicyDirective* violatedDirectiveForUnsafeInlineStyleElement() const;
     const ContentSecurityPolicyDirective* violatedDirectiveForUnsafeInlineStyleAttribute() const;
 
-    const ContentSecurityPolicyDirective* violatedDirectiveForScriptHash(const ContentSecurityPolicyHash&) const;
-    const ContentSecurityPolicyDirective* violatedDirectiveForStyleHash(const ContentSecurityPolicyHash&) const;
-    const ContentSecurityPolicyDirective* violatedDirectiveForUnsafeHashScript(const ContentSecurityPolicyHash&) const;
-    const ContentSecurityPolicyDirective* violatedDirectiveForUnsafeHashStyle(const ContentSecurityPolicyHash&) const;
+    const ContentSecurityPolicyDirective* violatedDirectiveForScriptHash(const Vector<ContentSecurityPolicyHash>&) const;
+    const ContentSecurityPolicyDirective* violatedDirectiveForStyleHash(const Vector<ContentSecurityPolicyHash>&) const;
+    const ContentSecurityPolicyDirective* violatedDirectiveForUnsafeHashScript(const Vector<ContentSecurityPolicyHash>&) const;
+    const ContentSecurityPolicyDirective* violatedDirectiveForUnsafeHashStyle(const Vector<ContentSecurityPolicyHash>&) const;
 
     const ContentSecurityPolicyDirective* violatedDirectiveForScriptNonce(const String&) const;
     const ContentSecurityPolicyDirective* violatedDirectiveForStyleNonce(const String&) const;

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp	2021-10-27 21:34:04 UTC (rev 284959)
@@ -145,9 +145,14 @@
     return false;
 }
 
-bool ContentSecurityPolicySourceList::matches(const ContentSecurityPolicyHash& hash) const
+bool ContentSecurityPolicySourceList::matches(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
-    return m_hashes.contains(hash);
+    for (auto& hash : hashes) {
+        if (m_hashes.contains(hash))
+            return true;
+    }
+
+    return false;
 }
 
 bool ContentSecurityPolicySourceList::matches(const String& nonce) const

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h	2021-10-27 21:34:04 UTC (rev 284959)
@@ -44,7 +44,7 @@
     void parse(const String&);
 
     bool matches(const URL&, bool didReceiveRedirectResponse) const;
-    bool matches(const ContentSecurityPolicyHash&) const;
+    bool matches(const Vector<ContentSecurityPolicyHash>&) const;
     bool matches(const String& nonce) const;
 
     OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsUsed() const { return m_hashAlgorithmsUsed; }

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp	2021-10-27 21:34:04 UTC (rev 284959)
@@ -52,14 +52,14 @@
     return m_sourceList.matches(nonce);
 }
 
-bool ContentSecurityPolicySourceListDirective::allows(const ContentSecurityPolicyHash& hash) const
+bool ContentSecurityPolicySourceListDirective::allows(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
-    return m_sourceList.matches(hash);
+    return m_sourceList.matches(hashes);
 }
 
-bool ContentSecurityPolicySourceListDirective::allowUnsafeHashes(const ContentSecurityPolicyHash& hash) const
+bool ContentSecurityPolicySourceListDirective::allowUnsafeHashes(const Vector<ContentSecurityPolicyHash>& hashes) const
 {
-    return m_sourceList.allowUnsafeHashes() && allows(hash);
+    return m_sourceList.allowUnsafeHashes() && allows(hashes);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h (284958 => 284959)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h	2021-10-27 21:23:40 UTC (rev 284958)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h	2021-10-27 21:34:04 UTC (rev 284959)
@@ -39,8 +39,8 @@
 
     enum class ShouldAllowEmptyURLIfSourceListIsNotNone { No, Yes };
     bool allows(const URL&, bool didReceiveRedirectResponse, ShouldAllowEmptyURLIfSourceListIsNotNone);
-    bool allows(const ContentSecurityPolicyHash&) const;
-    bool allowUnsafeHashes(const ContentSecurityPolicyHash&) const;
+    bool allows(const Vector<ContentSecurityPolicyHash>&) const;
+    bool allowUnsafeHashes(const Vector<ContentSecurityPolicyHash>&) const;
     bool allows(const String& nonce) const;
     bool allowInline() const { return m_sourceList.allowInline(); }
     bool allowEval() const { return m_sourceList.allowEval(); }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to