Changeset 198395 in webkit


Ignore:
Timestamp:
Mar 18, 2016 4:17:09 AM (8 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

crossorigin element resource loading should check HTTP redirection
https://bugs.webkit.org/show_bug.cgi?id=130578

Reviewed by Daniel Bates and Brent Fulgham.

Source/WebCore:

Moved part of DocumentThreadableLoader redirection cross origin control code
into functions in CrossOriginAccessControl.cpp. Added cross origin control for
redirections in SubResourceLoader when policy is set to PotentiallyCrossOriginEnabled
using CrossOriginAccessControl.cpp new functions. Added a new test that checks that
cross-origin redirections are checked against CORS.

Test: http/tests/security/shape-image-cors-redirect.html

  • loader/CrossOriginAccessControl.cpp:

(WebCore::isValidCrossOriginRedirectionURL): Returns true if the redirected URL is a valid URL for cross-origin requests.
(WebCore::cleanRedirectedRequestForAccessControl): Removes all headers added by the network backend that may cause the response CORS validation to fail.

  • loader/CrossOriginAccessControl.h: Added above function prototypes.
  • loader/DocumentThreadableLoader.cpp:

(WebCore::DocumentThreadableLoader::redirectReceived): Used new CORS redirection methods of CrossOriginAccessControl.cpp.

  • loader/SubresourceLoader.cpp:

(WebCore::SubresourceLoader::init): Initialize the SecurityOrigin to be used for loading the resource.
(WebCore::SubresourceLoader::willSendRequest): Added cross-origin redirection response check.
(WebCore::SubresourceLoader::checkCrossOriginAccessControl): Checks CORS and update request if needed. Returns true if control checks passed.

  • loader/SubresourceLoader.h: Added checkCrossOriginAccessControl declaration and m_origin declaration.

LayoutTests:

shape-image-cors-redirect.html checks that cross-origin redirections are checked against CORS.
It also checks that same-origin redirections are not checked against CORS.

  • http/tests/security/resources/redirect-allow-star.php: Added.
  • http/tests/security/shape-image-cors-redirect-expected.html: Added.
  • http/tests/security/shape-image-cors-redirect.html: Added.
Location:
trunk
Files:
11 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r198394 r198395  
     12016-03-18  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        crossorigin element resource loading should check HTTP redirection
     4        https://bugs.webkit.org/show_bug.cgi?id=130578
     5
     6        Reviewed by Daniel Bates and Brent Fulgham.
     7
     8        shape-image-cors-redirect.html checks that cross-origin redirections are checked against CORS.
     9        It also checks that same-origin redirections are not checked against CORS.
     10
     11        * http/tests/security/resources/redirect-allow-star.php: Added.
     12        * http/tests/security/shape-image-cors-redirect-expected.html: Added.
     13        * http/tests/security/shape-image-cors-redirect.html: Added.
     14
    1152016-03-18  Youenn Fablet  <youenn.fablet@crf.canon.fr>
    216
  • trunk/LayoutTests/TestExpectations

    r198394 r198395  
    806806webkit.org/b/52185 fast/css/vertical-align-baseline-rowspan-010.html [ ImageOnlyFailure ]
    807807
     808webkit.org/b/155634 http/tests/security/shape-image-cors-redirect-error-message-logging-1.html [ Pass Failure ]
     809webkit.org/b/155634 http/tests/security/shape-image-cors-redirect-error-message-logging-2.html [ Pass Failure ]
     810webkit.org/b/155634 http/tests/security/shape-image-cors-redirect-error-message-logging-3.html [ Pass Failure ]
     811webkit.org/b/155634 http/tests/security/shape-image-cors-redirect-error-message-logging-4.html [ Pass Failure ]
     812
    808813# Content Security Policy failures
    809814webkit.org/b/85558 http/tests/security/contentSecurityPolicy/1.1
  • trunk/Source/WebCore/ChangeLog

    r198393 r198395  
     12016-03-18  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        crossorigin element resource loading should check HTTP redirection
     4        https://bugs.webkit.org/show_bug.cgi?id=130578
     5
     6        Reviewed by Daniel Bates and Brent Fulgham.
     7
     8        Moved part of DocumentThreadableLoader redirection cross origin control code
     9        into functions in CrossOriginAccessControl.cpp. Added cross origin control for
     10        redirections in SubResourceLoader when policy is set to PotentiallyCrossOriginEnabled
     11        using CrossOriginAccessControl.cpp new functions. Added a new test that checks that
     12        cross-origin redirections are checked against CORS.
     13
     14        Test: http/tests/security/shape-image-cors-redirect.html
     15
     16        * loader/CrossOriginAccessControl.cpp:
     17        (WebCore::isValidCrossOriginRedirectionURL): Returns true if the redirected URL is a valid URL for cross-origin requests.
     18        (WebCore::cleanRedirectedRequestForAccessControl): Removes all headers added by the network backend that may cause the response CORS validation to fail.
     19        * loader/CrossOriginAccessControl.h: Added above function prototypes.
     20        * loader/DocumentThreadableLoader.cpp:
     21        (WebCore::DocumentThreadableLoader::redirectReceived): Used new CORS redirection methods of CrossOriginAccessControl.cpp.
     22        * loader/SubresourceLoader.cpp:
     23        (WebCore::SubresourceLoader::init): Initialize the SecurityOrigin to be used for loading the resource.
     24        (WebCore::SubresourceLoader::willSendRequest): Added cross-origin redirection response check.
     25        (WebCore::SubresourceLoader::checkCrossOriginAccessControl): Checks CORS and update request if needed. Returns true if control checks passed.
     26        * loader/SubresourceLoader.h: Added checkCrossOriginAccessControl declaration and m_origin declaration.
     27
    1282016-03-18  Darin Adler  <darin@apple.com>
    229
  • trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp

    r196080 r198395  
    3232#include "ResourceRequest.h"
    3333#include "ResourceResponse.h"
     34#include "SchemeRegistry.h"
    3435#include "SecurityOrigin.h"
    3536#include <mutex>
     
    134135}
    135136
     137bool isValidCrossOriginRedirectionURL(const URL& redirectURL)
     138{
     139    return SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(redirectURL.protocol())
     140        && redirectURL.user().isEmpty()
     141        && redirectURL.pass().isEmpty();
     142}
     143
     144void cleanRedirectedRequestForAccessControl(ResourceRequest& request)
     145{
     146    // Remove headers that may have been added by the network layer that cause access control to fail.
     147    request.clearHTTPContentType();
     148    request.clearHTTPReferrer();
     149    request.clearHTTPOrigin();
     150    request.clearHTTPUserAgent();
     151    request.clearHTTPAccept();
     152    request.clearHTTPAcceptEncoding();
     153}
     154
    136155bool passesAccessControlCheck(const ResourceResponse& response, StoredCredentials includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription)
    137156{
  • trunk/Source/WebCore/loader/CrossOriginAccessControl.h

    r195928 r198395  
    4242class ResourceResponse;
    4343class SecurityOrigin;
     44class URL;
    4445
    4546bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
     
    5152ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin*);
    5253
     54bool isValidCrossOriginRedirectionURL(const URL&);
     55void cleanRedirectedRequestForAccessControl(ResourceRequest&);
     56
    5357bool passesAccessControlCheck(const ResourceResponse&, StoredCredentials, SecurityOrigin*, String& errorDescription);
    5458void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet&);
  • trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp

    r197551 r198395  
    209209        if (m_simpleRequest) {
    210210            String accessControlErrorDescription;
    211             allowRedirect = SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())
    212                             && request.url().user().isEmpty()
    213                             && request.url().pass().isEmpty()
     211            allowRedirect = isValidCrossOriginRedirectionURL(request.url())
    214212                            && (m_sameOriginRequest || passesAccessControlCheck(redirectResponse, m_options.allowCredentials(), securityOrigin(), accessControlErrorDescription));
    215213        }
     
    234232                m_options.setAllowCredentials(DoNotAllowStoredCredentials);
    235233
    236             // Remove any headers that may have been added by the network layer that cause access control to fail.
    237             request.clearHTTPContentType();
    238             request.clearHTTPReferrer();
    239             request.clearHTTPOrigin();
    240             request.clearHTTPUserAgent();
    241             request.clearHTTPAccept();
    242             request.clearHTTPAcceptEncoding();
     234            cleanRedirectedRequestForAccessControl(request);
     235
    243236            makeCrossOriginAccessRequest(request);
    244237            return;
  • trunk/Source/WebCore/loader/SubresourceLoader.cpp

    r198292 r198395  
    3131
    3232#include "CachedResourceLoader.h"
     33#include "CrossOriginAccessControl.h"
    3334#include "DiagnosticLoggingClient.h"
    3435#include "DiagnosticLoggingKeys.h"
     
    147148    m_state = Initialized;
    148149    m_documentLoader->addSubresourceLoader(this);
     150
     151    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155633.
     152    // SubresourceLoader could use the document origin as a default and set PotentiallyCrossOriginEnabled requests accordingly.
     153    // This would simplify resource loader users as they would only need to set the policy to PotentiallyCrossOriginEnabled.
     154    if (options().requestOriginPolicy() == PotentiallyCrossOriginEnabled)
     155        m_origin = SecurityOrigin::createFromString(request.httpOrigin());
     156
    149157    return true;
    150158}
     
    183191            return;
    184192        }
     193
     194        if (options().requestOriginPolicy() == PotentiallyCrossOriginEnabled && !checkCrossOriginAccessControl(request(), redirectResponse, newRequest)) {
     195            cancel();
     196            return;
     197        }
     198
    185199        if (m_resource->isImage() && m_documentLoader->cachedResourceLoader().shouldDeferImageLoad(newRequest.url())) {
    186200            cancel();
     
    371385}
    372386
     387bool SubresourceLoader::checkCrossOriginAccessControl(const ResourceRequest& previousRequest, const ResourceResponse& redirectResponse, ResourceRequest& newRequest)
     388{
     389    if (m_origin->canRequest(newRequest.url()))
     390        return true;
     391
     392    String errorDescription;
     393    bool responsePassesCORS = m_origin->canRequest(previousRequest.url())
     394        || passesAccessControlCheck(redirectResponse, options().allowCredentials(), m_origin.get(), errorDescription);
     395    if (!responsePassesCORS || !isValidCrossOriginRedirectionURL(newRequest.url())) {
     396        if (m_frame && m_frame->document()) {
     397            String errorMessage = "Cross-origin redirection denied by Cross-Origin Resource Sharing policy: " +
     398                (!responsePassesCORS ? errorDescription : "Redirected to either a non-HTTP URL or a URL that contains credentials.");
     399            m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, errorMessage);
     400        }
     401        return false;
     402    }
     403
     404    // If the request URL origin is not the same as the original origin, the request origin should be set to a globally unique identifier.
     405    m_origin = SecurityOrigin::createUnique();
     406    cleanRedirectedRequestForAccessControl(newRequest);
     407    updateRequestForAccessControl(newRequest, m_origin.get(), options().allowCredentials());
     408
     409    return true;
     410}
     411
    373412void SubresourceLoader::didFinishLoading(double finishTime)
    374413{
  • trunk/Source/WebCore/loader/SubresourceLoader.h

    r197563 r198395  
    4141class Document;
    4242class ResourceRequest;
     43class SecurityOrigin;
    4344
    4445class SubresourceLoader final : public ResourceLoader {
     
    9293
    9394    bool checkForHTTPStatusCodeError();
     95    bool checkCrossOriginAccessControl(const ResourceRequest&, const ResourceResponse&, ResourceRequest& newRequest);
    9496
    9597    void didReceiveDataOrBuffer(const char*, int, PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType);
     
    125127    SubresourceLoaderState m_state;
    126128    std::unique_ptr<RequestCountTracker> m_requestCountTracker;
     129    RefPtr<SecurityOrigin> m_origin;
    127130};
    128131
Note: See TracChangeset for help on using the changeset viewer.