Title: [274197] trunk
Revision
274197
Author
[email protected]
Date
2021-03-09 21:30:39 -0800 (Tue, 09 Mar 2021)

Log Message

HTTPS upgrade should allow same-site redirects from HTTPS to HTTP
https://bugs.webkit.org/show_bug.cgi?id=222994
<rdar://75159643>

Patch by Alex Christensen <[email protected]> on 2021-03-09
Reviewed by Geoff Garen.

Source/WebCore:

Several sites support HTTPS, but have certain pages or resources that for some reason are only served over HTTP.
If you try to load the resource over HTTPS, it will simply redirect you to HTTP.  In order to increase compatibility
with the web, we need to not do infinite redirect loops in this case.

The next version of this patch will have a test, but feel free to review the content of this code change before then.

* contentextensions/ContentExtensionsBackend.cpp:
(WebCore::ContentExtensions::makeSecureIfNecessary):
(WebCore::ContentExtensions::ContentExtensionsBackend::processContentRuleListsForLoad):
* contentextensions/ContentExtensionsBackend.h:
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::willSendRequestInternal):
* page/UserContentProvider.cpp:
(WebCore::UserContentProvider::processContentRuleListsForLoad):
* page/UserContentProvider.h:
(WebCore::UserContentProvider::processContentRuleListsForLoad):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (274196 => 274197)


--- trunk/Source/WebCore/ChangeLog	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Source/WebCore/ChangeLog	2021-03-10 05:30:39 UTC (rev 274197)
@@ -1,3 +1,28 @@
+2021-03-09  Alex Christensen  <[email protected]>
+
+        HTTPS upgrade should allow same-site redirects from HTTPS to HTTP
+        https://bugs.webkit.org/show_bug.cgi?id=222994
+        <rdar://75159643>
+
+        Reviewed by Geoff Garen.
+
+        Several sites support HTTPS, but have certain pages or resources that for some reason are only served over HTTP.
+        If you try to load the resource over HTTPS, it will simply redirect you to HTTP.  In order to increase compatibility
+        with the web, we need to not do infinite redirect loops in this case.
+
+        The next version of this patch will have a test, but feel free to review the content of this code change before then.
+
+        * contentextensions/ContentExtensionsBackend.cpp:
+        (WebCore::ContentExtensions::makeSecureIfNecessary):
+        (WebCore::ContentExtensions::ContentExtensionsBackend::processContentRuleListsForLoad):
+        * contentextensions/ContentExtensionsBackend.h:
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::willSendRequestInternal):
+        * page/UserContentProvider.cpp:
+        (WebCore::UserContentProvider::processContentRuleListsForLoad):
+        * page/UserContentProvider.h:
+        (WebCore::UserContentProvider::processContentRuleListsForLoad):
+
 2021-03-09  Sam Weinig  <[email protected]>
 
         Preferences do not need to be passed to the WebProcess via WebPageCreationParameters since the store already is

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (274196 => 274197)


--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2021-03-10 05:30:39 UTC (rev 274197)
@@ -57,8 +57,11 @@
 #if USE(APPLE_INTERNAL_SDK)
 #import <WebKitAdditions/ContentRuleListAdditions.mm>
 #else
-static void makeSecureIfNecessary(ContentRuleListResults& results, const URL& url)
+static void makeSecureIfNecessary(ContentRuleListResults& results, const URL& url, const URL& redirectFrom = { })
 {
+    if (redirectFrom.host() == url.host() && redirectFrom.protocolIs("https"))
+        return;
+
     if (url.protocolIs("http") && (url.host() == "www.opengl.org" || url.host() == "download"))
         results.summary.madeHTTPS = true;
 }
@@ -163,7 +166,7 @@
     return contentExtension ? contentExtension->globalDisplayNoneStyleSheet() : nullptr;
 }
 
