Title: [246872] trunk
Revision
246872
Author
[email protected]
Date
2019-06-26 23:33:50 -0700 (Wed, 26 Jun 2019)

Log Message

SubFrameSOAuthorizationSession should preserve the referrer header when fall back to web path
https://bugs.webkit.org/show_bug.cgi?id=199232
<rdar://problem/51718328>

Reviewed by Youenn Fablet.

Source/WebKit:

The fall back to web path mechanism in SubFrameSOAuthorizationSession doesn't actually resume
the previous navigation. Instead it starts a new one. The current implementation doesn't carry
any information from the previous navigation. It is problematic when it comes to http referrer
as the server might use that to determine what kind of responses to send back. Therefore, we
add that information now.

To accomplish the above, the patch teaches WebFrameProxy::loadURL to carry referrer information
when it is available. Then SubFrameSOAuthorizationSession can reuses the referrer from the
original request.

* UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm:
(WebKit::SubFrameSOAuthorizationSession::fallBackToWebPathInternal):
* UIProcess/WebFrameProxy.cpp:
(WebKit::WebFrameProxy::loadURL):
* UIProcess/WebFrameProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::loadURLInFrame):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm:
(TestWebKitAPI::TEST):
Add a test that utilizes TCPServer as local files always omit referrer.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (246871 => 246872)


--- trunk/Source/WebKit/ChangeLog	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/ChangeLog	2019-06-27 06:33:50 UTC (rev 246872)
@@ -1,3 +1,31 @@
+2019-06-26  Jiewen Tan  <[email protected]>
+
+        SubFrameSOAuthorizationSession should preserve the referrer header when fall back to web path
+        https://bugs.webkit.org/show_bug.cgi?id=199232
+        <rdar://problem/51718328>
+
+        Reviewed by Youenn Fablet.
+
+        The fall back to web path mechanism in SubFrameSOAuthorizationSession doesn't actually resume
+        the previous navigation. Instead it starts a new one. The current implementation doesn't carry
+        any information from the previous navigation. It is problematic when it comes to http referrer
+        as the server might use that to determine what kind of responses to send back. Therefore, we
+        add that information now.
+
+        To accomplish the above, the patch teaches WebFrameProxy::loadURL to carry referrer information
+        when it is available. Then SubFrameSOAuthorizationSession can reuses the referrer from the
+        original request.
+
+        * UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm:
+        (WebKit::SubFrameSOAuthorizationSession::fallBackToWebPathInternal):
+        * UIProcess/WebFrameProxy.cpp:
+        (WebKit::WebFrameProxy::loadURL):
+        * UIProcess/WebFrameProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::loadURLInFrame):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2019-06-26  Fujii Hironori  <[email protected]>
 
         testRunner.setAlwaysAcceptCookies should wait for cookie accept policy to be set

Modified: trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm (246871 => 246872)


--- trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SubFrameSOAuthorizationSession.mm	2019-06-27 06:33:50 UTC (rev 246872)
@@ -68,7 +68,7 @@
             if (auto* frame = page->process().webFrame(targetFrame->handle().frameID())) {
                 page->setShouldSuppressSOAuthorizationInNextNavigationPolicyDecision();
                 // Issue a new load to the original URL as the original load is aborted before start.
-                frame->loadURL(navigationActionPtr->request().url());
+                frame->loadURL(navigationActionPtr->request().url(), navigationActionPtr->request().httpReferrer());
             }
         }
     });

Modified: trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp (246871 => 246872)


--- trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/UIProcess/WebFrameProxy.cpp	2019-06-27 06:33:50 UTC (rev 246872)
@@ -79,12 +79,12 @@
     return this == m_page->mainFrame() || (m_page->provisionalPageProxy() && this == m_page->provisionalPageProxy()->mainFrame());
 }
 
-void WebFrameProxy::loadURL(const URL& url)
+void WebFrameProxy::loadURL(const URL& url, const String& referrer)
 {
     if (!m_page)
         return;
 
-    m_page->process().send(Messages::WebPage::LoadURLInFrame(url, m_frameID), m_page->pageID());
+    m_page->process().send(Messages::WebPage::LoadURLInFrame(url, referrer, m_frameID), m_page->pageID());
 }
 
 void WebFrameProxy::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encodingName, const URL& baseURL)

