Title: [259772] trunk
Revision
259772
Author
[email protected]
Date
2020-04-08 17:42:25 -0700 (Wed, 08 Apr 2020)

Log Message

_corsDisablingPatterns should allow security policy access to those patterns
https://bugs.webkit.org/show_bug.cgi?id=210218
<rdar://problem/61395166>

Patch by Alex Christensen <[email protected]> on 2020-04-08
Reviewed by Timothy Hatcher.

Source/WebCore:

This gives WKWebViewConfiguration._corsDisablingPatterns power similar to WKBundleAddOriginAccessWhitelistEntry
but its API is per-WKWebView (even if its implementation is unfortunately currently process global in the web process).
Functionality covered by a new API test.

* page/Page.cpp:
(WebCore::m_loadsFromNetwork):
* page/PageConfiguration.h:
* page/SecurityOrigin.cpp:
(WebCore::SecurityOrigin::canRequest const):
(WebCore::SecurityOrigin::canDisplay const):
* page/SecurityPolicy.cpp:
(WebCore::originAccessPatterns):
(WebCore::SecurityPolicy::isAccessWhiteListed):
(WebCore::SecurityPolicy::allowAccessTo):
(WebCore::SecurityPolicy::isAccessToURLWhiteListed): Deleted.
* page/SecurityPolicy.h:

Source/WebKit:

* WebProcess/WebPage/WebPage.cpp:
(WebKit::m_processDisplayName):

Tools:

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

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (259771 => 259772)


--- trunk/Source/WebCore/ChangeLog	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebCore/ChangeLog	2020-04-09 00:42:25 UTC (rev 259772)
@@ -1,3 +1,28 @@
+2020-04-08  Alex Christensen  <[email protected]>
+
+        _corsDisablingPatterns should allow security policy access to those patterns
+        https://bugs.webkit.org/show_bug.cgi?id=210218
+        <rdar://problem/61395166>
+
+        Reviewed by Timothy Hatcher.
+
+        This gives WKWebViewConfiguration._corsDisablingPatterns power similar to WKBundleAddOriginAccessWhitelistEntry
+        but its API is per-WKWebView (even if its implementation is unfortunately currently process global in the web process).
+        Functionality covered by a new API test.
+
+        * page/Page.cpp:
+        (WebCore::m_loadsFromNetwork):
+        * page/PageConfiguration.h:
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::canRequest const):
+        (WebCore::SecurityOrigin::canDisplay const):
+        * page/SecurityPolicy.cpp:
+        (WebCore::originAccessPatterns):
+        (WebCore::SecurityPolicy::isAccessWhiteListed):
+        (WebCore::SecurityPolicy::allowAccessTo):
+        (WebCore::SecurityPolicy::isAccessToURLWhiteListed): Deleted.
+        * page/SecurityPolicy.h:
+
 2020-04-08  Wenson Hsieh  <[email protected]>
 
         REGRESSION (r258525): Occasional crashes under TextManipulationController::observeParagraphs

Modified: trunk/Source/WebCore/page/Page.cpp (259771 => 259772)


--- trunk/Source/WebCore/page/Page.cpp	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebCore/page/Page.cpp	2020-04-09 00:42:25 UTC (rev 259772)
@@ -291,6 +291,7 @@
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
     , m_deviceOrientationUpdateProvider(WTFMove(pageConfiguration.deviceOrientationUpdateProvider))
 #endif
