source: webkit/trunk/Source/WebCore/loader/CrossOriginOpenerPolicy.cpp

Last change on this file was 295129, checked in by Chris Dumez, 3 years ago

Drop unnecessary operator==() overloads from StringView
https://bugs.webkit.org/show_bug.cgi?id=241189

Reviewed by Darin Adler.

  • Source/JavaScriptCore/runtime/IntlRelativeTimeFormat.cpp:

(JSC::relativeTimeUnitType):

  • Source/JavaScriptCore/runtime/TemporalObject.cpp:

(JSC::temporalUnitType):

  • Source/WTF/wtf/text/StringView.h:

(WTF::operator==):
(WTF::operator!=):

  • Source/WebCore/Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.cpp:

(WebCore::ApplePayAMSUIPaymentHandler::handlesIdentifier):

  • Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp:

(WebCore::ApplePayPaymentHandler::handlesIdentifier):

  • Source/WebCore/Modules/cache/DOMCache.cpp:

(WebCore::hasResponseVaryStarHeaderValue):

  • Source/WebCore/Modules/cache/DOMCacheEngine.cpp:

(WebCore::DOMCacheEngine::queryCacheMatch):

  • Source/WebCore/Modules/entriesapi/DOMFileSystem.cpp:

(WebCore::isValidPathSegment):
(WebCore::resolveRelativeVirtualPath):
(WebCore::DOMFileSystem::evaluatePath):

  • Source/WebCore/Modules/fetch/FetchRequest.cpp:

(WebCore::computeReferrer):

  • Source/WebCore/Modules/plugins/YouTubePluginReplacement.cpp:

(WebCore::createYouTubeURL):
(WebCore::processAndCreateYouTubeURL):

  • Source/WebCore/css/SelectorCheckerTestFunctions.h:

(WebCore::containslanguageSubtagMatchingRange):

  • Source/WebCore/css/StyleProperties.cpp:

(WebCore::isCSSWideValueKeyword):

  • Source/WebCore/css/parser/CSSPropertyParser.cpp:

(WebCore::parseGridTemplateAreasColumnNames):

  • Source/WebCore/dom/Document.cpp:

(WebCore::Document::initDNSPrefetch):

  • Source/WebCore/editing/TextManipulationController.cpp:

(WebCore::ParagraphContentIterator::advanceIteratorNodeAndUpdateText):

  • Source/WebCore/fileapi/ThreadableBlobRegistry.cpp:

(WebCore::isBlobURLContainsNullOrigin):

  • Source/WebCore/html/FeaturePolicy.cpp:

(WebCore::processOriginItem):

  • Source/WebCore/html/HTMLScriptElement.h:
  • Source/WebCore/html/parser/CSSPreloadScanner.cpp:

(WebCore::hasValidImportConditions):

  • Source/WebCore/loader/CrossOriginAccessControl.cpp:

(WebCore::shouldCrossOriginResourcePolicyCancelLoad):

  • Source/WebCore/loader/CrossOriginEmbedderPolicy.cpp:

(WebCore::obtainCrossOriginEmbedderPolicy):

  • Source/WebCore/loader/CrossOriginOpenerPolicy.cpp:

(WebCore::obtainCrossOriginOpenerPolicy):

  • Source/WebCore/loader/ResourceLoadInfo.cpp:

(WebCore::ContentExtensions::readResourceType):
(WebCore::ContentExtensions::readLoadType):
(WebCore::ContentExtensions::readLoadContext):

  • Source/WebCore/mathml/MathMLMencloseElement.cpp:

(WebCore::MathMLMencloseElement::addNotationFlags):

  • Source/WebCore/mathml/MathMLPresentationElement.cpp:

(WebCore::MathMLPresentationElement::parseNamedSpace):

  • Source/WebCore/page/EventSource.cpp:

(WebCore::EventSource::parseEventStreamLine):

  • Source/WebCore/page/FrameTree.cpp:

(WebCore::isSelfTargetFrameName):

  • Source/WebCore/page/Quirks.cpp:

