Diff
Modified: trunk/Source/WebCore/PAL/ChangeLog (280014 => 280015)
--- trunk/Source/WebCore/PAL/ChangeLog 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebCore/PAL/ChangeLog 2021-07-17 01:02:06 UTC (rev 280015)
@@ -1,3 +1,12 @@
+2021-07-16 Alex Christensen <achristen...@webkit.org>
+
+ Prevent HSTS tracking mitigation for top level navigation requests
+ https://bugs.webkit.org/show_bug.cgi?id=227936
+
+ Reviewed by Brady Eidson.
+
+ * pal/spi/cf/CFNetworkSPI.h:
+
2021-07-14 Jer Noble <jer.no...@apple.com>
Unreviewed build fix after r279912 (239661@main); Adopt HAVE(SYSTEM_STATUS) macro.
Modified: trunk/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h (280014 => 280015)
--- trunk/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h 2021-07-17 01:02:06 UTC (rev 280015)
@@ -491,6 +491,8 @@
@interface NSURLSessionConfiguration ()
// FIXME: Remove this once rdar://problem/40650244 is in a build.
@property (copy) NSDictionary *_socketStreamProperties;
+// FIXME: Remove this once rdar://80550123 is in a build.
+@property (nonatomic) BOOL _allowsHSTSWithUntrustedRootCertificate;
@end
@interface NSURLSessionTask ()
Modified: trunk/Source/WebKit/ChangeLog (280014 => 280015)
--- trunk/Source/WebKit/ChangeLog 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/ChangeLog 2021-07-17 01:02:06 UTC (rev 280015)
@@ -1,5 +1,37 @@
2021-07-16 Alex Christensen <achristen...@webkit.org>
+ Prevent HSTS tracking mitigation for top level navigation requests
+ https://bugs.webkit.org/show_bug.cgi?id=227936
+
+ Reviewed by Brady Eidson.
+
+ Use NSURLRequest.URL as the first party for cookies for HSTS purposes during redirects instead of NSURLRequest.mainDocumentURL,
+ which hasn't been updated because CFNetwork doesn't know that this is the main document request and when redirected, the main document URL also changes.
+
+ Covered by API tests, which will start covering this case once rdar://80550123 is integrated.
+
+ * NetworkProcess/NetworkSessionCreationParameters.cpp:
+ (WebKit::NetworkSessionCreationParameters::encode const):
+ (WebKit::NetworkSessionCreationParameters::decode):
+ * NetworkProcess/NetworkSessionCreationParameters.h:
+ * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+ (-[WKNetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
+ (-[WKNetworkSessionDelegate URLSession:task:_schemeUpgraded:completionHandler:]):
+ (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
+ * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
+ * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
+ (-[_WKWebsiteDataStoreConfiguration allowsHSTSWithUntrustedRootCertificate]):
+ (-[_WKWebsiteDataStoreConfiguration setAllowsHSTSWithUntrustedRootCertificate:]):
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::parameters):
+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
+ (WebKit::WebsiteDataStoreConfiguration::copy const):
+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
+ (WebKit::WebsiteDataStoreConfiguration::allowsHSTSWithUntrustedRootCertificate const):
+ (WebKit::WebsiteDataStoreConfiguration::setAllowsHSTSWithUntrustedRootCertificate):
+
+2021-07-16 Alex Christensen <achristen...@webkit.org>
+
Network access prevention SPI should prevent preconnecting, and it should first allow injected bundle to change request
https://bugs.webkit.org/show_bug.cgi?id=228044
<rdar://72995136>
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp (280014 => 280015)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2021-07-17 01:02:06 UTC (rev 280015)
@@ -85,6 +85,7 @@
encoder << preventsSystemHTTPProxyAuthentication;
encoder << appHasRequestedCrossWebsiteTrackingPermission;
encoder << useNetworkLoader;
+ encoder << allowsHSTSWithUntrustedRootCertificate;
encoder << resourceLoadStatisticsParameters;
}
@@ -282,6 +283,11 @@
if (!useNetworkLoader)
return std::nullopt;
+ std::optional<bool> allowsHSTSWithUntrustedRootCertificate;
+ decoder >> allowsHSTSWithUntrustedRootCertificate;
+ if (!allowsHSTSWithUntrustedRootCertificate)
+ return std::nullopt;
+
std::optional<ResourceLoadStatisticsParameters> resourceLoadStatisticsParameters;
decoder >> resourceLoadStatisticsParameters;
if (!resourceLoadStatisticsParameters)
@@ -333,6 +339,7 @@
, WTFMove(*preventsSystemHTTPProxyAuthentication)
, WTFMove(*appHasRequestedCrossWebsiteTrackingPermission)
, WTFMove(*useNetworkLoader)
+ , WTFMove(*allowsHSTSWithUntrustedRootCertificate)
, WTFMove(*resourceLoadStatisticsParameters)
}};
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h (280014 => 280015)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2021-07-17 01:02:06 UTC (rev 280015)
@@ -99,6 +99,7 @@
bool preventsSystemHTTPProxyAuthentication { false };
bool appHasRequestedCrossWebsiteTrackingPermission { false };
bool useNetworkLoader { false };
+ bool allowsHSTSWithUntrustedRootCertificate { false };
ResourceLoadStatisticsParameters resourceLoadStatisticsParameters;
};
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (280014 => 280015)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2021-07-17 01:02:06 UTC (rev 280015)
@@ -578,7 +578,10 @@
bool shouldIgnoreHSTS = false;
#if ENABLE(RESOURCE_LOAD_STATISTICS)
if (auto* sessionCocoa = networkDataTask->networkSession()) {
- shouldIgnoreHSTS = schemeWasUpgradedDueToDynamicHSTS(request) && sessionCocoa->networkProcess().storageSession(sessionCocoa->sessionID())->shouldBlockCookies(request, networkDataTask->frameID(), networkDataTask->pageID(), networkDataTask->shouldRelaxThirdPartyCookieBlocking());
+ auto* storageSession = sessionCocoa->networkProcess().storageSession(sessionCocoa->sessionID());
+ NSURL *firstPartyForCookies = networkDataTask->isTopLevelNavigation() ? request.URL : request.mainDocumentURL;
+ shouldIgnoreHSTS = schemeWasUpgradedDueToDynamicHSTS(request)
+ && storageSession->shouldBlockCookies(firstPartyForCookies, request.URL, networkDataTask->frameID(), networkDataTask->pageID(), networkDataTask->shouldRelaxThirdPartyCookieBlocking());
if (shouldIgnoreHSTS) {
request = downgradeRequest(request);
ASSERT([request.URL.scheme isEqualToString:@"http"]);
@@ -616,7 +619,9 @@
bool shouldIgnoreHSTS = false;
#if ENABLE(RESOURCE_LOAD_STATISTICS)
if (auto* sessionCocoa = networkDataTask->networkSession()) {
- shouldIgnoreHSTS = schemeWasUpgradedDueToDynamicHSTS(request) && sessionCocoa->networkProcess().storageSession(sessionCocoa->sessionID())->shouldBlockCookies(request, networkDataTask->frameID(), networkDataTask->pageID(), networkDataTask->shouldRelaxThirdPartyCookieBlocking());
+ auto* storageSession = sessionCocoa->networkProcess().storageSession(sessionCocoa->sessionID());
+ shouldIgnoreHSTS = schemeWasUpgradedDueToDynamicHSTS(request)
+ && storageSession->shouldBlockCookies(request, networkDataTask->frameID(), networkDataTask->pageID(), networkDataTask->shouldRelaxThirdPartyCookieBlocking());
if (shouldIgnoreHSTS) {
request = downgradeRequest(request);
ASSERT([request.URL.scheme isEqualToString:@"http"]);
@@ -1249,6 +1254,9 @@
configuration._usesNWLoader = parameters.useNetworkLoader;
#endif
+ if (parameters.allowsHSTSWithUntrustedRootCertificate && [configuration respondsToSelector:@selector(_allowsHSTSWithUntrustedRootCertificate)])
+ configuration._allowsHSTSWithUntrustedRootCertificate = YES;
+
#if HAVE(APP_SSO) || PLATFORM(MACCATALYST)
configuration._preventsAppSSO = true;
#endif
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h (280014 => 280015)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h 2021-07-17 01:02:06 UTC (rev 280015)
@@ -74,6 +74,7 @@
@property (nonatomic) BOOL allowsServerPreconnect WK_API_AVAILABLE(macos(10.15.4), ios(13.4));
@property (nonatomic, nullable, copy, setter=setHSTSStorageDirectory:) NSURL *hstsStorageDirectory WK_API_AVAILABLE(macos(12.0), ios(15.0));
@property (nonatomic) BOOL enableInAppBrowserPrivacyForTesting WK_API_AVAILABLE(macos(12.0), ios(15.0));
+@property (nonatomic) BOOL allowsHSTSWithUntrustedRootCertificate WK_API_AVAILABLE(macos(12.0), ios(15.0));
@property (nonatomic, nullable, copy) NSURL *alternativeServicesStorageDirectory WK_API_AVAILABLE(macos(11.0), ios(14.0));
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm (280014 => 280015)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm 2021-07-17 01:02:06 UTC (rev 280015)
@@ -479,6 +479,16 @@
_configuration->setEnableInAppBrowserPrivacyForTesting(enable);
}
+- (BOOL)allowsHSTSWithUntrustedRootCertificate
+{
+ return _configuration->allowsHSTSWithUntrustedRootCertificate();
+}
+
+- (void)setAllowsHSTSWithUntrustedRootCertificate:(BOOL)allows
+{
+ _configuration->setAllowsHSTSWithUntrustedRootCertificate(allows);
+}
+
- (BOOL)allLoadsBlockedByDeviceManagementRestrictionsForTesting
{
return _configuration->allLoadsBlockedByDeviceManagementRestrictionsForTesting();
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (280014 => 280015)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2021-07-17 01:02:06 UTC (rev 280015)
@@ -1999,6 +1999,7 @@
networkSessionParameters.resourceLoadStatisticsParameters = WTFMove(resourceLoadStatisticsParameters);
networkSessionParameters.requiresSecureHTTPSProxyConnection = m_configuration->requiresSecureHTTPSProxyConnection();
networkSessionParameters.preventsSystemHTTPProxyAuthentication = m_configuration->preventsSystemHTTPProxyAuthentication();
+ networkSessionParameters.allowsHSTSWithUntrustedRootCertificate = m_configuration->allowsHSTSWithUntrustedRootCertificate();
parameters.networkSessionParameters = WTFMove(networkSessionParameters);
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp (280014 => 280015)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp 2021-07-17 01:02:06 UTC (rev 280015)
@@ -96,6 +96,7 @@
copy->m_preventsSystemHTTPProxyAuthentication = this->m_preventsSystemHTTPProxyAuthentication;
copy->m_standaloneApplicationURL = this->m_standaloneApplicationURL;
copy->m_enableInAppBrowserPrivacyForTesting = this->m_enableInAppBrowserPrivacyForTesting;
+ copy->m_allowsHSTSWithUntrustedRootCertificate = this->m_allowsHSTSWithUntrustedRootCertificate;
#if PLATFORM(COCOA)
if (m_proxyConfiguration)
copy->m_proxyConfiguration = adoptCF(CFDictionaryCreateCopy(nullptr, this->m_proxyConfiguration.get()));
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h (280014 => 280015)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h 2021-07-17 01:02:06 UTC (rev 280015)
@@ -171,6 +171,9 @@
bool enableInAppBrowserPrivacyForTesting() const { return m_enableInAppBrowserPrivacyForTesting; }
void setEnableInAppBrowserPrivacyForTesting(bool value) { m_enableInAppBrowserPrivacyForTesting = value; }
+ bool allowsHSTSWithUntrustedRootCertificate() const { return m_allowsHSTSWithUntrustedRootCertificate; }
+ void setAllowsHSTSWithUntrustedRootCertificate(bool allows) { m_allowsHSTSWithUntrustedRootCertificate = allows; }
+
private:
IsPersistent m_isPersistent { IsPersistent::No };
@@ -220,6 +223,7 @@
unsigned m_testSpeedMultiplier { 1 };
URL m_standaloneApplicationURL;
bool m_enableInAppBrowserPrivacyForTesting { false };
+ bool m_allowsHSTSWithUntrustedRootCertificate { false };
#if PLATFORM(COCOA)
RetainPtr<CFDictionaryRef> m_proxyConfiguration;
#endif
Modified: trunk/Tools/ChangeLog (280014 => 280015)
--- trunk/Tools/ChangeLog 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Tools/ChangeLog 2021-07-17 01:02:06 UTC (rev 280015)
@@ -1,5 +1,20 @@
2021-07-16 Alex Christensen <achristen...@webkit.org>
+ Prevent HSTS tracking mitigation for top level navigation requests
+ https://bugs.webkit.org/show_bug.cgi?id=227936
+
+ Reviewed by Brady Eidson.
+
+ * TestWebKitAPI/SourcesCocoa.txt:
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/HSTS.mm: Added.
+ (TestWebKitAPI::hasRadar80550123):
+ (TestWebKitAPI::hstsWebViewAndDelegate):
+ (TestWebKitAPI::hstsServer):
+ (TestWebKitAPI::TEST):
+
+2021-07-16 Alex Christensen <achristen...@webkit.org>
+
Network access prevention SPI should prevent preconnecting, and it should first allow injected bundle to change request
https://bugs.webkit.org/show_bug.cgi?id=228044
<rdar://72995136>
Modified: trunk/Tools/TestWebKitAPI/SourcesCocoa.txt (280014 => 280015)
--- trunk/Tools/TestWebKitAPI/SourcesCocoa.txt 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Tools/TestWebKitAPI/SourcesCocoa.txt 2021-07-17 01:02:06 UTC (rev 280015)
@@ -35,6 +35,7 @@
cocoa/UserMediaCaptureUIDelegate.mm
Tests/WebKitCocoa/EventAttribution.mm
+Tests/WebKitCocoa/HSTS.mm
Tests/WebKitCocoa/TestAwakener.mm
Tests/WebKitCocoa/TLSDeprecation.mm
Tests/WebKitCocoa/WebSocket.mm
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (280014 => 280015)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-07-17 01:00:19 UTC (rev 280014)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-07-17 01:02:06 UTC (rev 280015)
@@ -2386,6 +2386,7 @@
5CB18BA71F5645B200EE23C4 /* ClickAutoFillButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ClickAutoFillButton.mm; sourceTree = "<group>"; };
5CB3CE381FA1691700C3A2D6 /* WKWebViewConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewConfiguration.mm; sourceTree = "<group>"; };
5CB40B4D1F4B98BE007DC7B9 /* UIDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIDelegate.mm; sourceTree = "<group>"; };
+ 5CB5990A269E74EC002A7CFF /* HSTS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HSTS.mm; sourceTree = "<group>"; };
5CB5B3BD1FFC517E00C27BB0 /* FrameHandleSerialization.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FrameHandleSerialization.mm; sourceTree = "<group>"; };
5CB7AFDB23C451E400E49CF3 /* ResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoadDelegate.mm; sourceTree = "<group>"; };
5CBAA7F324327F6B00564A8B /* TestUIDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestUIDelegate.h; path = cocoa/TestUIDelegate.h; sourceTree = "<group>"; };
@@ -3476,6 +3477,7 @@
07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */,
2DADF26221CB8F32003D3E3A /* GetResourceData.mm */,
465E2806255B2A690063A787 /* GPUProcess.mm */,
+ 5CB5990A269E74EC002A7CFF /* HSTS.mm */,
51AF23DE1EF1A3720072F281 /* IconLoadingDelegate.mm */,
EB230D3E245E726300C66AD1 /* IDBCheckpointWAL.mm */,
510477751D298E03009747EB /* IDBDeleteRecovery.mm */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HSTS.mm (0 => 280015)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HSTS.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/HSTS.mm 2021-07-17 01:02:06 UTC (rev 280015)
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "HTTPServer.h"
+#import "PlatformUtilities.h"
+#import "TCPServer.h"
+#import "TestNavigationDelegate.h"
+#import "TestUIDelegate.h"
+#import "Utilities.h"
+#import <WebKit/WKWebsiteDataStorePrivate.h>
+#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
+#import <pal/spi/cf/CFNetworkSPI.h>
+
+namespace TestWebKitAPI {
+
+#if HAVE(SSL)
+
+static bool hasRadar80550123()
+{
+ // FIXME: Replace this with a HAS macro once rdar://80550123 is in a build.
+ return [[NSURLSessionConfiguration ephemeralSessionConfiguration] respondsToSelector:@selector(_allowsHSTSWithUntrustedRootCertificate)];
+}
+
+std::pair<RetainPtr<WKWebView>, RetainPtr<TestNavigationDelegate>> hstsWebViewAndDelegate(const TCPServer& httpsServer, const HTTPServer& httpServer)
+{
+ auto storeConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] initNonPersistentConfiguration]);
+ [storeConfiguration setHTTPSProxy:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", httpsServer.port()]]];
+ [storeConfiguration setHTTPProxy:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", httpServer.port()]]];
+ [storeConfiguration setAllowsServerPreconnect:NO];
+ [storeConfiguration setAllowsHSTSWithUntrustedRootCertificate:YES];
+ auto viewConfiguration = adoptNS([WKWebViewConfiguration new]);
+ [viewConfiguration setWebsiteDataStore:adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:storeConfiguration.get()]).get()];
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) configuration:viewConfiguration.get()]);
+ auto delegate = adoptNS([TestNavigationDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ delegate.get().didReceiveAuthenticationChallenge = ^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+ EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+ completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+ };
+ return { WTFMove(webView), WTFMove(delegate) };
+}
+
+static TCPServer hstsServer(size_t replies)
+{
+ // FIXME: Use nw_framer_t to support HTTPS proxies in HTTPServer and remove TCPServer.
+ return TCPServer(TCPServer::Protocol::HTTPSProxy, [=] (SSL* ssl) {
+ for (size_t i = 0; i < replies; i++) {
+ TCPServer::read(ssl);
+ const char* response =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 0\r\n"
+ "Strict-Transport-Security: max-age=31536000\r\n"
+ "\r\n";
+ TCPServer::write(ssl, response, strlen(response));
+ }
+ });
+}
+
+TEST(HSTS, Basic)
+{
+ if (!hasRadar80550123())
+ return;
+
+ auto httpsServer = hstsServer(2);
+
+ HTTPServer httpServer({{ "http://example.com/", { {{ "Strict-Transport-Security", "max-age=31536000"}}, "hi" }}});
+
+ auto [webView, delegate] = hstsWebViewAndDelegate(httpsServer, httpServer);
+
+ NSURLRequest *httpRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/"]];
+ NSURLRequest *httpsRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/"]];
+
+ [webView loadRequest:httpRequest];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "http://example.com/");
+
+ [webView reload];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "http://example.com/");
+
+ [webView loadRequest:httpsRequest];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "https://example.com/");
+
+ [webView loadRequest:httpRequest];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "https://example.com/");
+}
+
+TEST(HSTS, ThirdParty)
+{
+ if (!hasRadar80550123())
+ return;
+
+ auto httpsServer = hstsServer(1);
+
+ const char* html = "<script>"
+ "var xhr = new XMLHttpRequest();"
+ "xhr.open('GET', 'http://example.com/');"
+ "xhr._onreadystatechange_ = function () { if(xhr.readyState == 4) { alert(xhr.responseURL + ' ' + xhr.responseText) } };"
+ "xhr.send();"
+ "</script>";
+
+ HTTPServer httpServer({
+ { "http://example.com/", { {{ "Access-Control-Allow-Origin", "http://example.org" }}, "hi" }},
+ { "http://example.org/", { html }},
+ });
+
+ auto [webView, delegate] = hstsWebViewAndDelegate(httpsServer, httpServer);
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/"]]];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "https://example.com/");
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.org/"]]];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "http://example.com/ hi");
+ EXPECT_EQ(httpServer.totalRequests(), 2u);
+}
+
+TEST(HSTS, CrossOriginRedirect)
+{
+ if (!hasRadar80550123())
+ return;
+
+ auto httpsServer = hstsServer(2);
+
+ HTTPServer httpServer({
+ { "http://example.com/", { "hi" }},
+ { "http://example.org/", { 301, {{ "Location", "http://example.com/" }} } },
+ });
+
+ auto [webView, delegate] = hstsWebViewAndDelegate(httpsServer, httpServer);
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/"]]];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "https://example.com/");
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.org/"]]];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_WK_STREQ(webView.get().URL.absoluteString, "https://example.com/");
+ EXPECT_EQ(httpServer.totalRequests(), 1u);
+}
+
+#endif // HAVE(SSL)
+
+} // namespace TestWebKitAPI