Index: Source/core/fetch/CrossOriginAccessControl.cpp |
diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp |
index ddcb29c406424386cc69bfafc051b9d6f413c30a..784df5f24c19c0adb36cc038bce67152c07ad86f 100644 |
--- a/Source/core/fetch/CrossOriginAccessControl.cpp |
+++ b/Source/core/fetch/CrossOriginAccessControl.cpp |
@@ -27,6 +27,7 @@ |
#include "config.h" |
#include "core/fetch/CrossOriginAccessControl.h" |
+#include "RuntimeEnabledFeatures.h" |
#include "core/fetch/Resource.h" |
#include "core/fetch/ResourceLoaderOptions.h" |
#include "platform/network/HTTPParsers.h" |
@@ -142,10 +143,19 @@ static bool isOriginSeparator(UChar ch) |
return isASCIISpace(ch) || ch == ','; |
} |
+static bool experimentalContentSecurityPolicyFeaturesEnabled() |
+{ |
+ // TODO (jww): Enable proper messaging here once we figure out how to make |
+ // it work well with the LayoutTests. |
+ // return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled(); |
abarth-chromium
2014/07/31 04:56:47
?
jww
2014/10/21 23:51:06
It seems this works better than I thought, so I'm
|
+ return false; |
+} |
+ |
bool passesAccessControlCheck(const ResourceResponse& response, StoredCredentials includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription) |
{ |
AtomicallyInitializedStatic(AtomicString&, accessControlAllowOrigin = *new AtomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral)); |
AtomicallyInitializedStatic(AtomicString&, accessControlAllowCredentials = *new AtomicString("access-control-allow-credentials", AtomicString::ConstructFromLiteral)); |
+ AtomicallyInitializedStatic(AtomicString&, accessControlAllowFinerOrigin = *new AtomicString("access-control-allow-finer-origin", AtomicString::ConstructFromLiteral)); |
if (!response.httpStatusCode()) { |
errorDescription = "Received an invalid response. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
@@ -153,26 +163,43 @@ bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential |
} |
const AtomicString& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin); |
- if (accessControlOriginString == starAtom) { |
+ const AtomicString& accessControlFinerOriginString = response.httpHeaderField(accessControlAllowFinerOrigin); |
+ if (accessControlOriginString == starAtom || accessControlAllowFinerOrigin == starAtom) { |
// A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent, |
// even with Access-Control-Allow-Credentials set to true. |
if (includeCredentials == DoNotAllowStoredCredentials) |
return true; |
if (response.isHTTP()) { |
- errorDescription = "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ if (!experimentalContentSecurityPolicyFeaturesEnabled()) |
+ errorDescription = "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ else |
+ errorDescription = "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' header when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
return false; |
} |
- } else if (accessControlOriginString != securityOrigin->toAtomicString()) { |
- if (accessControlOriginString.isEmpty()) { |
- errorDescription = "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
- } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound) { |
- errorDescription = "The 'Access-Control-Allow-Origin' header contains multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ } else if (accessControlOriginString != securityOrigin->toAtomicString() && accessControlFinerOriginString != securityOrigin->toRawAtomicString()) { |
+ if (accessControlOriginString.isEmpty() && accessControlFinerOriginString.isEmpty()) { |
+ if (!experimentalContentSecurityPolicyFeaturesEnabled()) |
+ errorDescription = "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ else |
+ errorDescription = "No 'Access-Control-Allow-Origin' or 'Access-Control-Allow-accessControlFinerOriginString' header is present on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound || accessControlFinerOriginString.string().find(isOriginSeparator, 0) != kNotFound) { |
+ if (!experimentalContentSecurityPolicyFeaturesEnabled()) |
+ errorDescription = "The 'Access-Control-Allow-Origin' header contains multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ else |
+ errorDescription = "The 'Access-Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' header contains multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
} else { |
KURL headerOrigin(KURL(), accessControlOriginString); |
- if (!headerOrigin.isValid()) |
+ KURL headerFinerOrigin(KURL(), accessControlFinerOriginString); |
+ if (!headerOrigin.isValid()) { |
errorDescription = "The 'Access-Control-Allow-Origin' header contains the invalid value '" + accessControlOriginString + "'. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
- else |
- errorDescription = "The 'Access-Control-Allow-Origin' header has a value '" + accessControlOriginString + "' that is not equal to the supplied origin. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ } else if (experimentalContentSecurityPolicyFeaturesEnabled() && !headerFinerOrigin.isValid()) { |
+ errorDescription = "The 'Access-Control-Allow-Finer-Origin' header contains the invalid value '" + accessControlOriginString + "'. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ } else { |
+ if (!experimentalContentSecurityPolicyFeaturesEnabled()) |
+ errorDescription = "The 'Access-Control-Allow-Origin' header has a value '" + accessControlOriginString + "' that is not equal to the supplied origin. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ else |
+ errorDescription = "The 'Access-Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' header has a value '" + accessControlOriginString + "' that is not equal to the supplied origin. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
+ } |
} |
return false; |
} |