(WebCore::Quirks::shouldAllowNavigationToCustomProtocolWithoutUserGesture):

  • Source/WebCore/platform/LegacySchemeRegistry.cpp:

(WebCore::LegacySchemeRegistry::isUserExtensionScheme):

  • Source/WebCore/platform/LocalizedStrings.cpp:

(WebCore::AXARIAContentGroupText):

  • Source/WebCore/platform/graphics/HEVCUtilities.cpp:

(WebCore::parseAVCCodecParameters):
(WebCore::parseHEVCCodecParameters):

  • Source/WebCore/platform/graphics/cg/UTIRegistry.cpp:

(WebCore::isGIFImageType):

  • Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp:

(WebCore::WebMParser::OnTrackEntry):
(WebCore::WebMParser::isSupportedVideoCodec):
(WebCore::WebMParser::isSupportedAudioCodec):
(WebCore::SourceBufferParserWebM::isContentTypeSupported):

  • Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.cpp:

(WebCore::VideoTrackPrivateWebM::codec const):

  • Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp:

(WebCore::sessionLoadFailureFromThunder):

  • Source/WebCore/platform/network/HTTPParsers.cpp:

(WebCore::filenameFromHTTPContentDisposition):
(WebCore::parseCrossOriginResourcePolicyHeader):

  • Source/WebCore/platform/network/ParsedContentRange.cpp:

(WebCore::parseContentRange):

  • Source/WebCore/platform/network/TimingAllowOrigin.cpp:

(WebCore::passesTimingAllowOriginCheck):

  • Source/WebCore/svg/animation/SVGSMILElement.cpp:

(WebCore::SVGSMILElement::parseCondition):

  • Source/WebGPU/WGSL/AST/TypeDecl.h:

(WGSL::AST::ParameterizedType::stringViewToKind):

  • Source/WebGPU/WGSL/Lexer.cpp:

(WGSL::Lexer<T>::lex):

  • Source/WebGPU/WGSL/Parser.cpp:

(WGSL::Parser<Lexer>::parseAttribute):
(WGSL::Parser<Lexer>::parsePrimaryExpression):

  • Source/WebKit/NetworkProcess/PrivateClickMeasurement/cocoa/PrivateClickMeasurementNetworkLoaderCocoa.mm:

(WebKit::PCM::NetworkLoader::start):

  • Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp:

(WebKit::CacheStorage::updateVaryInformation):

  • Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp:

(WebKit::WebsiteDataStore::setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting):
(WebKit::WebsiteDataStore::setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting):

  • Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm:

(WebKit::PDFPlugin::handleEditingCommand):
(WebKit::PDFPlugin::isEditingCommandEnabled):

  • Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:

(TestWebKitAPI::TEST):

  • Tools/TestWebKitAPI/Tests/WTF/URL.cpp:

(TestWebKitAPI::TEST_F):

  • Tools/TestWebKitAPI/Tests/WebKitCocoa/IndexedDBFileName.mm:

(createDirectories):

Canonical link: https://commits.webkit.org/251220@main