Modified: trunk/Source/WebKit/UIProcess/WebFrameProxy.h (246871 => 246872)


--- trunk/Source/WebKit/UIProcess/WebFrameProxy.h	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/UIProcess/WebFrameProxy.h	2019-06-27 06:33:50 UTC (rev 246872)
@@ -78,7 +78,7 @@
 
     FrameLoadState& frameLoadState() { return m_frameLoadState; }
 
-    void loadURL(const URL&);
+    void loadURL(const URL&, const String& referrer = String());
     // Sub frames only. For main frames, use WebPageProxy::loadData.
     void loadData(const IPC::DataReference&, const String& MIMEType, const String& encodingName, const URL& baseURL);
     void stopLoading() const;

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (246871 => 246872)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2019-06-27 06:33:50 UTC (rev 246872)
@@ -1488,13 +1488,13 @@
     send(Messages::WebPageProxy::DidSuspendAfterProcessSwap());
 }
 
-void WebPage::loadURLInFrame(URL&& url, uint64_t frameID)
+void WebPage::loadURLInFrame(URL&& url, const String& referrer, uint64_t frameID)
 {
     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
     if (!frame)
         return;
 
-    frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(url), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
+    frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(url, referrer), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
 }
 
 void WebPage::loadDataInFrame(IPC::DataReference&& data, String&& MIMEType, String&& encodingName, URL&& baseURL, uint64_t frameID)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (246871 => 246872)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-06-27 06:33:50 UTC (rev 246872)
@@ -1337,7 +1337,7 @@
     static bool scroll(WebCore::Page*, WebCore::ScrollDirection, WebCore::ScrollGranularity);
     static bool logicalScroll(WebCore::Page*, WebCore::ScrollLogicalDirection, WebCore::ScrollGranularity);
 
-    void loadURLInFrame(URL&&, uint64_t frameID);
+    void loadURLInFrame(URL&&, const String& referrer, uint64_t frameID);
     void loadDataInFrame(IPC::DataReference&&, String&& MIMEType, String&& encodingName, URL&& baseURL, uint64_t frameID);
 
     enum class WasRestoredByAPIRequest { No, Yes };

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (246871 => 246872)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2019-06-27 06:33:50 UTC (rev 246872)
@@ -158,7 +158,7 @@
     GoToBackForwardItem(uint64_t navigationID, struct WebCore::BackForwardItemIdentifier backForwardItemID, enum:uint8_t WebCore::FrameLoadType backForwardType, enum:bool WebCore::ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<WebKit::WebsitePoliciesData> websitePolicies)
     TryRestoreScrollPosition()
 
-    LoadURLInFrame(URL url, uint64_t frameID)
+    LoadURLInFrame(URL url, String referrer, uint64_t frameID)
     LoadDataInFrame(IPC::DataReference data, String MIMEType, String encodingName, URL baseURL, uint64_t frameID)
     LoadRequest(struct WebKit::LoadParameters loadParameters)
     LoadData(struct WebKit::LoadParameters loadParameters)

Modified: trunk/Tools/ChangeLog (246871 => 246872)


--- trunk/Tools/ChangeLog	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Tools/ChangeLog	2019-06-27 06:33:50 UTC (rev 246872)
@@ -1,3 +1,15 @@
+2019-06-26  Jiewen Tan  <[email protected]>
+
+        SubFrameSOAuthorizationSession should preserve the referrer header when fall back to web path
+        https://bugs.webkit.org/show_bug.cgi?id=199232
+        <rdar://problem/51718328>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm:
+        (TestWebKitAPI::TEST):
+        Add a test that utilizes TCPServer as local files always omit referrer.
+
 2019-06-26  Aakash Jain  <[email protected]>
 
         [ews-build] Add configuration and architecture for WPE and GTK builders

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm (246871 => 246872)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm	2019-06-27 05:01:24 UTC (rev 246871)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TestSOAuthorization.mm	2019-06-27 06:33:50 UTC (rev 246872)
@@ -31,10 +31,12 @@
 #import "ClassMethodSwizzler.h"
 #import "InstanceMethodSwizzler.h"
 #import "PlatformUtilities.h"
