Title: [243973] releases/WebKitGTK/webkit-2.24
Revision
243973
Author
[email protected]
Date
2019-04-08 03:14:04 -0700 (Mon, 08 Apr 2019)

Log Message

Merge r243434 - [GTK][WPE] Do not allow changes in active URI before provisional load starts for non-API requests
https://bugs.webkit.org/show_bug.cgi?id=194208

Reviewed by Michael Catanzaro.

* UIProcess/API/glib/WebKitWebView.cpp:
(webkitWebViewWillStartLoad): Block updates of active URL.
(webkitWebViewLoadChanged): Unblock updates of active URL on WEBKIT_LOAD_STARTED.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.24/Source/WebKit/ChangeLog (243972 => 243973)


--- releases/WebKitGTK/webkit-2.24/Source/WebKit/ChangeLog	2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Source/WebKit/ChangeLog	2019-04-08 10:14:04 UTC (rev 243973)
@@ -1,3 +1,14 @@
+2019-03-25  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WPE] Do not allow changes in active URI before provisional load starts for non-API requests
+        https://bugs.webkit.org/show_bug.cgi?id=194208
+
+        Reviewed by Michael Catanzaro.
+
+        * UIProcess/API/glib/WebKitWebView.cpp:
+        (webkitWebViewWillStartLoad): Block updates of active URL.
+        (webkitWebViewLoadChanged): Unblock updates of active URL on WEBKIT_LOAD_STARTED.
+
 2019-03-12  Carlos Garcia Campos  <[email protected]>
 
         [WPE][GTK] Load events may occur in unexpected order when JS redirects page before subresource load finishes

Modified: releases/WebKitGTK/webkit-2.24/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp (243972 => 243973)


--- releases/WebKitGTK/webkit-2.24/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp	2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp	2019-04-08 10:14:04 UTC (rev 243973)
@@ -246,6 +246,7 @@
     CString title;
     CString customTextEncoding;
     CString activeURI;
+    bool isActiveURIChangeBlocked;
     bool isLoading;
     bool isEphemeral;
     bool isControlledByAutomation;
@@ -355,10 +356,14 @@
 
     void willChangeActiveURL() override
     {
+        if (m_webView->priv->isActiveURIChangeBlocked)
+            return;
         g_object_freeze_notify(G_OBJECT(m_webView));
     }
     void didChangeActiveURL() override
     {
+        if (m_webView->priv->isActiveURIChangeBlocked)
+            return;
         m_webView->priv->activeURI = getPage(m_webView).pageLoadState().activeURL().utf8();
         g_object_notify(G_OBJECT(m_webView), "uri");
         g_object_thaw_notify(G_OBJECT(m_webView));
@@ -2077,6 +2082,15 @@
 
 void webkitWebViewWillStartLoad(WebKitWebView* webView)
 {
+    // Ignore the active URI changes happening before WEBKIT_LOAD_STARTED. If they are not user-initiated,
+    // they could be a malicious attempt to trick users by loading an invalid URI on a trusted host, with the load
+    // intended to stall, or perhaps be repeated. If we trust the URI here and display it to the user, then the user's
+    // only indication that something is wrong would be a page loading indicator. If the load request is not
+    // user-initiated, we must not trust it until WEBKIT_LOAD_COMMITTED. If the load is triggered by API
+    // request, then the active URI is already the pending API request URL, so the blocking is harmless and the
+    // client application will still see the URI update immediately. Otherwise, the URI update will be delayed a bit.
+    webView->priv->isActiveURIChangeBlocked = true;
+
     // This is called before NavigationClient::didStartProvisionalNavigation(), the page load state hasn't been committed yet.
     auto& pageLoadState = getPage(webView).pageLoadState();
     if (pageLoadState.isFinished())
@@ -2099,15 +2113,24 @@
         webkitWebViewCancelAuthenticationRequest(webView);
         priv->loadingResourcesMap.clear();
         priv->mainResource = nullptr;
+        webView->priv->isActiveURIChangeBlocked = false;
         break;
+    case WEBKIT_LOAD_COMMITTED: {
+        auto activeURL = getPage(webView).pageLoadState().activeURL().utf8();
+        // Active URL is trusted now. If it's different to our active URI, due to the
+        // update block before WEBKIT_LOAD_STARTED, we update it here to be in sync
+        // again with the page load state.
+        if (activeURL != priv->activeURI) {
+            priv->activeURI = activeURL;
+            g_object_notify(G_OBJECT(webView), "uri");
+        }
 #if PLATFORM(GTK)
-    case WEBKIT_LOAD_COMMITTED: {
         WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
         GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data()));
         webkitWebViewUpdateFaviconURI(webView, faviconURI.get());
+#endif
         break;
     }
-#endif
     case WEBKIT_LOAD_FINISHED:
         webkitWebViewCancelAuthenticationRequest(webView);
         break;

Modified: releases/WebKitGTK/webkit-2.24/Tools/ChangeLog (243972 => 243973)


--- releases/WebKitGTK/webkit-2.24/Tools/ChangeLog	2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Tools/ChangeLog	2019-04-08 10:14:04 UTC (rev 243973)
@@ -1,3 +1,13 @@
+2019-03-27  Carlos Garcia Campos  <[email protected]>
+
+        Unreviewed. Add GLib API test cases after r243434.
+
+        * TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp:
+        (testWebViewActiveURI):
+        (serverCallback):
+        * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
+        (sendRequestCallback):
+
 2019-03-12  Michael Catanzaro  <[email protected]>
 
         [WPE][GTK] Load events may occur in unexpected order when JS redirects page before subresource load finishes

Modified: releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp (243972 => 243973)


--- releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp	2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp	2019-04-08 10:14:04 UTC (rev 243973)
@@ -368,6 +368,55 @@
     test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, "/normal-change-request");
     test->checkURIAtState(ViewURITrackingTest::State::Commited, "/request-changed-on-redirect");
     test->checkURIAtState(ViewURITrackingTest::State::Finished, "/request-changed-on-redirect");
