Chromium Code Reviews| Index: Source/core/fetch/CrossOriginAccessControl.cpp |
| diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp |
| index 92dafdf3c2b1fd90666bf3e51d2bb958c8e265ab..221f038e9c5442a2dba2c2f4f684cd57f1fd1f22 100644 |
| --- a/Source/core/fetch/CrossOriginAccessControl.cpp |
| +++ b/Source/core/fetch/CrossOriginAccessControl.cpp |
| @@ -29,6 +29,7 @@ |
| #include "core/fetch/Resource.h" |
| #include "core/fetch/ResourceLoaderOptions.h" |
| +#include "platform/RuntimeEnabledFeatures.h" |
| #include "platform/network/HTTPParsers.h" |
| #include "platform/network/ResourceRequest.h" |
| #include "platform/network/ResourceResponse.h" |
| @@ -104,6 +105,11 @@ static bool isOriginSeparator(UChar ch) |
| return isASCIISpace(ch) || ch == ','; |
| } |
| +static bool experimentalContentSecurityPolicyFeaturesEnabled() |
| +{ |
| + return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled(); |
|
Mike West
2014/10/23 12:59:19
For clarity, I'd suggest adding a RuntimeEnabledFe
jww
2015/03/20 22:50:02
Done.
|
| +} |
| + |
| static bool isInterestingStatusCode(int statusCode) |
| { |
| // Predicate that gates what status codes should be included in |
| @@ -116,6 +122,7 @@ bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential |
| { |
| 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)); |
|
Mike West
2014/10/23 12:59:18
"finer-origin"? Why not "suborigin"?
This is a sp
jww
2015/03/20 22:50:02
I'll leave this for now since it's what I've said
|
| if (!response.httpStatusCode()) { |
| errorDescription = "Received an invalid response. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; |
| @@ -123,29 +130,44 @@ 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) { |
|
Mike West
2014/10/23 12:59:18
This seems wrong: as written, either `a-c-allow-or
jww
2015/03/20 22:50:02
This is on purpose, and I've tried to explain in t
|
| // 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."; |
| - return false; |
| + 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."; |
| } |
| - } 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 != 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."; |
| if (isInterestingStatusCode(response.httpStatusCode())) |
| errorDescription.append(" The response had HTTP status code " + String::number(response.httpStatusCode()) + "."); |
| - } 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.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."; |
|
Mike West
2014/10/23 12:59:19
I'd suggest moving all the occurrences of these er
jww
2015/03/20 22:50:02
Done. It's still a bit ugly, though, so any other
|
| + } |
| } |
| return false; |
| } |