-ContentRuleListResults ContentExtensionsBackend::processContentRuleListsForLoad(Page& page, const URL& url, OptionSet<ResourceType> resourceType, DocumentLoader& initiatingDocumentLoader)
+ContentRuleListResults ContentExtensionsBackend::processContentRuleListsForLoad(Page& page, const URL& url, OptionSet<ResourceType> resourceType, DocumentLoader& initiatingDocumentLoader, const URL& redirectFrom)
 {
     Document* currentDocument = nullptr;
     URL mainDocumentURL;
@@ -184,7 +187,7 @@
 
     ContentRuleListResults results;
     if (page.httpsUpgradeEnabled())
-        makeSecureIfNecessary(results, url);
+        makeSecureIfNecessary(results, url, redirectFrom);
     results.results.reserveInitialCapacity(actions.size());
     for (const auto& actionsFromContentRuleList : actions) {
         const String& contentRuleListIdentifier = actionsFromContentRuleList.contentRuleListIdentifier;

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h (274196 => 274197)


--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h	2021-03-10 05:30:39 UTC (rev 274197)
@@ -63,7 +63,7 @@
     WEBCORE_EXPORT Vector<ActionsFromContentRuleList> actionsForResourceLoad(const ResourceLoadInfo&) const;
     WEBCORE_EXPORT StyleSheetContents* globalDisplayNoneStyleSheet(const String& identifier) const;
 
-    ContentRuleListResults processContentRuleListsForLoad(Page&, const URL&, OptionSet<ResourceType>, DocumentLoader& initiatingDocumentLoader);
+    ContentRuleListResults processContentRuleListsForLoad(Page&, const URL&, OptionSet<ResourceType>, DocumentLoader& initiatingDocumentLoader, const URL& redirectFrom);
     WEBCORE_EXPORT ContentRuleListResults processContentRuleListsForPingLoad(const URL&, const URL& mainDocumentURL);
 
     static const String& displayNoneCSSRule();

Modified: trunk/Source/WebCore/loader/ResourceLoader.cpp (274196 => 274197)


--- trunk/Source/WebCore/loader/ResourceLoader.cpp	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Source/WebCore/loader/ResourceLoader.cpp	2021-03-10 05:30:39 UTC (rev 274197)
@@ -355,7 +355,7 @@
     if (!redirectResponse.isNull() && frameLoader()) {
         Page* page = frameLoader()->frame().page();
         if (page && m_documentLoader) {
-            auto results = page->userContentProvider().processContentRuleListsForLoad(*page, request.url(), m_resourceType, *m_documentLoader);
+            auto results = page->userContentProvider().processContentRuleListsForLoad(*page, request.url(), m_resourceType, *m_documentLoader, redirectResponse.url());
             bool blockedLoad = results.summary.blockedLoad;
             ContentExtensions::applyResultsToRequest(WTFMove(results), page, request);
             if (blockedLoad) {

Modified: trunk/Source/WebCore/page/UserContentProvider.cpp (274196 => 274197)


--- trunk/Source/WebCore/page/UserContentProvider.cpp	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Source/WebCore/page/UserContentProvider.cpp	2021-03-10 05:30:39 UTC (rev 274197)
@@ -102,12 +102,12 @@
     return true;
 }
     
-ContentRuleListResults UserContentProvider::processContentRuleListsForLoad(Page& page, const URL& url, OptionSet<ContentExtensions::ResourceType> resourceType, DocumentLoader& initiatingDocumentLoader)
+ContentRuleListResults UserContentProvider::processContentRuleListsForLoad(Page& page, const URL& url, OptionSet<ContentExtensions::ResourceType> resourceType, DocumentLoader& initiatingDocumentLoader, const URL& redirectFrom)
 {
     if (!contentRuleListsEnabled(initiatingDocumentLoader))
         return { };
 
-    return userContentExtensionBackend().processContentRuleListsForLoad(page, url, resourceType, initiatingDocumentLoader);
+    return userContentExtensionBackend().processContentRuleListsForLoad(page, url, resourceType, initiatingDocumentLoader, redirectFrom);
 }
 #endif
 

Modified: trunk/Source/WebCore/page/UserContentProvider.h (274196 => 274197)


--- trunk/Source/WebCore/page/UserContentProvider.h	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Source/WebCore/page/UserContentProvider.h	2021-03-10 05:30:39 UTC (rev 274197)
@@ -88,7 +88,7 @@
     void removePage(Page&);
 
 #if ENABLE(CONTENT_EXTENSIONS)
-    ContentRuleListResults processContentRuleListsForLoad(Page&, const URL&, OptionSet<ContentExtensions::ResourceType>, DocumentLoader& initiatingDocumentLoader);
+    ContentRuleListResults processContentRuleListsForLoad(Page&, const URL&, OptionSet<ContentExtensions::ResourceType>, DocumentLoader& initiatingDocumentLoader, const URL& redirectFrom = { });
 #endif
 
 protected:

Modified: trunk/Tools/ChangeLog (274196 => 274197)


--- trunk/Tools/ChangeLog	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Tools/ChangeLog	2021-03-10 05:30:39 UTC (rev 274197)
@@ -1,3 +1,14 @@
+2021-03-09  Alex Christensen  <[email protected]>
+
+        HTTPS upgrade should allow same-site redirects from HTTPS to HTTP
+        https://bugs.webkit.org/show_bug.cgi?id=222994
+        <rdar://75159643>
+
+        Reviewed by Geoff Garen.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm:
+        (TEST):
+
 2021-03-09  Chris Dumez  <[email protected]>
 
         [ BigSur wk2 arm64 ] quite a few fast/forms (Layout-Tests) are text failing on Apple Silicon

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm (274196 => 274197)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm	2021-03-10 05:19:18 UTC (rev 274196)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentRuleListNotification.mm	2021-03-10 05:30:39 UTC (rev 274197)
@@ -27,7 +27,9 @@
 
 #import "HTTPServer.h"
 #import "PlatformUtilities.h"
+#import "TCPServer.h"
 #import "Test.h"
+#import "TestNavigationDelegate.h"
 #import "TestUIDelegate.h"
 #import "TestURLSchemeHandler.h"
 #import <WebKit/WKContentRuleListPrivate.h>
@@ -36,7 +38,9 @@
 #import <WebKit/WKURLSchemeHandler.h>
 #import <WebKit/WKUserContentController.h>
 #import <WebKit/WKWebView.h>
+#import <WebKit/WKWebsiteDataStorePrivate.h>
 #import <WebKit/_WKContentRuleListAction.h>
+#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/SHA1.h>
 #import <wtf/URL.h>
@@ -297,3 +301,51 @@
     for (NSString *regex in disallowed)
         EXPECT_FALSE([WKContentRuleList _supportsRegularExpression:regex]);
 }
+
+#if HAVE(SSL)
+
+TEST(WebKit, RedirectToPlaintextHTTPSUpgrade)
+{
+    using namespace TestWebKitAPI;
+    TCPServer server([connectionCount = 0] (int socket) mutable {
+        TCPServer::read(socket);
+        if (!connectionCount++) {
+            const char* connectionEstablished =
+                "HTTP/1.1 200 Connection Established\r\n"
+                "Connection: close\r\n"
+                "\r\n";
+            TCPServer::write(socket, connectionEstablished, strlen(connectionEstablished));
+            TCPServer::startSecureConnection(socket, [] (SSL* ssl) {
+                TCPServer::read(ssl);
+                const char* redirect = ""
+                "HTTP/1.1 302 Found\r\n"
+                "Location: http://download/\r\n"
+                "Content-Length: 0\r\n\r\n";
+                TCPServer::write(ssl, redirect, strlen(redirect));
+            });
+            return;
+        }
+        const char* content = ""
+        "HTTP/1.1 200 OK\r\n"
+        "Content-Length: 34\r\n\r\n"
+        "<script>alert('success!')</script>";
+        TCPServer::write(socket, content, strlen(content));
+    }, 2);
+
+    auto storeConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] initNonPersistentConfiguration]);
+    [storeConfiguration setHTTPProxy:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]];
+    [storeConfiguration setHTTPSProxy:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]];
+    [storeConfiguration setAllowsServerPreconnect:NO];
+    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]);
+    delegate.get().didReceiveAuthenticationChallenge = ^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    };
+    webView.get().navigationDelegate = delegate.get();
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://download/"]]];
+    EXPECT_WK_STREQ([webView _test_waitForAlert], "success!");
+}
+
+#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to