+    , m_corsDisablingPatterns(WTFMove(pageConfiguration.corsDisablingPatterns))
     , m_loadsSubresources(pageConfiguration.loadsSubresources)
     , m_loadsFromNetwork(pageConfiguration.loadsFromNetwork)
 {
@@ -330,14 +331,6 @@
 #if USE(LIBWEBRTC)
     m_libWebRTCProvider->supportsH265(RuntimeEnabledFeatures::sharedFeatures().webRTCH265CodecEnabled());
 #endif
-
-    m_corsDisablingPatterns.reserveInitialCapacity(pageConfiguration.corsDisablingPatterns.size());
-    for (auto&& pattern : WTFMove(pageConfiguration.corsDisablingPatterns)) {
-        UserContentURLPattern parsedPattern(WTFMove(pattern));
-        if (parsedPattern.isValid())
-            m_corsDisablingPatterns.uncheckedAppend(WTFMove(parsedPattern));
-    }
-    m_corsDisablingPatterns.shrinkToFit();
     
     if (!pageConfiguration.userScriptsShouldWaitUntilNotification)
         m_hasBeenNotifiedToInjectUserScripts = true;

Modified: trunk/Source/WebCore/page/PageConfiguration.h (259771 => 259772)


--- trunk/Source/WebCore/page/PageConfiguration.h	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebCore/page/PageConfiguration.h	2020-04-09 00:42:25 UTC (rev 259772)
@@ -63,6 +63,7 @@
 class SocketProvider;
 class StorageNamespaceProvider;
 class UserContentProvider;
+class UserContentURLPattern;
 class ValidationMessageClient;
 class VisitedLinkStore;
 class WebGLStateTracker;
@@ -125,7 +126,7 @@
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
     RefPtr<DeviceOrientationUpdateProvider> deviceOrientationUpdateProvider;
 #endif
-    Vector<String> corsDisablingPatterns;
+    Vector<UserContentURLPattern> corsDisablingPatterns;
     UniqueRef<MediaRecorderProvider> mediaRecorderProvider;
     bool loadsSubresources { true };
     bool loadsFromNetwork { true };

Modified: trunk/Source/WebCore/page/SecurityOrigin.cpp (259771 => 259772)


--- trunk/Source/WebCore/page/SecurityOrigin.cpp	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebCore/page/SecurityOrigin.cpp	2020-04-09 00:42:25 UTC (rev 259772)
@@ -323,7 +323,7 @@
     if (isSameSchemeHostPort(targetOrigin.get()))
         return true;
 
-    if (SecurityPolicy::isAccessWhiteListed(this, &targetOrigin.get()))
+    if (SecurityPolicy::isAccessWhiteListed(*this, targetOrigin.get(), url))
         return true;
 
     return false;
@@ -382,7 +382,7 @@
         return canRequest(url);
 
     if (LegacySchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(protocol))
-        return equalIgnoringASCIICase(m_data.protocol, protocol) || SecurityPolicy::isAccessToURLWhiteListed(this, url);
+        return equalIgnoringASCIICase(m_data.protocol, protocol) || SecurityPolicy::isAccessWhiteListed(*this, url);
 
     if (!SecurityPolicy::restrictAccessToLocal())
         return true;
@@ -391,7 +391,7 @@
         return true;
 
     if (LegacySchemeRegistry::shouldTreatURLSchemeAsLocal(protocol))
-        return canLoadLocalResources() || SecurityPolicy::isAccessToURLWhiteListed(this, url);
+        return canLoadLocalResources() || SecurityPolicy::isAccessWhiteListed(*this, url);
 
     return true;
 }

Modified: trunk/Source/WebCore/page/SecurityPolicy.cpp (259771 => 259772)


--- trunk/Source/WebCore/page/SecurityPolicy.cpp	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebCore/page/SecurityPolicy.cpp	2020-04-09 00:42:25 UTC (rev 259772)
@@ -31,6 +31,7 @@
 
 #include "OriginAccessEntry.h"
 #include "SecurityOrigin.h"
+#include "UserContentURLPattern.h"
 #include <memory>
 #include <wtf/HashMap.h>
 #include <wtf/MainThread.h>
@@ -53,6 +54,14 @@
     return originAccessMap;
 }
 
+static Lock originAccessPatternLock;
+static Vector<UserContentURLPattern>& originAccessPatterns()
+{
+    ASSERT(originAccessPatternLock.isHeld());
+    static NeverDestroyed<Vector<UserContentURLPattern>> originAccessPatterns;
+    return originAccessPatterns;
+}
+
 bool SecurityPolicy::shouldHideReferrer(const URL& url, const String& referrer)
 {
     bool referrerIsSecureURL = protocolIs(referrer, "https");
@@ -191,22 +200,29 @@
     return localLoadPolicy != SecurityPolicy::AllowLocalLoadsForLocalOnly;
 }
 
