Changeset 206203 in webkit


Ignore:
Timestamp:
Sep 21, 2016 1:43:23 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

Refactor CachedResourceLoader::canRequest
https://bugs.webkit.org/show_bug.cgi?id=162144

Patch by Youenn Fablet <youenn@apple.com> on 2016-09-21
Reviewed by Darin Adler.

Covered by existing tests.

Simplifying CachedResourceLoader::canRequest by doing:

  • CSP checks in another method
  • Removing Same-Origin type-specific checks by setting FetchOptions::Mode appropriately in resource loader clients
  • Moving script specific check in ScriptElement

Note that the last check may affect the loading behavior in the case scripts are enabled when starting the load
of a script, but gets disabled before receiving a redirection for the script load.

  • dom/ProcessingInstruction.cpp:

(WebCore::ProcessingInstruction::checkStyleSheet): Setting XSLT stylesheet fetch mode to SameOrigin.

  • dom/ScriptElement.cpp:

(WebCore::ScriptElement::requestScriptWithCache): Returning early if scripts are disabled.

  • loader/CrossOriginPreflightChecker.cpp:

(WebCore::CrossOriginPreflightChecker::startPreflight): Bypassing CSP checks.

  • loader/DocumentLoader.cpp:

(WebCore::DocumentLoader::startLoadingMainResource): Bypassing CSP checks as CachedResourceLoader was not
checking them for MainResource.

  • loader/DocumentThreadableLoader.cpp:

(WebCore::DocumentThreadableLoader::loadRequest): Ditto.

  • loader/LinkLoader.cpp:

(WebCore::LinkLoader::preloadIfNeeded): Using new CachedResourceRequest constructor to enable moving the ResourceRequest.
(WebCore::LinkLoader::loadLink): Skipping CSP checks for link prefetch/subresources as CachedResourceLoader was
not checking them for Link Prefetch and Subresource types.

  • loader/cache/CachedResourceLoader.cpp:

(WebCore::CachedResourceLoader::allowedByContentSecurityPolicy): Helper routine to check for CSP.
(WebCore::CachedResourceLoader::canRequest): Making use of introduced helper routine.
Simplified same origin check as all requests should have their options set.

  • loader/cache/CachedResourceLoader.h:
  • loader/cache/CachedResourceRequest.cpp:

(WebCore::CachedResourceRequest::CachedResourceRequest): More efficient constructor.

  • loader/cache/CachedResourceRequest.h:
  • loader/cache/CachedSVGDocumentReference.cpp:

(WebCore::CachedSVGDocumentReference::load): Setting fetch mode to SameOrigin.

  • svg/SVGUseElement.cpp:

(WebCore::SVGUseElement::updateExternalDocument): Ditto.

  • xml/XSLImportRule.cpp:

(WebCore::XSLImportRule::loadSheet): Ditto.

