Skip to content
Permalink
Browse files
Private relay should fail closed for third party loads if the main re…
…source was loaded over private relay

https://bugs.webkit.org/show_bug.cgi?id=240483
<rdar://92697007>

Patch by Alex Christensen <achristensen@webkit.org> on 2022-05-17
Reviewed by Chris Dumez.

This re-lands the change from r293861 along with r293481 which should fix problems related to rdar://92336270
along with r293591 which should fix performance regressions related to rdar://92458995 but was insufficient.
During a basic browsing test, I found two more places where we were making a NetworkDataTask without setting the
parameters' top origin, one in the SpeculativeLoad constructor and another in WebLoaderStrategy::preconnectTo.

* Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp:
(WebKit::NetworkCORSPreflightChecker::startPreflight):
* Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
(WebKit::NetworkCache::SpeculativeLoad::SpeculativeLoad):
* Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
* Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
(WebKit::NetworkSessionCocoa::createWebSocketTask):
* Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::preconnectTo):

Canonical link: https://commits.webkit.org/250670@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294371 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Alex Christensen authored and webkit-commit-queue committed May 18, 2022
1 parent deb9275 commit b07ce12ec55dcd2fd25b0622c34f83c5d2302b49
Showing 5 changed files with 29 additions and 2 deletions.
@@ -75,6 +75,8 @@ void NetworkCORSPreflightChecker::startPreflight()
m_loadInformation = NetworkTransactionInformation { NetworkTransactionInformation::Type::Preflight, loadParameters.request, { }, { } };

loadParameters.webPageProxyID = m_parameters.webPageProxyID;
loadParameters.topOrigin = m_parameters.topOrigin;
loadParameters.sourceOrigin = m_parameters.sourceOrigin.ptr();

if (auto* networkSession = m_networkProcess->networkSession(m_parameters.sessionID)) {
m_task = NetworkDataTask::create(*networkSession, *this, WTFMove(loadParameters));
@@ -67,6 +67,7 @@ SpeculativeLoad::SpeculativeLoad(Cache& cache, const GlobalFrameID& globalFrameI
parameters.contentSniffingPolicy = ContentSniffingPolicy::DoNotSniffContent;
parameters.contentEncodingSniffingPolicy = ContentEncodingSniffingPolicy::Sniff;
parameters.request = m_originalRequest;
parameters.topOrigin = SecurityOrigin::create(m_originalRequest.firstPartyForCookies());
parameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
m_networkLoad = makeUnique<NetworkLoad>(*this, nullptr, WTFMove(parameters), *networkSession);
m_networkLoad->startWithScheduling();
@@ -340,6 +340,14 @@ static inline bool computeIsAlwaysOnLoggingAllowed(NetworkSession& session)
RetainPtr<NSURLRequest> nsRequest = request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::UpdateHTTPBody);
RetainPtr<NSMutableURLRequest> mutableRequest = adoptNS([nsRequest.get() mutableCopy]);

if (parameters.isMainFrameNavigation
|| parameters.hadMainFrameMainResourcePrivateRelayed
|| !parameters.topOrigin
|| request.url().host() == parameters.topOrigin->host()) {
if ([mutableRequest respondsToSelector:@selector(_setPrivacyProxyFailClosedForUnreachableNonMainHosts:)])
[mutableRequest _setPrivacyProxyFailClosedForUnreachableNonMainHosts:YES];
}

#if ENABLE(APP_PRIVACY_REPORT)
mutableRequest.get().attribution = request.isAppInitiated() ? NSURLRequestAttributionDeveloper : NSURLRequestAttributionUser;
#endif
@@ -936,7 +936,9 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)data

NSURLSessionTaskTransactionMetrics *metrics = taskMetrics.transactionMetrics.lastObject;
#if HAVE(NETWORK_CONNECTION_PRIVACY_STANCE)
auto privateRelayed = metrics._privacyStance == nw_connection_privacy_stance_direct ? PrivateRelayed::No : PrivateRelayed::Yes;
auto privateRelayed = metrics._privacyStance == nw_connection_privacy_stance_direct
|| metrics._privacyStance == nw_connection_privacy_stance_not_eligible
? PrivateRelayed::No : PrivateRelayed::Yes;
#else
auto privateRelayed = PrivateRelayed::No;
#endif
@@ -1712,6 +1714,17 @@ static void activateSessionCleanup(NetworkSessionCocoa& session, const NetworkSe
appPrivacyReportTestingData().didLoadAppInitiatedRequest(nsRequest.get().attribution == NSURLRequestAttributionDeveloper);
#endif

// FIXME: This function can make up to 3 copies of a request.
// Reduce that to one if the protocol is null, the request isn't app initiated,
// or the main frame main resource was private relayed, then set all properties
// on the one copy.
if (hadMainFrameMainResourcePrivateRelayed || request.url().host() == clientOrigin.topOrigin.host) {
RetainPtr<NSMutableURLRequest> mutableRequest = adoptNS([nsRequest.get() mutableCopy]);
if ([mutableRequest respondsToSelector:@selector(_setPrivacyProxyFailClosedForUnreachableNonMainHosts:)])
[mutableRequest _setPrivacyProxyFailClosedForUnreachableNonMainHosts:YES];
nsRequest = WTFMove(mutableRequest);
}

auto& sessionSet = sessionSetForPage(webPageProxyID);
RetainPtr<NSURLSessionWebSocketTask> task = [sessionSet.sessionWithCredentialStorage.session webSocketTaskWithRequest:nsRequest.get()];

@@ -829,16 +829,19 @@ void WebLoaderStrategy::preconnectTo(WebCore::ResourceRequest&& request, WebPage
return;
}

NetworkResourceLoadParameters parameters;

if (auto* document = webPage.mainFrame()->document()) {
if (shouldPreconnectAsFirstParty == ShouldPreconnectAsFirstParty::Yes)
request.setFirstPartyForCookies(request.url());
else
request.setFirstPartyForCookies(document->firstPartyForCookies());
if (auto* loader = document->loader())
request.setIsAppInitiated(loader->lastNavigationWasAppInitiated());
parameters.topOrigin = &document->topOrigin();
parameters.sourceOrigin = &document->securityOrigin();
}

NetworkResourceLoadParameters parameters;
parameters.request = WTFMove(request);
if (parameters.request.httpUserAgent().isEmpty()) {
// FIXME: we add user-agent to the preconnect request because otherwise the preconnect

0 comments on commit b07ce12

Please sign in to comment.