-bool SecurityPolicy::isAccessWhiteListed(const SecurityOrigin* activeOrigin, const SecurityOrigin* targetOrigin)
+bool SecurityPolicy::isAccessWhiteListed(const SecurityOrigin& activeOrigin, const SecurityOrigin& targetOrigin, const URL& targetURL)
 {
-    Locker<Lock> locker(originAccessMapLock);
-    if (OriginAccessWhiteList* list = originAccessMap().get(activeOrigin->toString())) {
-        for (auto& entry : *list) {
-            if (entry.matchesOrigin(*targetOrigin))
-                return true;
+    ASSERT(targetOrigin.equal(SecurityOrigin::create(targetURL).ptr()));
+    {
+        Locker<Lock> locker(originAccessMapLock);
+        if (OriginAccessWhiteList* list = originAccessMap().get(activeOrigin.toString())) {
+            for (auto& entry : *list) {
+                if (entry.matchesOrigin(targetOrigin))
+                    return true;
+            }
         }
     }
+    Locker<Lock> locker(originAccessPatternLock);
+    for (const auto& pattern : originAccessPatterns()) {
+        if (pattern.matches(targetURL))
+            return true;
+    }
     return false;
 }
 
-bool SecurityPolicy::isAccessToURLWhiteListed(const SecurityOrigin* activeOrigin, const URL& url)
+bool SecurityPolicy::isAccessWhiteListed(const SecurityOrigin& activeOrigin, const URL& url)
 {
-    Ref<SecurityOrigin> targetOrigin(SecurityOrigin::create(url));
-    return isAccessWhiteListed(activeOrigin, &targetOrigin.get());
+    return isAccessWhiteListed(activeOrigin, SecurityOrigin::create(url).get(), url);
 }
 
 void SecurityPolicy::addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains)
@@ -255,4 +271,10 @@
     originAccessMap().clear();
 }
 