+
+    // Non-API request loads.
+    test->loadURI(kServer->getURIForPath("/redirect-js/normal").data());
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/normal");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/normal");
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/normal");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/normal");
+
+    test->loadURI(kServer->getURIForPath("/redirect-js/redirect").data());
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/redirect");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/redirect");
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, "/normal");
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/normal");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/normal");
+
+    test->loadURI(kServer->getURIForPath("/redirect-js/normal-change-request").data());
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/normal-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/normal-change-request");
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/request-changed");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/request-changed");
+
+    test->loadURI(kServer->getURIForPath("/redirect-js/redirect-to-change-request").data());
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect-to-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/redirect-to-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/redirect-to-change-request");
+    test->waitUntilLoadFinished();
+    test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect-to-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, "/normal-change-request");
+    test->checkURIAtState(ViewURITrackingTest::State::Commited, "/request-changed-on-redirect");
+    test->checkURIAtState(ViewURITrackingTest::State::Finished, "/request-changed-on-redirect");
 }
 
 class ViewIsLoadingTest: public LoadTrackingTest {
@@ -618,16 +667,6 @@
         "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
         "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>";
 
-    static const char* unfinishedSubresourceLoadResponseString = "<html><body>"
-        "<img src=""
-        "<script>"
-        "  function run() {"
-        "      location = '/normal';"
-        "  }"
-        "  setInterval(run(), 50);"
-        "</script>"
-        "</body></html>";
-
     if (message->method != SOUP_METHOD_GET) {
         soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
         return;
@@ -645,6 +684,10 @@
     } else if (g_str_equal(path, "/redirect-to-change-request")) {
         soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
         soup_message_headers_append(message->response_headers, "Location", "/normal-change-request");
+    } else if (g_str_has_prefix(path, "/redirect-js/")) {
+        static const char* redirectJSFormat = "<html><body><script>location = '%s';</script></body></html>";
+        char* redirectJS = g_strdup_printf(redirectJSFormat, g_strrstr(path, "/"));
+        soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, redirectJS, strlen(redirectJS));
     } else if (g_str_equal(path, "/cancelled")) {
         soup_message_headers_set_encoding(message->response_headers, SOUP_ENCODING_CHUNKED);
         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString));
@@ -664,6 +707,15 @@
         soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
         soup_message_headers_append(message->response_headers, "Location", "data:text/plain;charset=utf-8,data-uri");
     } else if (g_str_equal(path, "/unfinished-subresource-load")) {
+        static const char* unfinishedSubresourceLoadResponseString = "<html><body>"
+            "<img src=""
+            "<script>"
+            "  function run() {"
+            "      location = '/normal';"
+            "  }"
+            "  setInterval(run(), 50);"
+            "</script>"
+            "</body></html>";
         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, unfinishedSubresourceLoadResponseString, strlen(unfinishedSubresourceLoadResponseString));
     } else if (g_str_equal(path, "/stall")) {
         // This request is never unpaused and stalls forever.

Modified: releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp (243972 => 243973)


--- releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp	2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp	2019-04-08 10:14:04 UTC (rev 243973)
@@ -205,7 +205,7 @@
         SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request);
         g_assert_nonnull(headers);
         soup_message_headers_append(headers, "DNT", "1");
-    } else if (g_str_has_suffix(requestURI, "/normal-change-request")) {
+    } else if (g_str_has_suffix(requestURI, "/normal-change-request") && !g_strrstr(requestURI, "/redirect-js/")) {
         GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen("/normal-change-request")));
         GUniquePtr<char> newURI(g_strdup_printf("%s/request-changed%s", prefix.get(), redirectResponse ? "-on-redirect" : ""));
         webkit_uri_request_set_uri(request, newURI.get());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to