File size: 12.0 KB
Line 
1/*
2 * Copyright (C) 2021 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "CrossOriginOpenerPolicy.h"
28
29#include "ContentSecurityPolicy.h"
30#include "CrossOriginEmbedderPolicy.h"
31#include "FormData.h"
32#include "Frame.h"
33#include "HTTPHeaderNames.h"
34#include "HTTPParsers.h"
35#include "NavigationRequester.h"
36#include "Page.h"
37#include "PingLoader.h"
38#include "ResourceResponse.h"
39#include "ScriptExecutionContext.h"
40#include "SecurityPolicy.h"
41#include <wtf/JSONValues.h>
42
43namespace WebCore {
44
45static ASCIILiteral crossOriginOpenerPolicyToString(const CrossOriginOpenerPolicyValue& coop)
46{
47 switch (coop) {
48 case CrossOriginOpenerPolicyValue::SameOrigin:
49 case CrossOriginOpenerPolicyValue::SameOriginPlusCOEP:
50 return "same-origin"_s;
51 case CrossOriginOpenerPolicyValue::SameOriginAllowPopups:
52 return "same-origin-allow-popups"_s;
53 case CrossOriginOpenerPolicyValue::UnsafeNone:
54 break;
55 }
56 return "unsafe-none"_s;
57}
58
59// https://html.spec.whatwg.org/multipage/origin.html#check-browsing-context-group-switch-coop-value
60static bool checkIfCOOPValuesRequireBrowsingContextGroupSwitch(bool isInitialAboutBlank, CrossOriginOpenerPolicyValue activeDocumentCOOPValue, const SecurityOrigin& activeDocumentNavigationOrigin, CrossOriginOpenerPolicyValue responseCOOPValue, const SecurityOrigin& responseOrigin)
61{
62 // If the result of matching activeDocumentCOOPValue, activeDocumentNavigationOrigin, responseCOOPValue, and responseOrigin is true, return false.
63 // https://html.spec.whatwg.org/multipage/origin.html#matching-coop
64 if (activeDocumentCOOPValue == CrossOriginOpenerPolicyValue::UnsafeNone && responseCOOPValue == CrossOriginOpenerPolicyValue::UnsafeNone)
65 return false;
66 if (activeDocumentCOOPValue == responseCOOPValue && activeDocumentNavigationOrigin.isSameOriginAs(responseOrigin))
67 return false;
68
69 // If all of the following are true:
70 // - isInitialAboutBlank,
71 // - activeDocumentCOOPValue's value is "same-origin-allow-popups".
72 // - responseCOOPValue is "unsafe-none",
73 // then return false.
74 if (isInitialAboutBlank && activeDocumentCOOPValue == CrossOriginOpenerPolicyValue::SameOriginAllowPopups && responseCOOPValue == CrossOriginOpenerPolicyValue::UnsafeNone)
75 return false;
76
77 return true;
78}
79
80// https://html.spec.whatwg.org/multipage/origin.html#check-bcg-switch-navigation-report-only
81static bool checkIfEnforcingReportOnlyCOOPWouldRequireBrowsingContextGroupSwitch(bool isInitialAboutBlank, const CrossOriginOpenerPolicy& activeDocumentCOOP, const SecurityOrigin& activeDocumentNavigationOrigin, const CrossOriginOpenerPolicy& responseCOOP, const SecurityOrigin& responseOrigin)
82{
83 if (!checkIfCOOPValuesRequireBrowsingContextGroupSwitch(isInitialAboutBlank, activeDocumentCOOP.reportOnlyValue, activeDocumentNavigationOrigin, responseCOOP.reportOnlyValue, responseOrigin))
84 return false;
85
86 if (checkIfCOOPValuesRequireBrowsingContextGroupSwitch(isInitialAboutBlank, activeDocumentCOOP.reportOnlyValue, activeDocumentNavigationOrigin, responseCOOP.value, responseOrigin))
87 return true;
88
89 if (checkIfCOOPValuesRequireBrowsingContextGroupSwitch(isInitialAboutBlank, activeDocumentCOOP.value, activeDocumentNavigationOrigin, responseCOOP.reportOnlyValue, responseOrigin))
90 return true;
91
92 return false;
93}
94
95static std::tuple<Ref<SecurityOrigin>, CrossOriginOpenerPolicy> computeResponseOriginAndCOOP(const ResourceResponse& response, const std::optional<NavigationRequester>& requester, ContentSecurityPolicy* responseCSP)
96{
97 // Non-initial empty documents (about:blank) should inherit their cross-origin-opener-policy from the navigation's initiator top level document,
98 // if the initiator and its top level document are same-origin, or default (unsafe-none) otherwise.
99 // https://github.com/whatwg/html/issues/6913
100 if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(response.url()) && requester)
101 return std::make_tuple(requester->securityOrigin, requester->securityOrigin->isSameOriginAs(requester->topOrigin) ? requester->crossOriginOpenerPolicy : CrossOriginOpenerPolicy { });
102
103 // If the HTTP response contains a CSP header, it may set sandbox flags, which would cause the origin to become unique.
104 auto responseOrigin = responseCSP && responseCSP->sandboxFlags() != SandboxNone ? SecurityOrigin::createUnique() : SecurityOrigin::create(response.url());
105 return std::make_tuple(WTFMove(responseOrigin), obtainCrossOriginOpenerPolicy(response));
106}
107
108// https://html.spec.whatwg.org/multipage/origin.html#coop-enforce
109static CrossOriginOpenerPolicyEnforcementResult enforceResponseCrossOriginOpenerPolicy(const CrossOriginOpenerPolicyEnforcementResult& currentCoopEnforcementResult, const URL& responseURL, SecurityOrigin& responseOrigin, const CrossOriginOpenerPolicy& responseCOOP, bool isDisplayingInitialEmptyDocument)
110{
111 CrossOriginOpenerPolicyEnforcementResult newCOOPEnforcementResult = {
112 responseURL,
113 responseOrigin,
114 responseCOOP,
115 true /* isCurrentContextNavigationSource */,
116 currentCoopEnforcementResult.needsBrowsingContextGroupSwitch,
117 currentCoopEnforcementResult.needsBrowsingContextGroupSwitchDueToReportOnly
118 };
119
120 if (checkIfCOOPValuesRequireBrowsingContextGroupSwitch(isDisplayingInitialEmptyDocument, currentCoopEnforcementResult.crossOriginOpenerPolicy.value, currentCoopEnforcementResult.currentOrigin, responseCOOP.value, responseOrigin))
121 newCOOPEnforcementResult.needsBrowsingContextGroupSwitch = true;
122
123 if (checkIfEnforcingReportOnlyCOOPWouldRequireBrowsingContextGroupSwitch(isDisplayingInitialEmptyDocument, currentCoopEnforcementResult.crossOriginOpenerPolicy, currentCoopEnforcementResult.currentOrigin, responseCOOP, responseOrigin))
124 newCOOPEnforcementResult.needsBrowsingContextGroupSwitchDueToReportOnly = true;
125
126 return newCOOPEnforcementResult;
127}
128
129// https://html.spec.whatwg.org/multipage/origin.html#obtain-coop
130CrossOriginOpenerPolicy obtainCrossOriginOpenerPolicy(const ResourceResponse& response)
131{
132 std::optional<CrossOriginEmbedderPolicy> coep;
133 auto ensureCOEP = [&coep, &response]() -> CrossOriginEmbedderPolicy& {
134 if (!coep)
135 coep = obtainCrossOriginEmbedderPolicy(response, nullptr);
136 return *coep;
137 };
138 auto parseCOOP = [&response, &ensureCOEP](HTTPHeaderName headerName, auto& value, auto& reportingEndpoint) {
139 auto coopParsingResult = parseStructuredFieldValue(response.httpHeaderField(headerName));
140 if (!coopParsingResult)
141 return;
142
143 if (coopParsingResult->first == "same-origin"_s) {
144 auto& coep = ensureCOEP();
145 if (coep.value == CrossOriginEmbedderPolicyValue::RequireCORP || (headerName == HTTPHeaderName::CrossOriginOpenerPolicyReportOnly && coep.reportOnlyValue == CrossOriginEmbedderPolicyValue::RequireCORP))
146 value = CrossOriginOpenerPolicyValue::SameOriginPlusCOEP;
147 else
148 value = CrossOriginOpenerPolicyValue::SameOrigin;
149 } else if (coopParsingResult->first == "same-origin-allow-popups"_s)
150 value = CrossOriginOpenerPolicyValue::SameOriginAllowPopups;
151
152 reportingEndpoint = coopParsingResult->second.get<HashTranslatorASCIILiteral>("report-to"_s);
153 };
154
155 CrossOriginOpenerPolicy policy;
156 if (!SecurityOrigin::create(response.url())->isPotentiallyTrustworthy())
157 return policy;
158
159 parseCOOP(HTTPHeaderName::CrossOriginOpenerPolicy, policy.value, policy.reportingEndpoint);
160 parseCOOP(HTTPHeaderName::CrossOriginOpenerPolicyReportOnly, policy.reportOnlyValue, policy.reportOnlyReportingEndpoint);
161 return policy;
162}
163
164CrossOriginOpenerPolicy CrossOriginOpenerPolicy::isolatedCopy() const &
165{
166 return { value, reportingEndpoint.isolatedCopy(), reportOnlyValue, reportOnlyReportingEndpoint.isolatedCopy() };
167}
168
169CrossOriginOpenerPolicy CrossOriginOpenerPolicy::isolatedCopy() &&
170{
171 return { value, WTFMove(reportingEndpoint).isolatedCopy(), reportOnlyValue, WTFMove(reportOnlyReportingEndpoint).isolatedCopy() };
172}
173
174void addCrossOriginOpenerPolicyHeaders(ResourceResponse& response, const CrossOriginOpenerPolicy& coop)
175{
176 if (coop.value != CrossOriginOpenerPolicyValue::UnsafeNone) {
177 if (coop.reportingEndpoint.isEmpty())
178 response.setHTTPHeaderField(HTTPHeaderName::CrossOriginOpenerPolicy, crossOriginOpenerPolicyToString(coop.value));
179 else
180 response.setHTTPHeaderField(HTTPHeaderName::CrossOriginOpenerPolicy, makeString(crossOriginOpenerPolicyToString(coop.value), "; report-to=\"", coop.reportingEndpoint, '\"'));
181 }
182 if (coop.reportOnlyValue != CrossOriginOpenerPolicyValue::UnsafeNone) {
183 if (coop.reportOnlyReportingEndpoint.isEmpty())
184 response.setHTTPHeaderField(HTTPHeaderName::CrossOriginOpenerPolicyReportOnly, crossOriginOpenerPolicyToString(coop.reportOnlyValue));
185 else
186 response.setHTTPHeaderField(HTTPHeaderName::CrossOriginOpenerPolicyReportOnly, makeString(crossOriginOpenerPolicyToString(coop.reportOnlyValue), "; report-to=\"", coop.reportOnlyReportingEndpoint, '\"'));
187 }
188}
189
190// https://html.spec.whatwg.org/multipage/browsing-the-web.html#process-a-navigate-fetch (Step 13.5.6)
191std::optional<CrossOriginOpenerPolicyEnforcementResult> doCrossOriginOpenerHandlingOfResponse(const ResourceResponse& response, const std::optional<NavigationRequester>& requester, ContentSecurityPolicy* responseCSP, SandboxFlags effectiveSandboxFlags, bool isDisplayingInitialEmptyDocument, const CrossOriginOpenerPolicyEnforcementResult& currentCoopEnforcementResult)
192{
193 auto [responseOrigin, responseCOOP] = computeResponseOriginAndCOOP(response, requester, responseCSP);
194
195 // https://html.spec.whatwg.org/multipage/browsing-the-web.html#process-a-navigate-fetch (Step 13.5.6.2)
196 // If sandboxFlags is not empty and responseCOOP's value is not "unsafe-none", then set response to an appropriate network error and break.
197 if (responseCOOP.value != CrossOriginOpenerPolicyValue::UnsafeNone && effectiveSandboxFlags != SandboxNone)
198 return std::nullopt;
199
200 return enforceResponseCrossOriginOpenerPolicy(currentCoopEnforcementResult, response.url(), responseOrigin, responseCOOP, isDisplayingInitialEmptyDocument);
201}
202
203CrossOriginOpenerPolicyEnforcementResult CrossOriginOpenerPolicyEnforcementResult::from(const URL& currentURL, Ref<SecurityOrigin>&& currentOrigin, const CrossOriginOpenerPolicy& crossOriginOpenerPolicy, std::optional<NavigationRequester> requester, const URL& openerURL)
204{
205 CrossOriginOpenerPolicyEnforcementResult result { currentURL, WTFMove(currentOrigin), crossOriginOpenerPolicy };
206 result.isCurrentContextNavigationSource = requester && result.currentOrigin->isSameOriginAs(requester->securityOrigin);
207 if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(currentURL) && openerURL.isValid())
208 result.url = openerURL;
209 return result;
210}
211
212} // namespace WebCore
Note: See TracBrowser for help on using the repository browser.