+void SecurityPolicy::allowAccessTo(const UserContentURLPattern& pattern)
+{
+    Locker<Lock> locker(originAccessPatternLock);
+    originAccessPatterns().append(pattern);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/SecurityPolicy.h (259771 => 259772)


--- trunk/Source/WebCore/page/SecurityPolicy.h	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebCore/page/SecurityPolicy.h	2020-04-09 00:42:25 UTC (rev 259772)
@@ -34,6 +34,7 @@
 namespace WebCore {
 
 class SecurityOrigin;
+class UserContentURLPattern;
 
 class SecurityPolicy {
 public:
@@ -66,12 +67,13 @@
     static bool restrictAccessToLocal();
     static bool allowSubstituteDataAccessToLocal();
 
+    WEBCORE_EXPORT static void allowAccessTo(const UserContentURLPattern&);
     WEBCORE_EXPORT static void addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
     WEBCORE_EXPORT static void removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
     WEBCORE_EXPORT static void resetOriginAccessWhitelists();
 
-    static bool isAccessWhiteListed(const SecurityOrigin* activeOrigin, const SecurityOrigin* targetOrigin);
-    static bool isAccessToURLWhiteListed(const SecurityOrigin* activeOrigin, const URL&);
+    static bool isAccessWhiteListed(const SecurityOrigin& activeOrigin, const SecurityOrigin& targetOrigin, const URL& targetURL);
+    static bool isAccessWhiteListed(const SecurityOrigin& activeOrigin, const URL& targetURL);
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (259771 => 259772)


--- trunk/Source/WebKit/ChangeLog	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebKit/ChangeLog	2020-04-09 00:42:25 UTC (rev 259772)
@@ -1,3 +1,14 @@
+2020-04-08  Alex Christensen  <[email protected]>
+
+        _corsDisablingPatterns should allow security policy access to those patterns
+        https://bugs.webkit.org/show_bug.cgi?id=210218
+        <rdar://problem/61395166>
+
+        Reviewed by Timothy Hatcher.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::m_processDisplayName):
+
 2020-04-08  Brent Fulgham  <[email protected]>
 
         REGRESSION(r257758): Launch time performance regression

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (259771 => 259772)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-04-09 00:42:25 UTC (rev 259772)
@@ -220,6 +220,7 @@
 #include <WebCore/RuntimeEnabledFeatures.h>
 #include <WebCore/SWClientConnection.h>
 #include <WebCore/ScriptController.h>
+#include <WebCore/SecurityPolicy.h>
 #include <WebCore/SerializedScriptValue.h>
 #include <WebCore/Settings.h>
 #include <WebCore/ShadowRoot.h>
@@ -228,6 +229,7 @@
 #include <WebCore/SubframeLoader.h>
 #include <WebCore/SubstituteData.h>
 #include <WebCore/TextIterator.h>
+#include <WebCore/UserContentURLPattern.h>
 #include <WebCore/UserGestureIndicator.h>
 #include <WebCore/UserInputBridge.h>
 #include <WebCore/UserScript.h>
@@ -528,7 +530,18 @@
     pageConfiguration.deviceOrientationUpdateProvider = WebDeviceOrientationUpdateProvider::create(*this);
 #endif
 
-    pageConfiguration.corsDisablingPatterns = WTFMove(parameters.corsDisablingPatterns);
+    Vector<UserContentURLPattern> parsedPatterns;
+    parsedPatterns.reserveInitialCapacity(parameters.corsDisablingPatterns.size());
+    for (auto&& pattern : WTFMove(parameters.corsDisablingPatterns)) {
+        UserContentURLPattern parsedPattern(WTFMove(pattern));
+        if (parsedPattern.isValid()) {
+            WebCore::SecurityPolicy::allowAccessTo(parsedPattern);
+            parsedPatterns.uncheckedAppend(WTFMove(parsedPattern));
+        }
+    }
+    parsedPatterns.shrinkToFit();
+    
+    pageConfiguration.corsDisablingPatterns = WTFMove(parsedPatterns);
     pageConfiguration.userScriptsShouldWaitUntilNotification = parameters.userScriptsShouldWaitUntilNotification;
     pageConfiguration.loadsSubresources = parameters.loadsSubresources;
     pageConfiguration.loadsFromNetwork = parameters.loadsFromNetwork;

Modified: trunk/Tools/ChangeLog (259771 => 259772)


--- trunk/Tools/ChangeLog	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Tools/ChangeLog	2020-04-09 00:42:25 UTC (rev 259772)
@@ -1,5 +1,15 @@
 2020-04-08  Alex Christensen  <[email protected]>
 
+        _corsDisablingPatterns should allow security policy access to those patterns
+        https://bugs.webkit.org/show_bug.cgi?id=210218
+        <rdar://problem/61395166>
+
+        Reviewed by Timothy Hatcher.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
+
+2020-04-08  Alex Christensen  <[email protected]>
+
         WKWebViews should behave as if they had loaded something after restoring session state
         https://bugs.webkit.org/show_bug.cgi?id=210097
         <rdar://problem/58778490>

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


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2020-04-09 00:41:18 UTC (rev 259771)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm	2020-04-09 00:42:25 UTC (rev 259772)
@@ -1004,6 +1004,77 @@
     EXPECT_FALSE(loadFail);
 }
 
+TEST(URLSchemeHandler, DisableCORSCanvas)
+{
+    bool corssuccess = false;
+    bool corsfailure = false;
+    bool done = false;
+
+    auto handler = adoptNS([TestURLSchemeHandler new]);
+
+    WKWebViewConfiguration *configuration = [[[WKWebViewConfiguration alloc] init] autorelease];
+    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"cors"];
+
+    [handler setStartURLSchemeTaskHandler:[&](WKWebView *, id<WKURLSchemeTask> task) {
+        NSData *response = nil;
+        NSString *mimeType = nil;
+        if ([task.request.URL.path isEqualToString:@"/main.html"]) {
+            mimeType = @"text/html";
+            response = [@"<canvas id='canvas'></canvas><img src='' _onload_='imageloaded()' id='img'></img><script>"
+                "function imageloaded() {"
+                    "let canvas = document.getElementById('canvas');"
+                    "let context = canvas.getContext('2d');"
+                    "let img = document.getElementById('img');"
+                    "context.drawImage(img, 0, 0);"
+                    "try {"
+                        "let dataURL = canvas.toDataURL('image/png', 1);"
+                        "fetch('corssuccess');"
+                    "} catch(err) {"
+                        "fetch('corsfailure');"
+                    "}"
+                "}"
+            "</script>" dataUsingEncoding:NSUTF8StringEncoding];
+        } else if ([task.request.URL.path isEqualToString:@"/corssuccess"]) {
+            corssuccess = true;
+            done = true;
+        } else if ([task.request.URL.path isEqualToString:@"/corsfailure"]) {
+            corsfailure = true;
+            done = true;
+        } else if ([task.request.URL.path isEqualToString:@"/image.png"]) {
+            mimeType = @"image/png";
+            response = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"400x400-green" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]];
+        } else
+            ASSERT_NOT_REACHED();
+
+        if (response) {
+            [task didReceiveResponse:[[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:response.length textEncodingName:nil] autorelease]];
+            [task didReceiveData:response];
+            [task didFinish];
+        }
+    }];
+
+    {
+        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
+        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"cors://host1/main.html"]]];
+        TestWebKitAPI::Util::run(&done);
+    }
+    EXPECT_FALSE(corssuccess);
+    EXPECT_TRUE(corsfailure);
+
+    corssuccess = false;
+    corsfailure = false;
+    done = false;
+
+    configuration._corsDisablingPatterns = @[@"*://*/*"];
+    {
+        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
+        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"cors://host1/main.html"]]];
+        TestWebKitAPI::Util::run(&done);
+    }
+    EXPECT_TRUE(corssuccess);
+    EXPECT_FALSE(corsfailure);
+}
+
 TEST(URLSchemeHandler, LoadsFromNetwork)
 {
     TestWebKitAPI::HTTPServer server({
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to