Title: [264664] trunk
Revision
264664
Author
you...@apple.com
Date
2020-07-21 11:13:18 -0700 (Tue, 21 Jul 2020)

Log Message

Fetch/XHR loads done by extensions should opt out of response sanitisation done in network process
https://bugs.webkit.org/show_bug.cgi?id=214588
Source/WebKit:

<rdar://problem/65060560>

Reviewed by Alex Christensen.

Send to network process the CORS disabling patterns.
Disable sanitization for fetch/xhr loads whose pages have a matching pattern.

Covered by API test.

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::setCORSDisablingPatterns):
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/NetworkConnectionToWebProcess.messages.in:
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::shouldDisableCORSForRequestTo const):
(WebKit::NetworkProcess::setCORSDisablingPatterns):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::shouldSanitizeResponse):
(WebKit::NetworkResourceLoader::sanitizeResponseIfPossible):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::parseAndAllowAccessToCORSDisablingPatterns):
(WebKit::m_limitsNavigationsToAppBoundDomains):
(WebKit::WebPage::~WebPage):
(WebKit::WebPage::updateCORSDisablingPatterns):
(WebKit::WebPage::synchronizeCORSDisablingPatternsWithNetworkProcess):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::ensureNetworkProcessConnection):

Tools:

Reviewed by Alex Christensen.

Update test to check for header. Minor modernization of the JS script to impriove readability.

* TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (264663 => 264664)


--- trunk/Source/WebKit/ChangeLog	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/ChangeLog	2020-07-21 18:13:18 UTC (rev 264664)
@@ -1,3 +1,37 @@
+2020-07-21  Youenn Fablet  <you...@apple.com>
+
+        Fetch/XHR loads done by extensions should opt out of response sanitisation done in network process
+        https://bugs.webkit.org/show_bug.cgi?id=214588
+        <rdar://problem/65060560>
+
+        Reviewed by Alex Christensen.
+
+        Send to network process the CORS disabling patterns.
+        Disable sanitization for fetch/xhr loads whose pages have a matching pattern.
+
+        Covered by API test.
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::setCORSDisablingPatterns):
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::shouldDisableCORSForRequestTo const):
+        (WebKit::NetworkProcess::setCORSDisablingPatterns):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::shouldSanitizeResponse):
+        (WebKit::NetworkResourceLoader::sanitizeResponseIfPossible):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::parseAndAllowAccessToCORSDisablingPatterns):
+        (WebKit::m_limitsNavigationsToAppBoundDomains):
+        (WebKit::WebPage::~WebPage):
+        (WebKit::WebPage::updateCORSDisablingPatterns):
+        (WebKit::WebPage::synchronizeCORSDisablingPatternsWithNetworkProcess):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::ensureNetworkProcessConnection):
+
 2020-07-21  Eric Carlson  <eric.carl...@apple.com>
 
         Use AVRoutePickerView when available for choosing AirPlay devices

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (264663 => 264664)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2020-07-21 18:13:18 UTC (rev 264664)
@@ -1148,6 +1148,11 @@
     connection().send(Messages::NetworkProcessConnection::BroadcastConsoleMessage(source, level, message), 0);
 }
 
+void NetworkConnectionToWebProcess::setCORSDisablingPatterns(WebCore::PageIdentifier pageIdentifier, Vector<String>&& patterns)
+{
+    networkProcess().setCORSDisablingPatterns(pageIdentifier, WTFMove(patterns));
+}
+
 } // namespace WebKit
 
 #undef NETWORK_PROCESS_MESSAGE_CHECK_COMPLETION

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h (264663 => 264664)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h	2020-07-21 18:13:18 UTC (rev 264664)
@@ -248,6 +248,8 @@
     void checkRemotePortForActivity(const WebCore::MessagePortIdentifier, CompletionHandler<void(bool)>&&);
     void didDeliverMessagePortMessages(uint64_t messageBatchIdentifier);
 