Location:
trunk/Source/WebCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r206202 r206203  
     12016-09-21  Youenn Fablet  <youenn@apple.com>
     2
     3        Refactor CachedResourceLoader::canRequest
     4        https://bugs.webkit.org/show_bug.cgi?id=162144
     5
     6        Reviewed by Darin Adler.
     7
     8        Covered by existing tests.
     9
     10        Simplifying CachedResourceLoader::canRequest by doing:
     11        - CSP checks in another method
     12        - Removing Same-Origin type-specific checks by setting FetchOptions::Mode appropriately in resource loader clients
     13        - Moving script specific check in ScriptElement
     14
     15        Note that the last check may affect the loading behavior in the case scripts are enabled when starting the load
     16        of a script, but gets disabled before receiving a redirection for the script load.
     17
     18        * dom/ProcessingInstruction.cpp:
     19        (WebCore::ProcessingInstruction::checkStyleSheet): Setting XSLT stylesheet fetch mode to SameOrigin.
     20        * dom/ScriptElement.cpp:
     21        (WebCore::ScriptElement::requestScriptWithCache): Returning early if scripts are disabled.
     22        * loader/CrossOriginPreflightChecker.cpp:
     23        (WebCore::CrossOriginPreflightChecker::startPreflight): Bypassing CSP checks.
     24        * loader/DocumentLoader.cpp:
     25        (WebCore::DocumentLoader::startLoadingMainResource): Bypassing CSP checks as CachedResourceLoader was not
     26        checking them for MainResource.
     27        * loader/DocumentThreadableLoader.cpp:
     28        (WebCore::DocumentThreadableLoader::loadRequest): Ditto.
     29        * loader/LinkLoader.cpp:
     30        (WebCore::LinkLoader::preloadIfNeeded): Using new CachedResourceRequest constructor to enable moving the ResourceRequest.
     31        (WebCore::LinkLoader::loadLink): Skipping CSP checks for link prefetch/subresources as CachedResourceLoader was
     32        not checking them for Link Prefetch and Subresource types.
     33        * loader/cache/CachedResourceLoader.cpp:
     34        (WebCore::CachedResourceLoader::allowedByContentSecurityPolicy): Helper routine to check for CSP.
     35        (WebCore::CachedResourceLoader::canRequest): Making use of introduced helper routine.
     36        Simplified same origin check as all requests should have their options set.
     37        * loader/cache/CachedResourceLoader.h:
     38        * loader/cache/CachedResourceRequest.cpp:
     39        (WebCore::CachedResourceRequest::CachedResourceRequest): More efficient constructor.
     40        * loader/cache/CachedResourceRequest.h:
     41        * loader/cache/CachedSVGDocumentReference.cpp:
     42        (WebCore::CachedSVGDocumentReference::load): Setting fetch mode to SameOrigin.
     43        * svg/SVGUseElement.cpp:
     44        (WebCore::SVGUseElement::updateExternalDocument): Ditto.
     45        * xml/XSLImportRule.cpp:
     46        (WebCore::XSLImportRule::loadSheet): Ditto.
     47
    1482016-09-21  Miguel Gomez  <magomez@igalia.com>
    249
  • trunk/Source/WebCore/dom/ProcessingInstruction.cpp

    r206016 r206203  
    138138            document().authorStyleSheets().addPendingSheet();
    139139
    140             CachedResourceRequest request(ResourceRequest(document().completeURL(href)));
    141 #if ENABLE(XSLT)
    142             if (m_isXSL)
    143                 m_cachedSheet = document().cachedResourceLoader().requestXSLStyleSheet(WTFMove(request));
    144             else
     140#if ENABLE(XSLT)
     141            if (m_isXSL) {
     142                auto options = CachedResourceLoader::defaultCachedResourceOptions();
     143                options.mode = FetchOptions::Mode::SameOrigin;
     144                m_cachedSheet = document().cachedResourceLoader().requestXSLStyleSheet({ResourceRequest(document().completeURL(href)), options});
     145            } else
    145146#endif
    146147            {
     148                CachedResourceRequest request(ResourceRequest(document().completeURL(href)));
    147149                String charset = attrs.get("charset");
    148150                if (charset.isEmpty())
  • trunk/Source/WebCore/dom/ScriptElement.cpp

    r206016 r206203  
    282282CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCache(const URL& sourceURL, const String& nonceAttribute)
    283283{
    284     bool hasKnownNonce = m_element.document().contentSecurityPolicy()->allowScriptWithNonce(nonceAttribute, m_element.isInUserAgentShadowTree());
     284    Document& document = m_element.document();
     285    auto* settings = document.settings();
     286    if (settings && !settings->isScriptEnabled())
     287        return nullptr;
     288
     289    ASSERT(document.contentSecurityPolicy());
     290    bool hasKnownNonce = document.contentSecurityPolicy()->allowScriptWithNonce(nonceAttribute, m_element.isInUserAgentShadowTree());
    285291    ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
    286292    options.contentSecurityPolicyImposition = hasKnownNonce ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck;
    287293
    288294    CachedResourceRequest request(ResourceRequest(sourceURL), options);
    289     request.setAsPotentiallyCrossOrigin(m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), m_element.document());
    290 
    291     m_element.document().contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(request.mutableResourceRequest(), ContentSecurityPolicy::InsecureRequestType::Load);
     295    request.setAsPotentiallyCrossOrigin(m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), document);
     296
     297    document.contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(request.mutableResourceRequest(), ContentSecurityPolicy::InsecureRequestType::Load);
    292298
    293299    request.setCharset(scriptCharset());
    294300    request.setInitiator(&element());
    295301
    296     return m_element.document().cachedResourceLoader().requestScript(WTFMove(request));
     302    return document.cachedResourceLoader().requestScript(WTFMove(request));
    297303}
    298304
  • trunk/Source/WebCore/loader/CrossOriginPreflightChecker.cpp

    r206016 r206203  
    104104    options.referrerPolicy = m_loader.options().referrerPolicy;
    105105    options.redirect = FetchOptions::Redirect::Manual;
     106    options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck;
    106107
    107108    CachedResourceRequest preflightRequest(createAccessControlPreflightRequest(m_request, m_loader.securityOrigin()), options);
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r206189 r206203  
    15191519    RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Starting load (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
    15201520
    1521     static NeverDestroyed<ResourceLoaderOptions> mainResourceLoadOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, ClientCredentialPolicy::MayAskClientForCredentials, FetchOptions::Credentials::Include, SkipSecurityCheck, FetchOptions::Mode::NoCors, IncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching);
     1521    static NeverDestroyed<ResourceLoaderOptions> mainResourceLoadOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, ClientCredentialPolicy::MayAskClientForCredentials, FetchOptions::Credentials::Include, SkipSecurityCheck, FetchOptions::Mode::NoCors, IncludeCertificateInfo, ContentSecurityPolicyImposition::SkipPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching);
    15221522    m_mainResource = m_cachedResourceLoader->requestMainResource(CachedResourceRequest(ResourceRequest(request), mainResourceLoadOptions));
    15231523
  • trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp

    r206016 r206203  
    364364
    365365    if (m_async) {
    366         ThreadableLoaderOptions options = m_options;
     366        ResourceLoaderOptions options = m_options;
    367367        options.clientCredentialPolicy = m_sameOriginRequest ? ClientCredentialPolicy::MayAskClientForCredentials : ClientCredentialPolicy::CannotAskClientForCredentials;
     368        options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck;
    368369
    369370        CachedResourceRequest newRequest(WTFMove(request), options);
  • trunk/Source/WebCore/loader/LinkLoader.cpp

    r206016 r206203  
    159159    ResourceRequest resourceRequest(document.completeURL(href));
    160160    resourceRequest.setIgnoreForRequestCount(true);
    161     CachedResourceRequest linkRequest(resourceRequest, CachedResource::defaultPriorityForResourceType(type.value()));
     161    CachedResourceRequest linkRequest(WTFMove(resourceRequest), CachedResourceLoader::defaultCachedResourceOptions(), CachedResource::defaultPriorityForResourceType(type.value()));
    162162    linkRequest.setInitiator("link");
    163163
     
    201201            m_cachedLinkResource = nullptr;
    202202        }
    203         m_cachedLinkResource = document.cachedResourceLoader().requestLinkResource(type, CachedResourceRequest(ResourceRequest(document.completeURL(href)), priority));
     203        ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
     204        options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck;
     205        m_cachedLinkResource = document.cachedResourceLoader().requestLinkResource(type, CachedResourceRequest(ResourceRequest(document.completeURL(href)), options, priority));
    204206        if (m_cachedLinkResource)
    205207            m_cachedLinkResource->addClient(this);
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r206189 r206203  
    385385}
    386386
     387bool CachedResourceLoader::allowedByContentSecurityPolicy(CachedResource::Type type, const URL& url, const ResourceLoaderOptions& options, bool didReceiveRedirectResponse)
     388{
     389    if (options.contentSecurityPolicyImposition == ContentSecurityPolicyImposition::SkipPolicyCheck)
     390        return true;
     391
     392    ASSERT(m_document);
     393    ASSERT(m_document->contentSecurityPolicy());
     394
     395    auto redirectResponseReceived = didReceiveRedirectResponse ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
     396
     397    switch (type) {
     398#if ENABLE(XSLT)
     399    case CachedResource::XSLStyleSheet:
     400#endif
     401    case CachedResource::Script:
     402        if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, false, redirectResponseReceived))
     403            return false;
     404        break;
     405    case CachedResource::CSSStyleSheet:
     406        if (!m_document->contentSecurityPolicy()->allowStyleFromSource(url, false, redirectResponseReceived))
     407            return false;
     408        break;
     409    case CachedResource::SVGDocumentResource:
     410    case CachedResource::ImageResource:
     411        if (!m_document->contentSecurityPolicy()->allowImageFromSource(url, false, redirectResponseReceived))
     412            return false;
     413        break;
     414#if ENABLE(SVG_FONTS)
     415    case CachedResource::SVGFontResource:
     416#endif
     417    case CachedResource::FontResource:
     418        if (!m_document->contentSecurityPolicy()->allowFontFromSource(url, false, redirectResponseReceived))
     419            return false;
     420        break;
     421    case CachedResource::MediaResource:
     422#if ENABLE(VIDEO_TRACK)
     423    case CachedResource::TextTrackResource:
     424#endif
     425        if (!m_document->contentSecurityPolicy()->allowMediaFromSource(url, false, redirectResponseReceived))
     426            return false;
     427        break;
     428    case CachedResource::RawResource:
     429        return true;
     430    default:
     431        ASSERT_NOT_REACHED();
     432    }
     433    return true;
     434}
     435
    387436bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL& url, const ResourceLoaderOptions& options, bool forPreload, bool didReceiveRedirectResponse)
    388437{
     
    394443    }
    395444
    396     bool skipContentSecurityPolicyCheck = options.contentSecurityPolicyImposition == ContentSecurityPolicyImposition::SkipPolicyCheck;
    397     ContentSecurityPolicy::RedirectResponseReceived redirectResponseReceived = didReceiveRedirectResponse ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
    398 
    399     // Some types of resources can be loaded only from the same origin. Other types of resources, like Images, Scripts, and CSS, can be loaded from any URL.
    400     // FIXME: We should remove that check and handle it by setting the correct ResourceLoaderOptions::mode.
    401     switch (type) {
    402     case CachedResource::MainResource:
    403     case CachedResource::ImageResource:
    404     case CachedResource::CSSStyleSheet:
    405     case CachedResource::Script:
    406 #if ENABLE(SVG_FONTS)
    407     case CachedResource::SVGFontResource:
    408 #endif
    409     case CachedResource::MediaResource:
    410     case CachedResource::FontResource:
    411     case CachedResource::RawResource:
    412 #if ENABLE(LINK_PREFETCH)
    413     case CachedResource::LinkPrefetch:
    414     case CachedResource::LinkSubresource:
    415 #endif
    416 #if ENABLE(VIDEO_TRACK)
    417     case CachedResource::TextTrackResource:
    418 #endif
    419         if (options.mode == FetchOptions::Mode::SameOrigin && !isSameOriginDataURL(url, options, didReceiveRedirectResponse) &&!m_document->securityOrigin()->canRequest(url)) {
    420             printAccessDeniedMessage(url);
    421             return false;
    422         }
    423         break;
    424     case CachedResource::SVGDocumentResource:
    425 #if ENABLE(XSLT)
    426     case CachedResource::XSLStyleSheet:
    427         if (!m_document->securityOrigin()->canRequest(url)) {
    428             printAccessDeniedMessage(url);
    429             return false;
    430         }
    431 #endif
    432         break;
    433     }
    434 
    435     switch (type) {
    436 #if ENABLE(XSLT)
    437     case CachedResource::XSLStyleSheet:
    438         if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, skipContentSecurityPolicyCheck, redirectResponseReceived))
    439             return false;
    440         break;
    441 #endif
    442     case CachedResource::Script:
    443         if (!m_document->contentSecurityPolicy()->allowScriptFromSource(url, skipContentSecurityPolicyCheck, redirectResponseReceived))
    444             return false;
    445         if (frame() && !frame()->settings().isScriptEnabled())
    446             return false;
    447         break;
    448     case CachedResource::CSSStyleSheet:
    449         if (!m_document->contentSecurityPolicy()->allowStyleFromSource(url, skipContentSecurityPolicyCheck, redirectResponseReceived))
    450             return false;
    451         break;
    452     case CachedResource::SVGDocumentResource:
    453     case CachedResource::ImageResource:
    454         if (!m_document->contentSecurityPolicy()->allowImageFromSource(url, skipContentSecurityPolicyCheck, redirectResponseReceived))
    455             return false;
    456         break;
    457 #if ENABLE(SVG_FONTS)
    458     case CachedResource::SVGFontResource:
    459 #endif
    460     case CachedResource::FontResource: {
    461         if (!m_document->contentSecurityPolicy()->allowFontFromSource(url, skipContentSecurityPolicyCheck, redirectResponseReceived))
    462             return false;
    463         break;
    464     }
    465     case CachedResource::MainResource:
    466     case CachedResource::RawResource:
    467 #if ENABLE(LINK_PREFETCH)
    468     case CachedResource::LinkPrefetch:
    469     case CachedResource::LinkSubresource:
    470 #endif
    471         break;
    472     case CachedResource::MediaResource:
    473 #if ENABLE(VIDEO_TRACK)
    474     case CachedResource::TextTrackResource:
    475 #endif
    476         if (!m_document->contentSecurityPolicy()->allowMediaFromSource(url, skipContentSecurityPolicyCheck, redirectResponseReceived))
    477             return false;
    478         break;
    479     }
     445    // FIXME: Remove same-origin data URL flag since it was removed from fetch spec (see https://github.com/whatwg/fetch/issues/381).
     446    if (options.mode == FetchOptions::Mode::SameOrigin && !isSameOriginDataURL(url, options, didReceiveRedirectResponse) && !m_document->securityOrigin()->canRequest(url)) {
     447        printAccessDeniedMessage(url);
     448        return false;
     449    }
     450
     451    if (!allowedByContentSecurityPolicy(type, url, options, didReceiveRedirectResponse))
     452        return false;
    480453
    481454    // SVG Images have unique security rules that prevent all subresource requests except for data urls.
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.h

    r206189 r206203  
    164164    bool shouldContinueAfterNotifyingLoadedFromMemoryCache(const CachedResourceRequest&, CachedResource*);
    165165    bool checkInsecureContent(CachedResource::Type, const URL&) const;
     166    bool allowedByContentSecurityPolicy(CachedResource::Type, const URL&, const ResourceLoaderOptions&, bool);
    166167
    167168    void performPostLoadActions();
  • trunk/Source/WebCore/loader/cache/CachedResourceRequest.cpp

    r204026 r206203  
    4545}
    4646
    47 CachedResourceRequest::CachedResourceRequest(ResourceRequest&& resourceRequest, const ResourceLoaderOptions& options)
     47CachedResourceRequest::CachedResourceRequest(ResourceRequest&& resourceRequest, const ResourceLoaderOptions& options, Optional<ResourceLoadPriority> priority)
    4848    : m_resourceRequest(WTFMove(resourceRequest))
    4949    , m_options(options)
    50     , m_forPreload(false)
    51     , m_defer(NoDefer)
    52 {
    53 }
    54 
    55 CachedResourceRequest::CachedResourceRequest(const ResourceRequest& resourceRequest, Optional<ResourceLoadPriority> priority)
    56     : m_resourceRequest(resourceRequest)
    57     , m_options(CachedResourceLoader::defaultCachedResourceOptions())
    5850    , m_priority(priority)
    5951    , m_forPreload(false)
    6052    , m_defer(NoDefer)
    61 {
    62 }
    63 
    64 CachedResourceRequest::~CachedResourceRequest()
    6553{
    6654}
  • trunk/Source/WebCore/loader/cache/CachedResourceRequest.h

    r205473 r206203  
    4343
    4444    explicit CachedResourceRequest(const ResourceRequest&, const String& charset = String(), Optional<ResourceLoadPriority> = Nullopt);
    45     CachedResourceRequest(ResourceRequest&&, const ResourceLoaderOptions&);
    46     CachedResourceRequest(const ResourceRequest&, Optional<ResourceLoadPriority>);
    47     ~CachedResourceRequest();
     45    CachedResourceRequest(ResourceRequest&&, const ResourceLoaderOptions&, Optional<ResourceLoadPriority> = Nullopt);
    4846
    4947    ResourceRequest& mutableResourceRequest() { return m_resourceRequest; }
  • trunk/Source/WebCore/loader/cache/CachedSVGDocumentReference.cpp

    r206016 r206203  
    5353        return;
    5454
    55     CachedResourceRequest request(ResourceRequest(loader.document()->completeURL(m_url)), options);
     55    auto fetchOptions = options;
     56    fetchOptions.mode = FetchOptions::Mode::SameOrigin;
     57    CachedResourceRequest request(ResourceRequest(loader.document()->completeURL(m_url)), fetchOptions);
    5658    request.setInitiator(cachedResourceRequestInitiators().css);
    5759    m_document = loader.requestSVGDocument(WTFMove(request));
  • trunk/Source/WebCore/svg/SVGUseElement.cpp

    r206016 r206203  
    571571        ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
    572572        options.contentSecurityPolicyImposition = isInUserAgentShadowTree() ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck;
    573 
     573        options.mode = FetchOptions::Mode::SameOrigin;
    574574        CachedResourceRequest request { ResourceRequest { externalDocumentURL }, options };
    575575        request.setInitiator(this);
  • trunk/Source/WebCore/xml/XSLImportRule.cpp

    r206016 r206203  
    101101    if (m_cachedSheet)
    102102        m_cachedSheet->removeClient(this);
    103     m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet(CachedResourceRequest(ResourceRequest(cachedResourceLoader->document()->completeURL(absHref))));
     103
     104    auto options = CachedResourceLoader::defaultCachedResourceOptions();
     105    options.mode = FetchOptions::Mode::SameOrigin;
     106    m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet({ResourceRequest(cachedResourceLoader->document()->completeURL(absHref)), options});
    104107
    105108    if (m_cachedSheet) {
Note: See TracChangeset for help on using the changeset viewer.