Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1542)

Unified Diff: third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp

Issue 2264503002: Clean up SecurityOrigin handling around CrossOriginAccessControl::handleRedirect() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
diff --git a/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp b/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
index 74dd919175f7a509e0e07367683c25ba5a06d0cc..3c70a9865bc370ffd61a479af39e0e8335de2be7 100644
--- a/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
+++ b/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
@@ -56,7 +56,7 @@ bool isOnAccessControlResponseHeaderWhitelist(const String& name)
return allowedCrossOriginResponseHeaders.contains(name);
}
-void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, StoredCredentials allowCredentials)
+void updateRequestForAccessControl(ResourceRequest& request, const SecurityOrigin* securityOrigin, StoredCredentials allowCredentials)
{
request.removeCredentials();
request.setAllowStoredCredentials(allowCredentials == AllowStoredCredentials);
@@ -65,7 +65,7 @@ void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* sec
request.setHTTPOrigin(securityOrigin);
}
-ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, SecurityOrigin* securityOrigin)
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, const SecurityOrigin* securityOrigin)
{
ResourceRequest preflightRequest(request.url());
updateRequestForAccessControl(preflightRequest, securityOrigin, DoNotAllowStoredCredentials);
@@ -124,12 +124,12 @@ static bool isInterestingStatusCode(int statusCode)
return statusCode >= 400;
}
-static String buildAccessControlFailureMessage(const String& detail, SecurityOrigin* securityOrigin)
+static String buildAccessControlFailureMessage(const String& detail, const SecurityOrigin* securityOrigin)
{
return detail + " Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
}
-bool passesAccessControlCheck(const ResourceResponse& response, StoredCredentials includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription, WebURLRequest::RequestContext context)
+bool passesAccessControlCheck(const ResourceResponse& response, StoredCredentials includeCredentials, const SecurityOrigin* securityOrigin, String& errorDescription, WebURLRequest::RequestContext context)
{
DEFINE_THREAD_SAFE_STATIC_LOCAL(AtomicString, allowOriginHeaderName, (new AtomicString("access-control-allow-origin")));
DEFINE_THREAD_SAFE_STATIC_LOCAL(AtomicString, allowCredentialsHeaderName, (new AtomicString("access-control-allow-credentials")));
@@ -272,12 +272,22 @@ void extractCorsExposedHeaderNamesList(const ResourceResponse& response, 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.)
+ // Block non HTTP(S) schemes as specified in the step 4 in
+ // https://fetch.spec.whatwg.org/#http-redirect-fetch. Chromium also allows
+ // the data scheme.
+ //
+ // TODO(tyoshino): This check should be performed regardless of the CORS
+ // flag and request's mode.
if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestURL.protocol())) {
errorDescription = "Redirect location '" + requestURL.getString() + "' has a disallowed scheme for cross-origin requests.";
return false;
}
+ // Block URLs including credentials as specified in the step 9 in
+ // https://fetch.spec.whatwg.org/#http-redirect-fetch.
+ //
+ // TODO(tyoshino): This check should be performed also when request's
+ // origin is not same origin with the redirect destination's origin.
if (!(requestURL.user().isEmpty() && requestURL.pass().isEmpty())) {
errorDescription = "Redirect location '" + requestURL.getString() + "' contains userinfo, which is disallowed for cross-origin requests.";
return false;
@@ -286,45 +296,49 @@ bool CrossOriginAccessControl::isLegalRedirectLocation(const KURL& requestURL, S
return true;
}
-bool CrossOriginAccessControl::handleRedirect(SecurityOrigin* securityOrigin, ResourceRequest& newRequest, const ResourceResponse& redirectResponse, StoredCredentials withCredentials, ResourceLoaderOptions& options, String& errorMessage)
+bool CrossOriginAccessControl::handleRedirect(const SecurityOrigin* securityOrigin, ResourceRequest& newRequest, const ResourceResponse& redirectResponse, StoredCredentials withCredentials, ResourceLoaderOptions& options, String& errorMessage)
{
// http://www.w3.org/TR/cors/#redirect-steps terminology:
- const KURL& originalURL = redirectResponse.url();
+ const KURL& lastURL = redirectResponse.url();
const KURL& newURL = newRequest.url();
- bool redirectCrossOrigin = !securityOrigin->canRequest(newURL);
+ const SecurityOrigin* securityOriginForHeader = securityOrigin;
- // Same-origin request URLs that redirect are allowed without checking access.
- if (!securityOrigin->canRequest(originalURL)) {
+ // TODO(tyoshino): This should be fixed to check not only the last one but
+ // all redirect responses.
+ if (!securityOrigin->canRequest(lastURL)) {
// Follow http://www.w3.org/TR/cors/#redirect-steps
String errorDescription;
- // Steps 3 & 4 - check if scheme and other URL restrictions hold.
if (!isLegalRedirectLocation(newURL, errorDescription)) {
- errorMessage = "Redirect from '" + originalURL.getString() + "' has been blocked by CORS policy: " + errorDescription;
+ errorMessage = "Redirect from '" + lastURL.getString() + "' has been blocked by CORS policy: " + errorDescription;
return false;
}
// Step 5: perform resource sharing access check.
if (!passesAccessControlCheck(redirectResponse, withCredentials, securityOrigin, errorDescription, newRequest.requestContext())) {
- errorMessage = "Redirect from '" + originalURL.getString() + "' has been blocked by CORS policy: " + errorDescription;
+ errorMessage = "Redirect from '" + lastURL.getString() + "' has been blocked by CORS policy: " + errorDescription;
return false;
}
- 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(newURL)) {
+ RefPtr<SecurityOrigin> lastOrigin = SecurityOrigin::create(lastURL);
+ // Set request's origin to a globally unique identifier as specified in
+ // the step 10 in https://fetch.spec.whatwg.org/#http-redirect-fetch.
+ if (!lastOrigin->canRequest(newURL)) {
options.securityOrigin = SecurityOrigin::createUnique();
- securityOrigin = options.securityOrigin.get();
+ securityOriginForHeader = options.securityOrigin.get();
}
}
- if (redirectCrossOrigin) {
- // If now to a different origin, update/set Origin:.
+
+ if (!securityOrigin->canRequest(newURL)) {
newRequest.clearHTTPOrigin();
- newRequest.setHTTPOrigin(securityOrigin);
- // 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.
+ newRequest.setHTTPOrigin(securityOriginForHeader);
+
+ // Unset credentials flag if request's credentials mode is
+ // "same-origin" as request's response tainting becomes "cors".
+ //
+ // This is equivalent to the step 2 in
+ // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
if (options.credentialsRequested == ClientDidNotRequestCredentials)
options.allowCredentials = DoNotAllowStoredCredentials;
}

Powered by Google App Engine
This is Rietveld 408576698