Changeset 253978 in webkit


Ignore:
Timestamp:
Jan 2, 2020, 1:14:02 PM (5 years ago)
Author:
achristensen@apple.com
Message:

Add SPI to disable CORS on requests to URLs matching a pattern
https://bugs.webkit.org/show_bug.cgi?id=205534
<rdar://problem/58011337>

Reviewed by Chris Dumez.

Source/WebCore:

This should allow us to remove the layering violation in LegacySchemeRegistry::isUserExtensionScheme
and fix the bug in the radar. The SPI is exercised by a new API test.

  • loader/DocumentThreadableLoader.cpp:

(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):

  • page/Page.cpp:

(WebCore::m_deviceOrientationUpdateProvider):
(WebCore::Page::shouldDisableCorsForRequestTo const):

  • page/Page.h:
  • page/PageConfiguration.h:
  • platform/LegacySchemeRegistry.cpp:

(WebCore::LegacySchemeRegistry::isUserExtensionScheme):

Source/WebKit:

  • Shared/WebPageCreationParameters.cpp:

(WebKit::WebPageCreationParameters::encode const):
(WebKit::WebPageCreationParameters::decode):

  • Shared/WebPageCreationParameters.h:
  • UIProcess/API/APIPageConfiguration.cpp:

(API::PageConfiguration::copy const):
(API::PageConfiguration::PageConfiguration): Deleted.
(API::PageConfiguration::~PageConfiguration): Deleted.

  • UIProcess/API/APIPageConfiguration.h:

(API::PageConfiguration::corsDisablingPatterns const):
(API::PageConfiguration::setCORSDisablingPatterns):

  • UIProcess/API/Cocoa/WKWebViewConfiguration.mm:

