Diff
Modified: releases/WebKitGTK/webkit-2.34/LayoutTests/imported/w3c/ChangeLog (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/LayoutTests/imported/w3c/ChangeLog 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/LayoutTests/imported/w3c/ChangeLog 2021-12-17 22:48:02 UTC (rev 287209)
@@ -1,3 +1,14 @@
+2021-09-02 Chris Dumez <[email protected]>
+
+ [COOP] html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox.html WPT test is failing
+ https://bugs.webkit.org/show_bug.cgi?id=229716
+
+ Reviewed by Darin Adler.
+
+ Rebaseline WPT test that is now passing.
+
+ * web-platform-tests/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt:
+
2021-10-01 Yusuke Suzuki <[email protected]>
Disable new incumbent-window until it is fully implemented
Modified: releases/WebKitGTK/webkit-2.34/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox-expected.txt 2021-12-17 22:48:02 UTC (rev 287209)
@@ -1,3 +1,3 @@
-FAIL coop-navigate-same-origin-csp-sandbox assert_equals: expected "Success: no opener" but got "Error: have opener"
+PASS coop-navigate-same-origin-csp-sandbox
Modified: releases/WebKitGTK/webkit-2.34/Source/WebCore/ChangeLog (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/Source/WebCore/ChangeLog 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/Source/WebCore/ChangeLog 2021-12-17 22:48:02 UTC (rev 287209)
@@ -1,3 +1,31 @@
+2021-09-02 Chris Dumez <[email protected]>
+
+ [COOP] html/cross-origin-opener-policy/coop-navigate-same-origin-csp-sandbox.html WPT test is failing
+ https://bugs.webkit.org/show_bug.cgi?id=229716
+
+ Reviewed by Darin Adler.
+
+ The COOP algorithm is relying on the response origin for some of the checks. We were computing the
+ response origin via `SecurityOrigin::create(response.url())`, which worked fine in most cases.
+ However, the response may contain a CSP header, which could set sandbox flags. If sandbox flags
+ are set, the response origin should be unique, not the origin of the response URL. This patch fixes
+ that.
+
+ No new tests, rebaselined existing WPT test.
+
+ * loader/DocumentLoader.cpp:
+ (WebCore::computeResponseOriginAndCOOP):
+ (WebCore::DocumentLoader::doCrossOriginOpenerHandlingOfResponse):
+ * loader/DocumentLoader.h:
+ (WebCore::DocumentLoader::contentSecurityPolicy const):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::didBeginDocument):
+ * page/csp/ContentSecurityPolicy.cpp:
+ (WebCore::ContentSecurityPolicy::copyStateFrom):
+ (WebCore::ContentSecurityPolicy::didReceiveHeaders):
+ * page/csp/ContentSecurityPolicy.h:
+ (WebCore::ContentSecurityPolicy::sandboxFlags const):
+
2021-10-02 Yusuke Suzuki <[email protected]>
Remove JSC hack after r283410
Modified: releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/DocumentLoader.cpp (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/DocumentLoader.cpp 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/DocumentLoader.cpp 2021-12-17 22:48:02 UTC (rev 287209)
@@ -758,7 +758,7 @@
return true;
}
-static std::tuple<Ref<SecurityOrigin>, CrossOriginOpenerPolicy> computeResponseOriginAndCOOP(const ResourceResponse& response, const Document& document, const std::optional<NavigationAction::Requester>& requester)
+static std::tuple<Ref<SecurityOrigin>, CrossOriginOpenerPolicy> computeResponseOriginAndCOOP(const ResourceResponse& response, const Document& document, const std::optional<NavigationAction::Requester>& requester, ContentSecurityPolicy* responseCSP)
{
// Non-initial empty documents (about:blank) should inherit their cross-origin-opener-policy from the navigation's initiator top level document,
// if the initiator and its top level document are same-origin, or default (unsafe-none) otherwise.
@@ -766,7 +766,9 @@
if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(response.url()) && requester)
return std::make_tuple(makeRef(requester->securityOrigin()), requester->securityOrigin().isSameOriginAs(requester->topOrigin()) ? requester->crossOriginOpenerPolicy() : CrossOriginOpenerPolicy { });
- return std::make_tuple(SecurityOrigin::create(response.url()), obtainCrossOriginOpenerPolicy(response, document));
+ // If the HTTP response contains a CSP header, it may set sandbox flags, which would cause the origin to become unique.
+ auto responseOrigin = responseCSP && responseCSP->sandboxFlags() != SandboxNone ? SecurityOrigin::createUnique() : SecurityOrigin::create(response.url());
+ return std::make_tuple(WTFMove(responseOrigin), obtainCrossOriginOpenerPolicy(response, document));
}
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#process-a-navigate-fetch (Step 12.5.6)
@@ -779,8 +781,14 @@
if (!m_frame->document() || !m_frame->document()->settings().crossOriginOpenerPolicyEnabled())
return true;
- auto [responseOrigin, responseCOOP] = computeResponseOriginAndCOOP(response, *m_frame->document(), m_triggeringAction.requester());
+ if (!response.httpHeaderField(HTTPHeaderName::ContentSecurityPolicy).isNull()) {
+ m_contentSecurityPolicy = makeUnique<ContentSecurityPolicy>(URL { response.url() }, nullptr);
+ m_contentSecurityPolicy->didReceiveHeaders(ContentSecurityPolicyResponseHeaders { response }, m_request.httpReferrer(), ContentSecurityPolicy::ReportParsingErrors::No);
+ } else
+ m_contentSecurityPolicy = nullptr;
+ auto [responseOrigin, responseCOOP] = computeResponseOriginAndCOOP(response, *m_frame->document(), m_triggeringAction.requester(), m_contentSecurityPolicy.get());
+
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#process-a-navigate-fetch (Step 12.5.6.2)
// If sandboxFlags is not empty and responseCOOP's value is not "unsafe-none", then set response to an appropriate network error and break.
if (responseCOOP.value != CrossOriginOpenerPolicyValue::UnsafeNone && frameLoader()->effectiveSandboxFlags() != SandboxNone) {
Modified: releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/DocumentLoader.h (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/DocumentLoader.h 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/DocumentLoader.h 2021-12-17 22:48:02 UTC (rev 287209)
@@ -423,6 +423,7 @@
bool lastNavigationWasAppInitiated() const { return m_lastNavigationWasAppInitiated; }
void setLastNavigationWasAppInitiated(bool lastNavigationWasAppInitiated) { m_lastNavigationWasAppInitiated = lastNavigationWasAppInitiated; }
+ ContentSecurityPolicy* contentSecurityPolicy() const { return m_contentSecurityPolicy.get(); }
std::optional<CrossOriginOpenerPolicy> crossOriginOpenerPolicy() const { return m_currentCoopEnforcementResult ? std::make_optional(m_currentCoopEnforcementResult->crossOriginOpenerPolicy) : std::nullopt; }
bool isContinuingLoadAfterResponsePolicyCheck() const { return m_isContinuingLoadAfterResponsePolicyCheck; }
@@ -628,6 +629,7 @@
ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
std::unique_ptr<ApplicationCacheHost> m_applicationCacheHost;
+ std::unique_ptr<ContentSecurityPolicy> m_contentSecurityPolicy;
#if ENABLE(CONTENT_FILTERING)
std::unique_ptr<ContentFilter> m_contentFilter;
Modified: releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/FrameLoader.cpp (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/FrameLoader.cpp 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/Source/WebCore/loader/FrameLoader.cpp 2021-12-17 22:48:02 UTC (rev 287209)
@@ -749,7 +749,11 @@
if (!dnsPrefetchControl.isEmpty())
m_frame.document()->parseDNSPrefetchControlHeader(dnsPrefetchControl);
- m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()), referrer(), ContentSecurityPolicy::ReportParsingErrors::No);
+ // The DocumentLoader may have already parsed the CSP header to do some checks. If so, reuse the already parsed version instead of parsing again.
+ if (auto* contentSecurityPolicy = m_documentLoader->contentSecurityPolicy())
+ m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(*contentSecurityPolicy, ContentSecurityPolicy::ReportParsingErrors::No);
+ else
+ m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()), referrer(), ContentSecurityPolicy::ReportParsingErrors::No);
if (m_frame.document()->url().protocolIsInHTTPFamily() || m_frame.document()->url().protocolIsBlob())
m_frame.document()->setCrossOriginEmbedderPolicy(obtainCrossOriginEmbedderPolicy(m_documentLoader->response(), *m_frame.document()));
Modified: releases/WebKitGTK/webkit-2.34/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2021-12-17 22:48:02 UTC (rev 287209)
@@ -173,6 +173,17 @@
m_httpStatusCode = headers.m_httpStatusCode;
}
+void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicy& other, ReportParsingErrors reportParsingErrors)
+{
+ SetForScope<bool> isReportingEnabled(m_isReportingEnabled, reportParsingErrors == ReportParsingErrors::Yes);
+ for (auto& policy : other.m_policies)
+ didReceiveHeader(policy->header(), policy->headerType(), ContentSecurityPolicy::PolicyFrom::HTTPHeader, String { });
+ m_referrer = other.m_referrer;
+ m_httpStatusCode = other.m_httpStatusCode;
+ m_upgradeInsecureRequests = other.m_upgradeInsecureRequests;
+ m_insecureNavigationRequestsToUpgrade.add(other.m_insecureNavigationRequestsToUpgrade.begin(), other.m_insecureNavigationRequestsToUpgrade.end());
+}
+
void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicy::PolicyFrom policyFrom, String&& referrer, int httpStatusCode)
{
if (m_hasAPIPolicy)
Modified: releases/WebKitGTK/webkit-2.34/Source/WebCore/page/csp/ContentSecurityPolicy.h (287208 => 287209)
--- releases/WebKitGTK/webkit-2.34/Source/WebCore/page/csp/ContentSecurityPolicy.h 2021-12-17 22:41:39 UTC (rev 287208)
+++ releases/WebKitGTK/webkit-2.34/Source/WebCore/page/csp/ContentSecurityPolicy.h 2021-12-17 22:48:02 UTC (rev 287209)
@@ -84,6 +84,7 @@
WEBCORE_EXPORT ContentSecurityPolicyResponseHeaders responseHeaders() const;
enum ReportParsingErrors { No, Yes };
WEBCORE_EXPORT void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&, String&& referrer, ReportParsingErrors = ReportParsingErrors::Yes);
+ void didReceiveHeaders(const ContentSecurityPolicy&, ReportParsingErrors = ReportParsingErrors::Yes);
void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom, String&& referrer, int httpStatusCode = 0);
bool allowScriptWithNonce(const String& nonce, bool overrideContentSecurityPolicy = false) const;
@@ -177,6 +178,8 @@
void setDocumentURL(URL& documentURL) { m_documentURL = documentURL; }
+ SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
+
private:
void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), const WTF::OrdinalNumber& contextColumn = WTF::OrdinalNumber::beforeFirst(), JSC::JSGlobalObject* = nullptr) const;
void applyPolicyToScriptExecutionContext();