Title: [280015] trunk
Revision
280015
Author
achristen...@apple.com
Date
2021-07-16 18:02:06 -0700 (Fri, 16 Jul 2021)

Log Message

Prevent HSTS tracking mitigation for top level navigation requests
https://bugs.webkit.org/show_bug.cgi?id=227936

Reviewed by Brady Eidson.

Source/WebCore/PAL:

* pal/spi/cf/CFNetworkSPI.h:

Source/WebKit:

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):

Tools:

* TestWebKitAPI/SourcesCocoa.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/HSTS.mm: Added.
(TestWebKitAPI::hasRadar80550123):
(TestWebKitAPI::hstsWebViewAndDelegate):
(TestWebKitAPI::hstsServer):
(TestWebKitAPI::TEST):

Modified Paths

Added Paths

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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to