+    void setCORSDisablingPatterns(WebCore::PageIdentifier, Vector<String>&&);
+
 #if USE(LIBWEBRTC)
     NetworkRTCProvider& rtcProvider();
 #endif

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in (264663 => 264664)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in	2020-07-21 18:13:18 UTC (rev 264664)
@@ -94,4 +94,5 @@
     CheckRemotePortForActivity(struct WebCore::MessagePortIdentifier port) -> (bool hasActivity) Async
     DidDeliverMessagePortMessages(uint64_t messageBatchIdentifier)
     RegisterURLSchemesAsCORSEnabled(Vector<String> schemes);
+    SetCORSDisablingPatterns(WebCore::PageIdentifier pageIdentifier, Vector<String> patterns)
 }

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (264663 => 264664)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2020-07-21 18:13:18 UTC (rev 264664)
@@ -80,6 +80,7 @@
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/SecurityOriginData.h>
 #include <WebCore/StorageQuotaManager.h>
+#include <WebCore/UserContentURLPattern.h>
 #include <wtf/Algorithms.h>
 #include <wtf/CallbackAggregator.h>
 #include <wtf/OptionSet.h>
@@ -2828,4 +2829,28 @@
     completionHandler();
 }
 
+bool NetworkProcess::shouldDisableCORSForRequestTo(PageIdentifier pageIdentifier, const URL& url) const
+{
+    return WTF::anyOf(m_extensionCORSDisablingPatterns.get(pageIdentifier), [&] (const auto& pattern) {
+        return pattern.matches(url);
+    });
+}
+
+void NetworkProcess::setCORSDisablingPatterns(PageIdentifier pageIdentifier, Vector<String>&& patterns)
+{
+    Vector<UserContentURLPattern> parsedPatterns;
+    parsedPatterns.reserveInitialCapacity(patterns.size());
+    for (auto&& pattern : WTFMove(patterns)) {
+        UserContentURLPattern parsedPattern(WTFMove(pattern));
+        if (parsedPattern.isValid())
+            parsedPatterns.uncheckedAppend(WTFMove(parsedPattern));
+    }
+    parsedPatterns.shrinkToFit();
+    if (parsedPatterns.isEmpty()) {
+        m_extensionCORSDisablingPatterns.remove(pageIdentifier);
+        return;
+    }
+    m_extensionCORSDisablingPatterns.set(pageIdentifier, WTFMove(parsedPatterns));
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (264663 => 264664)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2020-07-21 18:13:18 UTC (rev 264664)
@@ -83,6 +83,7 @@
 class NetworkStorageSession;
 class ResourceError;
 class SWServer;
+class UserContentURLPattern;
 enum class HTTPCookieAcceptPolicy : uint8_t;
 enum class IncludeHttpOnlyCookies : bool;
 enum class StoredCredentialsPolicy : uint8_t;
@@ -363,6 +364,9 @@
     void updateBundleIdentifier(String&&, CompletionHandler<void()>&&);
     void clearBundleIdentifier(CompletionHandler<void()>&&);
 
+    bool shouldDisableCORSForRequestTo(WebCore::PageIdentifier, const URL&) const;
+    void setCORSDisablingPatterns(WebCore::PageIdentifier, Vector<String>&&);
+
 private:
     void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&);
     std::unique_ptr<WebCore::NetworkStorageSession> platformCreateDefaultStorageSession() const;
@@ -599,6 +603,8 @@
 
     static const Seconds defaultServiceWorkerFetchTimeout;
     Seconds m_serviceWorkerFetchTimeout { defaultServiceWorkerFetchTimeout };
+
+    HashMap<WebCore::PageIdentifier, Vector<WebCore::UserContentURLPattern>> m_extensionCORSDisablingPatterns;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (264663 => 264664)


--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2020-07-21 18:13:18 UTC (rev 264664)
@@ -906,9 +906,19 @@
     cleanup(LoadResult::Success);
 }
 
