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

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

Issue 149643003: Improve handling of CORS redirects for some resource loads. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Compile fix (struct/class mismatch on fwd decl) Created 6 years, 11 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: Source/core/fetch/CrossOriginAccessControl.cpp
diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp
index d2a87bf2abb80e348a9c74a42f1098733e7c9d46..b72cf173367313f20f8eba496a0b9fab53ef18cd 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,68 @@ 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();
abarth-chromium 2014/02/05 08:20:44 s/Url/URL/
sof 2014/02/05 10:05:42 Alright, I'll follow that convention -- done.
+ 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);
+ RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::create(requestUrl);
+ // 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->isSameSchemeHostPort(requestOrigin.get())) {
abarth-chromium 2014/02/05 08:20:44 we should probably use: originalOrigin->canReques
sof 2014/02/05 10:05:42 I see; we do want to avoid "degenerating" to uniqu
+ 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

Powered by Google App Engine
This is Rietveld 408576698