+#import "TCPServer.h"
 #import "TestWKWebView.h"
 #import <WebKit/WKNavigationActionPrivate.h>
 #import <WebKit/WKNavigationDelegatePrivate.h>
 #import <WebKit/WKNavigationPrivate.h>
+#import <WebKit/WKWebViewPrivate.h>
 #import <pal/cocoa/AppSSOSoftLink.h>
 #import <pal/spi/cocoa/AuthKitSPI.h>
 #import <wtf/BlockPtr.h>
@@ -41,6 +43,7 @@
 #import <wtf/RetainPtr.h>
 #import <wtf/StringPrintStream.h>
 #import <wtf/URL.h>
+#import <wtf/text/StringConcatenateNumbers.h>
 #import <wtf/text/WTFString.h>
 
 static bool navigationCompleted = false;
@@ -95,6 +98,7 @@
 
 static const char* parentTemplate =
 "<html>"
+"<meta name='referrer' content='origin' />"
 "<iframe src=''></iframe>"
 "<script>"
 "function receiveMessage(event)"
@@ -110,6 +114,7 @@
 "<html>"
 "<script>"
 "parent.postMessage('Hello.', '*');"
+"%s"
 "</script>"
 "</html>";
 
@@ -2124,6 +2129,51 @@
     EXPECT_FALSE(authorizationPerformed);
 }
 
+TEST(SOAuthorizationSubFrame, InterceptionErrorWithReferrer)
+{
+    resetState();
+    ClassMethodSwizzler swizzler1(PAL::getSOAuthorizationClass(), @selector(canPerformAuthorizationWithURL:responseCode:), reinterpret_cast<IMP>(overrideCanPerformAuthorizationWithURL));
+    InstanceMethodSwizzler swizzler2(PAL::getSOAuthorizationClass(), @selector(setDelegate:), reinterpret_cast<IMP>(overrideSetDelegate));
+    InstanceMethodSwizzler swizzler3(PAL::getSOAuthorizationClass(), @selector(beginAuthorizationWithURL:httpHeaders:httpBody:), reinterpret_cast<IMP>(overrideBeginAuthorizationWithURL));
+    ClassMethodSwizzler swizzler4([AKAuthorizationController class], @selector(isURLFromAppleOwnedDomain:), reinterpret_cast<IMP>(overrideIsURLFromAppleOwnedDomain));
+
+    TCPServer server([parentHtml = generateHtml(parentTemplate, "simple.html"), frameHtml = generateHtml(iframeTemplate, "parent.postMessage('Referrer: ' + document.referrer, '*');")] (int socket) {
+        NSString *firstResponse = [NSString stringWithFormat:
+            @"HTTP/1.1 200 OK\r\n"
+            "Content-Length: %d\r\n\r\n"
+            "%@",
+            parentHtml.length(),
+            (id)parentHtml
+        ];
+        NSString *secondResponse = [NSString stringWithFormat:
+            @"HTTP/1.1 200 OK\r\n"
+            "Content-Length: %d\r\n\r\n"
+            "%@",
+            frameHtml.length(),
+            (id)frameHtml
+        ];
+
+        TCPServer::read(socket);
+        TCPServer::write(socket, firstResponse.UTF8String, firstResponse.length);
+        TCPServer::read(socket);
+        TCPServer::write(socket, secondResponse.UTF8String, secondResponse.length);
+    });
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto delegate = adoptNS([[TestSOAuthorizationNavigationDelegate alloc] init]);
+    configureSOAuthorizationWebView(webView.get(), delegate.get());
+
+    auto origin = makeString("http://127.0.0.1:", static_cast<unsigned>(server.port()));
+    [webView _loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:(id)origin]] shouldOpenExternalURLs:NO];
+    [webView waitForMessage:(id)origin];
+    [webView waitForMessage:@"SOAuthorizationDidStart"];
+
+    [gDelegate authorization:gAuthorization didCompleteWithError:adoptNS([[NSError alloc] initWithDomain:NSCocoaErrorDomain code:0 userInfo:nil]).get()];
+    [webView waitForMessage:(id)origin];
+    [webView waitForMessage:@"SOAuthorizationDidCancel"];
+    [webView waitForMessage:(id)makeString("Referrer: ", origin, "/")]; // Referrer policy requires '/' after origin.
+}
+
 } // namespace TestWebKitAPI
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to