+static bool shouldSanitizeResponse(const NetworkProcess& process, Optional<PageIdentifier> pageIdentifier, const FetchOptions& options, const URL& url)
+{
+    if (!pageIdentifier || options.destination != FetchOptions::Destination::EmptyString || options.mode != FetchOptions::Mode::NoCors)
+        return true;
+    return !process.shouldDisableCORSForRequestTo(*pageIdentifier, url);
+}
+
 ResourceResponse NetworkResourceLoader::sanitizeResponseIfPossible(ResourceResponse&& response, ResourceResponse::SanitizationType type)
 {
-    if (m_parameters.shouldRestrictHTTPResponseAccess)
+    if (!m_parameters.shouldRestrictHTTPResponseAccess)
+        return WTFMove(response);
+
+    if (shouldSanitizeResponse(m_connection->networkProcess(), pageID(), parameters().options, originalRequest().url()))
         response.sanitizeHTTPHeaderFields(type);
 
     return WTFMove(response);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (264663 => 264664)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-07-21 18:13:18 UTC (rev 264664)
@@ -393,12 +393,12 @@
     return page;
 }
 
-static Vector<UserContentURLPattern> parseAndAllowAccessToCORSDisablingPatterns(Vector<String>&& input)
+static Vector<UserContentURLPattern> parseAndAllowAccessToCORSDisablingPatterns(const Vector<String>& input)
 {
     Vector<UserContentURLPattern> parsedPatterns;
     parsedPatterns.reserveInitialCapacity(input.size());
-    for (auto&& pattern : WTFMove(input)) {
-        UserContentURLPattern parsedPattern(WTFMove(pattern));
+    for (const auto& pattern : input) {
+        UserContentURLPattern parsedPattern(pattern);
         if (parsedPattern.isValid()) {
             WebCore::SecurityPolicy::allowAccessTo(parsedPattern);
             parsedPatterns.uncheckedAppend(WTFMove(parsedPattern));
@@ -548,8 +548,12 @@
 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
     pageConfiguration.deviceOrientationUpdateProvider = WebDeviceOrientationUpdateProvider::create(*this);
 #endif
-    
-    pageConfiguration.corsDisablingPatterns = parseAndAllowAccessToCORSDisablingPatterns(WTFMove(parameters.corsDisablingPatterns));
+
+    m_corsDisablingPatterns = WTFMove(parameters.corsDisablingPatterns);
+    if (!m_corsDisablingPatterns.isEmpty())
+        synchronizeCORSDisablingPatternsWithNetworkProcess();
+    pageConfiguration.corsDisablingPatterns = parseAndAllowAccessToCORSDisablingPatterns(m_corsDisablingPatterns);
+
     pageConfiguration.userScriptsShouldWaitUntilNotification = parameters.userScriptsShouldWaitUntilNotification;
     pageConfiguration.loadsSubresources = parameters.loadsSubresources;
     pageConfiguration.loadsFromNetwork = parameters.loadsFromNetwork;
@@ -870,6 +874,11 @@
 {
     ASSERT(!m_page);
 
+    if (!m_corsDisablingPatterns.isEmpty()) {
+        m_corsDisablingPatterns.clear();
+        synchronizeCORSDisablingPatternsWithNetworkProcess();
+    }
+
     platformDetach();
     
     m_sandboxExtensionTracker.invalidate();
@@ -7126,10 +7135,20 @@
 
 void WebPage::updateCORSDisablingPatterns(Vector<String>&& patterns)
 {
-    if (m_page)
-        m_page->setCORSDisablingPatterns(parseAndAllowAccessToCORSDisablingPatterns(WTFMove(patterns)));
+    if (!m_page)
+        return;
+
+    m_corsDisablingPatterns = WTFMove(patterns);
+    synchronizeCORSDisablingPatternsWithNetworkProcess();
+    m_page->setCORSDisablingPatterns(parseAndAllowAccessToCORSDisablingPatterns(m_corsDisablingPatterns));
 }
 
+void WebPage::synchronizeCORSDisablingPatternsWithNetworkProcess()
+{
+    // FIXME: We should probably have this mechanism done between UIProcess and NetworkProcess directly.
+    WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCORSDisablingPatterns(m_identifier, m_corsDisablingPatterns), 0);
+}
+
 bool WebPage::shouldUseRemoteRenderingFor(RenderingPurpose purpose)
 {
 #if ENABLE(GPU_PROCESS)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (264663 => 264664)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2020-07-21 18:13:18 UTC (rev 264664)
@@ -1344,6 +1344,8 @@
 
     static void updatePreferencesGenerated(const WebPreferencesStore&);
 
+    void synchronizeCORSDisablingPatternsWithNetworkProcess();
+
 private:
     WebPage(WebCore::PageIdentifier, WebPageCreationParameters&&);
 
@@ -2132,6 +2134,7 @@
     
     bool m_limitsNavigationsToAppBoundDomains { false };
     bool m_navigationHasOccured { false };
+    Vector<String> m_corsDisablingPatterns;
 };
 
 #if !PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (264663 => 264664)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2020-07-21 18:13:18 UTC (rev 264664)
@@ -1148,6 +1148,8 @@
         if (!Document::allDocuments().isEmpty())
             m_networkProcessConnection->serviceWorkerConnection().registerServiceWorkerClients();
 #endif
+        for (auto& webPage : m_pageMap.values())
+            webPage->synchronizeCORSDisablingPatternsWithNetworkProcess();
     }
     
     return *m_networkProcessConnection;

Modified: trunk/Tools/ChangeLog (264663 => 264664)


--- trunk/Tools/ChangeLog	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Tools/ChangeLog	2020-07-21 18:13:18 UTC (rev 264664)
@@ -1,3 +1,14 @@
+2020-07-21  Youenn Fablet  <you...@apple.com>
+
+        Fetch/XHR loads done by extensions should opt out of response sanitisation done in network process
+        https://bugs.webkit.org/show_bug.cgi?id=214588
+
+        Reviewed by Alex Christensen.
+
+        Update test to check for header. Minor modernization of the JS script to impriove readability.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
+
 2020-07-21  Eric Carlson  <eric.carl...@apple.com>
 
         Use AVRoutePickerView when available for choosing AirPlay devices

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm (264663 => 264664)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2020-07-21 17:46:28 UTC (rev 264663)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2020-07-21 18:13:18 UTC (rev 264664)
@@ -836,7 +836,7 @@
 TEST(URLSchemeHandler, DisableCORS)
 {
     TestWebKitAPI::HTTPServer server({
-        { "/subresource", { {{ "Content-Type", "application/json" }}, "{\"testkey\":\"testvalue\"}" } }
+        { "/subresource", { {{ "Content-Type", "application/json" }, { "headerName", "headerValue" }}, "{\"testKey\":\"testValue\"}" } }
     });
 
     bool corssuccess = false;
@@ -849,14 +849,13 @@
     [configuration setURLSchemeHandler:handler.get() forURLScheme:@"cors"];
 
     NSString *testJS = [NSString stringWithFormat:
-        @"fetch('http://127.0.0.1:%d/subresource').then(function(r){"
-            "r.json().then(function(object) {"
-                "if (object.testkey == 'testvalue') {"
-                    "fetch('/corssuccess')"
-                "} else {"
-                    "fetch('/corsfailure')"
-                "}"
-            "}).catch(function(){fetch('/corsfailure')})"
+        @"fetch('http://127.0.0.1:%d/subresource').then(async (r) => {"
+            "if (r.headers.get('headerName') != 'headerValue')"
+                "return fetch('/corsfailure');"
+            "const object = await r.json();"
+            "if (object.testKey != 'testValue')"
+                "return fetch('/corsfailure');"
+            "fetch('/corssuccess');"
         "}).catch(function(){fetch('/corsfailure')})"
         , server.port()];
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to