(-[WKWebViewConfiguration _corsDisablingPatterns]):
(-[WKWebViewConfiguration _setCORSDisablingPatterns:]):

  • UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
  • UIProcess/WebPageProxy.cpp:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::m_overriddenMediaType):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r253977 r253978  
     12020-01-02  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add SPI to disable CORS on requests to URLs matching a pattern
     4        https://bugs.webkit.org/show_bug.cgi?id=205534
     5        <rdar://problem/58011337>
     6
     7        Reviewed by Chris Dumez.
     8
     9        This should allow us to remove the layering violation in LegacySchemeRegistry::isUserExtensionScheme
     10        and fix the bug in the radar.  The SPI is exercised by a new API test.
     11
     12        * loader/DocumentThreadableLoader.cpp:
     13        (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
     14        * page/Page.cpp:
     15        (WebCore::m_deviceOrientationUpdateProvider):
     16        (WebCore::Page::shouldDisableCorsForRequestTo const):
     17        * page/Page.h:
     18        * page/PageConfiguration.h:
     19        * platform/LegacySchemeRegistry.cpp:
     20        (WebCore::LegacySchemeRegistry::isUserExtensionScheme):
     21
    1222020-01-02  Zalan Bujtas  <zalan@apple.com>
    223
  • trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp

    r253213 r253978  
    154154        m_options.httpHeadersToKeep = httpHeadersToKeepFromCleaning(request.httpHeaderFields());
    155155
    156     if (document.isRunningUserScripts() && LegacySchemeRegistry::isUserExtensionScheme(request.url().protocol().toStringWithoutCopying())) {
     156    bool shouldDisableCORS = document.isRunningUserScripts() && LegacySchemeRegistry::isUserExtensionScheme(request.url().protocol().toStringWithoutCopying());
     157    if (auto* page = document.page())
     158        shouldDisableCORS |= page->shouldDisableCorsForRequestTo(request.url());
     159
     160    if (shouldDisableCORS) {
    157161        m_options.mode = FetchOptions::Mode::NoCors;
    158162        m_options.filteringPolicy = ResponseFilteringPolicy::Disable;
  • trunk/Source/WebCore/page/Page.cpp

    r253923 r253978  
    120120#include "TextResourceDecoder.h"
    121121#include "UserContentProvider.h"
     122#include "UserContentURLPattern.h"
    122123#include "UserInputBridge.h"
    123124#include "ValidationMessageClient.h"
     
    328329    m_libWebRTCProvider->supportsVP8(RuntimeEnabledFeatures::sharedFeatures().webRTCVP8CodecEnabled());
    329330#endif
     331
     332    m_corsDisablingPatterns.reserveInitialCapacity(pageConfiguration.corsDisablingPatterns.size());
     333    for (auto&& pattern : WTFMove(pageConfiguration.corsDisablingPatterns)) {
     334        UserContentURLPattern parsedPattern(WTFMove(pattern));
     335        if (parsedPattern.isValid())
     336            m_corsDisablingPatterns.uncheckedAppend(WTFMove(parsedPattern));
     337    }
     338    m_corsDisablingPatterns.shrinkToFit();
    330339}
    331340
     
    29993008#endif
    30003009
     3010bool Page::shouldDisableCorsForRequestTo(const URL& url) const
     3011{
     3012    return WTF::anyOf(m_corsDisablingPatterns, [&] (const auto& pattern) {
     3013        return pattern.matches(url);
     3014    });
     3015}
     3016
    30013017} // namespace WebCore
  • trunk/Source/WebCore/page/Page.h

    r253923 r253978  
    139139class StorageNamespaceProvider;
    140140class UserContentProvider;
     141class UserContentURLPattern;
    141142class UserInputBridge;
    142143class ValidationMessageClient;
     
    713714    void forEachDocument(const WTF::Function<void(Document&)>&) const;
    714715    void forEachMediaElement(const WTF::Function<void(HTMLMediaElement&)>&);
     716
     717    bool shouldDisableCorsForRequestTo(const URL&) const;
    715718
    716719private:
     
    987990    bool m_mediaBufferingIsSuspended { false };
    988991    bool m_inUpdateRendering { false };
     992    Vector<UserContentURLPattern> m_corsDisablingPatterns;
    989993};
    990994
  • trunk/Source/WebCore/page/PageConfiguration.h

    r253231 r253978  
    123123    RefPtr<DeviceOrientationUpdateProvider> deviceOrientationUpdateProvider;
    124124#endif
     125    Vector<String> corsDisablingPatterns;
    125126};
    126127
  • trunk/Source/WebCore/platform/LegacySchemeRegistry.cpp

    r251659 r253978  
    534534bool LegacySchemeRegistry::isUserExtensionScheme(const String& scheme)
    535535{
     536    // FIXME: Remove this once Safari has adopted WKWebViewConfiguration._corsDisablingPatterns
    536537#if PLATFORM(MAC)
    537538    if (scheme == "safari-extension")
  • trunk/Source/WebKit/ChangeLog

    r253975 r253978  
     12020-01-02  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add SPI to disable CORS on requests to URLs matching a pattern
     4        https://bugs.webkit.org/show_bug.cgi?id=205534
     5        <rdar://problem/58011337>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * Shared/WebPageCreationParameters.cpp:
     10        (WebKit::WebPageCreationParameters::encode const):
     11        (WebKit::WebPageCreationParameters::decode):
     12        * Shared/WebPageCreationParameters.h:
     13        * UIProcess/API/APIPageConfiguration.cpp:
     14        (API::PageConfiguration::copy const):
     15        (API::PageConfiguration::PageConfiguration): Deleted.
     16        (API::PageConfiguration::~PageConfiguration): Deleted.
     17        * UIProcess/API/APIPageConfiguration.h:
     18        (API::PageConfiguration::corsDisablingPatterns const):
     19        (API::PageConfiguration::setCORSDisablingPatterns):
     20        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
     21        (-[WKWebViewConfiguration _corsDisablingPatterns]):
     22        (-[WKWebViewConfiguration _setCORSDisablingPatterns:]):
     23        * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
     24        * UIProcess/WebPageProxy.cpp:
     25        * WebProcess/WebPage/WebPage.cpp:
     26        (WebKit::m_overriddenMediaType):
     27
    1282020-01-02  Sam Weinig  <weinig@apple.com>
    229
  • trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp

    r252459 r253978  
    131131    encoder << oldPageID;
    132132    encoder << overriddenMediaType;
     133    encoder << corsDisablingPatterns;
    133134}
    134135
     
    398399        return WTF::nullopt;
    399400
     401    Optional<Vector<String>> corsDisablingPatterns;
     402    decoder >> corsDisablingPatterns;
     403    if (!corsDisablingPatterns)
     404        return WTF::nullopt;
     405    parameters.corsDisablingPatterns = WTFMove(*corsDisablingPatterns);
     406
    400407    return parameters;
    401408}
  • trunk/Source/WebKit/Shared/WebPageCreationParameters.h

    r252459 r253978  
    203203
    204204    String overriddenMediaType;
     205    Vector<String> corsDisablingPatterns;
    205206};
    206207
  • trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp

    r250169 r253978  
    4141
    4242namespace API {
    43 using namespace WebCore;
    4443using namespace WebKit;
    4544
     
    4948}
    5049
    51 PageConfiguration::PageConfiguration()
    52 {
    53 }
    54 
    55 PageConfiguration::~PageConfiguration()
    56 {
    57 }
     50PageConfiguration::PageConfiguration() = default;
     51PageConfiguration::~PageConfiguration() = default;
    5852
    5953Ref<PageConfiguration> PageConfiguration::copy() const
     
    8680    for (auto& pair : this->m_urlSchemeHandlers)
    8781        copy->m_urlSchemeHandlers.set(pair.key, pair.value.copyRef());
     82    copy->m_corsDisablingPatterns = this->m_corsDisablingPatterns;
    8883
    8984    return copy;
     
    141136}
    142137
    143 
    144138VisitedLinkStore* PageConfiguration::visitedLinkStore()
    145139{
  • trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h

    r250287 r253978  
    3030#include <wtf/Forward.h>
    3131#include <wtf/GetPtr.h>
     32#include <wtf/HashSet.h>
    3233
    3334#if PLATFORM(IOS_FAMILY)
     
    135136    const HashMap<WTF::String, Ref<WebKit::WebURLSchemeHandler>>& urlSchemeHandlers() { return m_urlSchemeHandlers; }
    136137
     138    const Vector<WTF::String>& corsDisablingPatterns() const { return m_corsDisablingPatterns; }
     139    void setCORSDisablingPatterns(Vector<WTF::String>&& patterns) { m_corsDisablingPatterns = WTFMove(patterns); }
     140
    137141private:
    138142
     
    171175
    172176    HashMap<WTF::String, Ref<WebKit::WebURLSchemeHandler>> m_urlSchemeHandlers;
     177    Vector<WTF::String> m_corsDisablingPatterns;
    173178};
    174179
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm

    r252354 r253978  
    884884}
    885885
     886- (NSArray<NSString *> *)_corsDisablingPatterns
     887{
     888    auto& vector = _pageConfiguration->corsDisablingPatterns();
     889    NSMutableArray *array = [NSMutableArray arrayWithCapacity:vector.size()];
     890    for (auto& pattern : vector)
     891        [array addObject:pattern];
     892    return array;
     893}
     894
     895- (void)_setCORSDisablingPatterns:(NSArray<NSString *> *)patterns
     896{
     897    Vector<String> vector;
     898    vector.reserveInitialCapacity(patterns.count);
     899    for (NSString *pattern in patterns)
     900        vector.uncheckedAppend(pattern);
     901    _pageConfiguration->setCORSDisablingPatterns(WTFMove(vector));
     902}
     903
    886904- (BOOL)_drawsBackground
    887905{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h

    r252354 r253978  
    7878
    7979@property (nonatomic, readonly) WKWebsiteDataStore *_websiteDataStoreIfExists WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     80@property (nonatomic, copy, setter=_setCORSDisablingPatterns:) NSArray<NSString *> *_corsDisablingPatterns WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    8081
    8182#if TARGET_OS_IPHONE
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r253950 r253978  
    75477547
    75487548    parameters.overriddenMediaType = m_overriddenMediaType;
     7549    parameters.corsDisablingPatterns = m_configuration->corsDisablingPatterns();
    75497550
    75507551    process.addWebUserContentControllerProxy(m_userContentController, parameters);
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r253950 r253978  
    517517#endif
    518518
     519    pageConfiguration.corsDisablingPatterns = WTFMove(parameters.corsDisablingPatterns);
     520
    519521    m_page = makeUnique<Page>(WTFMove(pageConfiguration));
    520522
  • trunk/Tools/ChangeLog

    r253975 r253978  
     12020-01-02  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add SPI to disable CORS on requests to URLs matching a pattern
     4        https://bugs.webkit.org/show_bug.cgi?id=205534
     5        <rdar://problem/58011337>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
     10
    1112020-01-02  Sam Weinig  <weinig@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm

    r253501 r253978  
    2626#import "config.h"
    2727
     28#import "HTTPServer.h"
    2829#import "PlatformUtilities.h"
    2930#import "Test.h"
     
    804805    EXPECT_FALSE(corsfailure);
    805806}
     807
     808#if HAVE(NETWORK_FRAMEWORK)
     809
     810TEST(URLSchemeHandler, DisableCORS)
     811{
     812    TestWebKitAPI::HTTPServer server({
     813        { "/subresource", { "subresourcecontent" } }
     814    });
     815
     816    bool corssuccess = false;
     817    bool corsfailure = false;
     818    bool done = false;
     819
     820    auto handler = adoptNS([[TestURLSchemeHandler alloc] init]);
     821
     822    WKWebViewConfiguration *configuration = [[[WKWebViewConfiguration alloc] init] autorelease];
     823    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"cors"];
     824
     825    [handler setStartURLSchemeTaskHandler:[&](WKWebView *, id<WKURLSchemeTask> task) {
     826        if ([task.request.URL.path isEqualToString:@"/main.html"]) {
     827            NSData *data = [[NSString stringWithFormat:@"<script>fetch('http://127.0.0.1:%d/subresource').then(function(){fetch('/corssuccess')}).catch(function(){fetch('/corsfailure')})</script>", server.port()] dataUsingEncoding:NSUTF8StringEncoding];
     828            [task didReceiveResponse:[[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil] autorelease]];
     829            [task didReceiveData:data];
     830            [task didFinish];
     831        } else if ([task.request.URL.path isEqualToString:@"/corssuccess"]) {
     832            corssuccess = true;
     833            done = true;
     834        } else if ([task.request.URL.path isEqualToString:@"/corsfailure"]) {
     835            corsfailure = true;
     836            done = true;
     837        } else
     838            ASSERT_NOT_REACHED();
     839    }];
     840   
     841    {
     842        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
     843        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"cors://host1/main.html"]]];
     844        TestWebKitAPI::Util::run(&done);
     845    }
     846    EXPECT_FALSE(corssuccess);
     847    EXPECT_TRUE(corsfailure);
     848   
     849    corssuccess = false;
     850    corsfailure = false;
     851    done = false;
     852
     853    configuration._corsDisablingPatterns = @[@"http://*/*"];
     854    {
     855        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
     856        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"cors://host1/main.html"]]];
     857        TestWebKitAPI::Util::run(&done);
     858    }
     859    EXPECT_TRUE(corssuccess);
     860    EXPECT_FALSE(corsfailure);
     861}
     862
     863#endif // HAVE(NETWORK_FRAMEWORK)
Note: See TracChangeset for help on using the changeset viewer.