| Index: Source/core/fetch/CrossOriginAccessControl.cpp
|
| diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp
|
| index d2a87bf2abb80e348a9c74a42f1098733e7c9d46..98d2b1a7734902740dc2f692cc42445a52a8299d 100644
|
| --- a/Source/core/fetch/CrossOriginAccessControl.cpp
|
| +++ b/Source/core/fetch/CrossOriginAccessControl.cpp
|
| @@ -27,8 +27,12 @@
|
| #include "config.h"
|
| #include "core/fetch/CrossOriginAccessControl.h"
|
|
|
| +#include "core/fetch/Resource.h"
|
| +#include "core/fetch/ResourceLoaderOptions.h"
|
| #include "platform/network/HTTPParsers.h"
|
| +#include "platform/network/ResourceRequest.h"
|
| #include "platform/network/ResourceResponse.h"
|
| +#include "platform/weborigin/SchemeRegistry.h"
|
| #include "platform/weborigin/SecurityOrigin.h"
|
| #include "wtf/Threading.h"
|
| #include "wtf/text/AtomicString.h"
|
| @@ -203,4 +207,67 @@ void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHea
|
| }
|
| }
|
|
|
| +bool CrossOriginAccessControl::isLegalRedirectLocation(const KURL& requestURL, String& errorDescription)
|
| +{
|
| + // CORS restrictions imposed on Location: URL -- http://www.w3.org/TR/cors/#redirect-steps (steps 2 + 3.)
|
| + if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestURL.protocol())) {
|
| + errorDescription = "The request was redirected to a URL ('" + requestURL.string() + "') which has a disallowed scheme for cross-origin requests.";
|
| + return false;
|
| + }
|
| +
|
| + if (!(requestURL.user().isEmpty() && requestURL.pass().isEmpty())) {
|
| + errorDescription = "The request was redirected to a URL ('" + requestURL.string() + "') containing userinfo, which is disallowed for cross-origin requests.";
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool CrossOriginAccessControl::handleRedirect(Resource* resource, SecurityOrigin* securityOrigin, ResourceRequest& request, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options, String& errorMessage)
|
| +{
|
| + // http://www.w3.org/TR/cors/#redirect-steps terminology:
|
| + const KURL& originalURL = redirectResponse.url();
|
| + const KURL& requestURL = request.url();
|
| +
|
| + bool redirectCrossOrigin = !securityOrigin->canRequest(requestURL);
|
| +
|
| + // Same-origin request URLs that redirect are allowed without checking access.
|
| + if (!securityOrigin->canRequest(originalURL)) {
|
| + // Follow http://www.w3.org/TR/cors/#redirect-steps
|
| + String errorDescription;
|
| +
|
| + // Steps 3 & 4 - check if scheme and other URL restrictions hold.
|
| + bool allowRedirect = isLegalRedirectLocation(requestURL, errorDescription);
|
| + if (allowRedirect) {
|
| + // Step 5: perform resource sharing access check.
|
| + StoredCredentials withCredentials = resource->resourceRequest().allowCookies() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
|
| + allowRedirect = passesAccessControlCheck(redirectResponse, withCredentials, securityOrigin, errorDescription);
|
| + if (allowRedirect) {
|
| + RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(originalURL);
|
| + // Step 6: if the request URL origin is not same origin as the original URL's,
|
| + // set the source origin to a globally unique identifier.
|
| + if (!originalOrigin->canRequest(requestURL)) {
|
| + options.securityOrigin = SecurityOrigin::createUnique();
|
| + securityOrigin = options.securityOrigin.get();
|
| + }
|
| + }
|
| + }
|
| + if (!allowRedirect) {
|
| + const String& originalOrigin = SecurityOrigin::create(originalURL)->toString();
|
| + errorMessage = "Redirect at origin '" + originalOrigin + "' has been blocked from loading by Cross-Origin Resource Sharing policy: " + errorDescription;
|
| + return false;
|
| + }
|
| + }
|
| + if (redirectCrossOrigin) {
|
| + // If now to a different origin, update/set Origin:.
|
| + request.clearHTTPOrigin();
|
| + request.setHTTPOrigin(securityOrigin->toAtomicString());
|
| + // If the user didn't request credentials in the first place, update our
|
| + // state so we neither request them nor expect they must be allowed.
|
| + if (options.credentialsRequested == ClientDidNotRequestCredentials)
|
| + options.allowCredentials = DoNotAllowStoredCredentials;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| } // namespace WebCore
|
|
|