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

Side by Side Diff: Source/core/fetch/CrossOriginAccessControl.cpp

Issue 27073003: CSP Suborigins Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Address abarth's comments Created 6 years, 2 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 11 matching lines...) Expand all
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * 24 *
25 */ 25 */
26 26
27 #include "config.h" 27 #include "config.h"
28 #include "core/fetch/CrossOriginAccessControl.h" 28 #include "core/fetch/CrossOriginAccessControl.h"
29 29
30 #include "core/fetch/Resource.h" 30 #include "core/fetch/Resource.h"
31 #include "core/fetch/ResourceLoaderOptions.h" 31 #include "core/fetch/ResourceLoaderOptions.h"
32 #include "platform/RuntimeEnabledFeatures.h"
32 #include "platform/network/HTTPParsers.h" 33 #include "platform/network/HTTPParsers.h"
33 #include "platform/network/ResourceRequest.h" 34 #include "platform/network/ResourceRequest.h"
34 #include "platform/network/ResourceResponse.h" 35 #include "platform/network/ResourceResponse.h"
35 #include "platform/weborigin/SchemeRegistry.h" 36 #include "platform/weborigin/SchemeRegistry.h"
36 #include "platform/weborigin/SecurityOrigin.h" 37 #include "platform/weborigin/SecurityOrigin.h"
37 #include "wtf/Threading.h" 38 #include "wtf/Threading.h"
38 #include "wtf/text/AtomicString.h" 39 #include "wtf/text/AtomicString.h"
39 #include "wtf/text/StringBuilder.h" 40 #include "wtf/text/StringBuilder.h"
40 41
41 namespace blink { 42 namespace blink {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 98 }
98 99
99 return preflightRequest; 100 return preflightRequest;
100 } 101 }
101 102
102 static bool isOriginSeparator(UChar ch) 103 static bool isOriginSeparator(UChar ch)
103 { 104 {
104 return isASCIISpace(ch) || ch == ','; 105 return isASCIISpace(ch) || ch == ',';
105 } 106 }
106 107
108 static bool experimentalContentSecurityPolicyFeaturesEnabled()
109 {
110 return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnab led();
Mike West 2014/10/23 12:59:19 For clarity, I'd suggest adding a RuntimeEnabledFe
jww 2015/03/20 22:50:02 Done.
111 }
112
107 static bool isInterestingStatusCode(int statusCode) 113 static bool isInterestingStatusCode(int statusCode)
108 { 114 {
109 // Predicate that gates what status codes should be included in 115 // Predicate that gates what status codes should be included in
110 // console error messages for responses containing no access 116 // console error messages for responses containing no access
111 // control headers. 117 // control headers.
112 return statusCode >= 400; 118 return statusCode >= 400;
113 } 119 }
114 120
115 bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential s includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription) 121 bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential s includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription)
116 { 122 {
117 AtomicallyInitializedStatic(AtomicString&, accessControlAllowOrigin = *new A tomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral)); 123 AtomicallyInitializedStatic(AtomicString&, accessControlAllowOrigin = *new A tomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral));
118 AtomicallyInitializedStatic(AtomicString&, accessControlAllowCredentials = * new AtomicString("access-control-allow-credentials", AtomicString::ConstructFrom Literal)); 124 AtomicallyInitializedStatic(AtomicString&, accessControlAllowCredentials = * new AtomicString("access-control-allow-credentials", AtomicString::ConstructFrom Literal));
125 AtomicallyInitializedStatic(AtomicString&, accessControlAllowFinerOrigin = * new AtomicString("access-control-allow-finer-origin", AtomicString::ConstructFro mLiteral));
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
119 126
120 if (!response.httpStatusCode()) { 127 if (!response.httpStatusCode()) {
121 errorDescription = "Received an invalid response. Origin '" + securityOr igin->toString() + "' is therefore not allowed access."; 128 errorDescription = "Received an invalid response. Origin '" + securityOr igin->toString() + "' is therefore not allowed access.";
122 return false; 129 return false;
123 } 130 }
124 131
125 const AtomicString& accessControlOriginString = response.httpHeaderField(acc essControlAllowOrigin); 132 const AtomicString& accessControlOriginString = response.httpHeaderField(acc essControlAllowOrigin);
126 if (accessControlOriginString == starAtom) { 133 const AtomicString& accessControlFinerOriginString = response.httpHeaderFiel d(accessControlAllowFinerOrigin);
134 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
127 // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent, 135 // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
128 // even with Access-Control-Allow-Credentials set to true. 136 // even with Access-Control-Allow-Credentials set to true.
129 if (includeCredentials == DoNotAllowStoredCredentials) 137 if (includeCredentials == DoNotAllowStoredCredentials)
130 return true; 138 return true;
131 if (response.isHTTP()) { 139 if (response.isHTTP()) {
132 errorDescription = "A wildcard '*' cannot be used in the 'Access-Con trol-Allow-Origin' header when the credentials flag is true. Origin '" + securit yOrigin->toString() + "' is therefore not allowed access."; 140 if (!experimentalContentSecurityPolicyFeaturesEnabled())
133 return false; 141 errorDescription = "A wildcard '*' cannot be used in the 'Access -Control-Allow-Origin' header when the credentials flag is true. Origin '" + sec urityOrigin->toString() + "' is therefore not allowed access.";
142 else
143 errorDescription = "A wildcard '*' cannot be used in the 'Access -Control-Allow-Origin' or 'Access-Control-Allow-Finer-Origin' header when the cr edentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
134 } 144 }
135 } else if (accessControlOriginString != securityOrigin->toAtomicString()) { 145 } else if (accessControlOriginString != securityOrigin->toAtomicString() && accessControlFinerOriginString != securityOrigin->toRawAtomicString()) {
136 if (accessControlOriginString.isEmpty()) { 146 if (accessControlOriginString.isEmpty() && accessControlFinerOriginStrin g.isEmpty()) {
137 errorDescription = "No 'Access-Control-Allow-Origin' header is prese nt on the requested resource. Origin '" + securityOrigin->toString() + "' is the refore not allowed access."; 147 if (!experimentalContentSecurityPolicyFeaturesEnabled())
138 148 errorDescription = "No 'Access-Control-Allow-Origin' header is p resent on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
149 else
150 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.";
139 if (isInterestingStatusCode(response.httpStatusCode())) 151 if (isInterestingStatusCode(response.httpStatusCode()))
140 errorDescription.append(" The response had HTTP status code " + String::number(response.httpStatusCode()) + "."); 152 errorDescription.append(" The response had HTTP status code " + String::number(response.httpStatusCode()) + ".");
141 } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound) { 153 } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound || accessControlFinerOriginString.string().find(isOriginSeparator, 0) != kNotFound) {
142 errorDescription = "The 'Access-Control-Allow-Origin' header contain s multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access."; 154 if (!experimentalContentSecurityPolicyFeaturesEnabled())
155 errorDescription = "The 'Access-Control-Allow-Origin' header con tains multiple values '" + accessControlOriginString + "', but only one is allow ed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access. ";
156 else
157 errorDescription = "The 'Access-Control-Allow-Origin' or 'Access -Control-Allow-Finer-Origin' header contains multiple values '" + accessControlO riginString + "', but only one is allowed. Origin '" + securityOrigin->toString( ) + "' is therefore not allowed access.";
143 } else { 158 } else {
144 KURL headerOrigin(KURL(), accessControlOriginString); 159 KURL headerOrigin(KURL(), accessControlOriginString);
145 if (!headerOrigin.isValid()) 160 KURL headerFinerOrigin(KURL(), accessControlFinerOriginString);
161 if (!headerOrigin.isValid()) {
146 errorDescription = "The 'Access-Control-Allow-Origin' header con tains the invalid value '" + accessControlOriginString + "'. Origin '" + securit yOrigin->toString() + "' is therefore not allowed access."; 162 errorDescription = "The 'Access-Control-Allow-Origin' header con tains the invalid value '" + accessControlOriginString + "'. Origin '" + securit yOrigin->toString() + "' is therefore not allowed access.";
147 else 163 } else if (experimentalContentSecurityPolicyFeaturesEnabled() && !he aderFinerOrigin.isValid()) {
148 errorDescription = "The 'Access-Control-Allow-Origin' header has a value '" + accessControlOriginString + "' that is not equal to the supplied o rigin. Origin '" + securityOrigin->toString() + "' is therefore not allowed acce ss."; 164 errorDescription = "The 'Access-Control-Allow-Finer-Origin' head er contains the invalid value '" + accessControlOriginString + "'. Origin '" + s ecurityOrigin->toString() + "' is therefore not allowed access.";
165 } else {
166 if (!experimentalContentSecurityPolicyFeaturesEnabled())
167 errorDescription = "The 'Access-Control-Allow-Origin' header has a value '" + accessControlOriginString + "' that is not equal to the suppli ed origin. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
168 else
169 errorDescription = "The 'Access-Control-Allow-Origin' or 'Ac cess-Control-Allow-Finer-Origin' header has a value '" + accessControlOriginStri ng + "' that is not equal to the supplied origin. Origin '" + securityOrigin->to String() + "' 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
170 }
149 } 171 }
150 return false; 172 return false;
151 } 173 }
152 174
153 if (includeCredentials == AllowStoredCredentials) { 175 if (includeCredentials == AllowStoredCredentials) {
154 const AtomicString& accessControlCredentialsString = response.httpHeader Field(accessControlAllowCredentials); 176 const AtomicString& accessControlCredentialsString = response.httpHeader Field(accessControlAllowCredentials);
155 if (accessControlCredentialsString != "true") { 177 if (accessControlCredentialsString != "true") {
156 errorDescription = "Credentials flag is 'true', but the 'Access-Cont rol-Allow-Credentials' header is '" + accessControlCredentialsString + "'. It mu st be 'true' to allow credentials."; 178 errorDescription = "Credentials flag is 'true', but the 'Access-Cont rol-Allow-Credentials' header is '" + accessControlCredentialsString + "'. It mu st be 'true' to allow credentials.";
157 return false; 179 return false;
158 } 180 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 request.setHTTPOrigin(securityOrigin->toAtomicString()); 261 request.setHTTPOrigin(securityOrigin->toAtomicString());
240 // If the user didn't request credentials in the first place, update our 262 // If the user didn't request credentials in the first place, update our
241 // state so we neither request them nor expect they must be allowed. 263 // state so we neither request them nor expect they must be allowed.
242 if (options.credentialsRequested == ClientDidNotRequestCredentials) 264 if (options.credentialsRequested == ClientDidNotRequestCredentials)
243 options.allowCredentials = DoNotAllowStoredCredentials; 265 options.allowCredentials = DoNotAllowStoredCredentials;
244 } 266 }
245 return true; 267 return true;
246 } 268 }
247 269
248 } // namespace blink 270 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698