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

Side by Side Diff: third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp

Issue 1745083002: CORS-RFC1918: Force preflights for external requests in DocumentThreadableLoader. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Test. Created 4 years, 7 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) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013, Intel Corporation 3 * Copyright (C) 2013, Intel Corporation
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // |this| may be dead here. 228 // |this| may be dead here.
229 return; 229 return;
230 } 230 }
231 231
232 dispatchInitialRequest(request); 232 dispatchInitialRequest(request);
233 // |this| may be dead here in async mode. 233 // |this| may be dead here in async mode.
234 } 234 }
235 235
236 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req uest) 236 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req uest)
237 { 237 {
238 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO riginRequests) { 238 if (!request.isExternalRequest() && (m_sameOriginRequest || m_options.crossO riginRequestPolicy == AllowCrossOriginRequests)) {
239 loadRequest(request, m_resourceLoaderOptions); 239 loadRequest(request, m_resourceLoaderOptions);
240 // |this| may be dead here in async mode. 240 // |this| may be dead here in async mode.
241 return; 241 return;
242 } 242 }
243 243
244 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 244 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE xternalRequest());
245 245
246 makeCrossOriginAccessRequest(request); 246 makeCrossOriginAccessRequest(request);
247 // |this| may be dead here in async mode. 247 // |this| may be dead here in async mode.
248 } 248 }
249 249
250 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) 250 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request)
251 { 251 {
252 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 252 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE xternalRequest());
253 ASSERT(m_client); 253 ASSERT(m_client);
254 ASSERT(!resource()); 254 ASSERT(!resource());
255 255
256 // Cross-origin requests are only allowed certain registered schemes. 256 // Cross-origin requests are only allowed certain registered schemes.
257 // We would catch this when checking response headers later, but there 257 // We would catch this when checking response headers later, but there
258 // is no reason to send a request, preflighted or not, that's guaranteed 258 // is no reason to send a request, preflighted or not, that's guaranteed
259 // to be denied. 259 // to be denied.
260 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { 260 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) {
261 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo rClient(m_document, m_client); 261 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo rClient(m_document, m_client);
262 ThreadableLoaderClient* client = m_client; 262 ThreadableLoaderClient* client = m_client;
263 clear(); 263 clear();
264 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Cross origin requests are only supported for pr otocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); 264 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Cross origin requests are only supported for pr otocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + "."));
265 // |this| may be dead here in async mode. 265 // |this| may be dead here in async mode.
266 return; 266 return;
267 } 267 }
268 268
269 // Non-secure origins may not make "external requests": https://mikewest.git hub.io/cors-rfc1918/#integration-fetch
270 if (!document().isSecureContext() && request.isExternalRequest()) {
271 ThreadableLoaderClient* client = m_client;
272 clear();
273 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Requests to internal network resources are not allowed from non-secure contexts (see https://goo.gl/Y0ZkNV). This is an experim ental restriction which is part of 'https://mikewest.github.io/cors-rfc1918/'.") );
274 // |this| may be dead here in async mode.
275 return;
276 }
277
269 // We use isSimpleOrForbiddenRequest() here since |request| may have been 278 // We use isSimpleOrForbiddenRequest() here since |request| may have been
270 // modified in the process of loading (not from the user's input). For 279 // modified in the process of loading (not from the user's input). For
271 // example, referrer. We need to accept them. For security, we must reject 280 // example, referrer. We need to accept them. For security, we must reject
272 // forbidden headers/methods at the point we accept user's input. Not here. 281 // forbidden headers/methods at the point we accept user's input. Not here.
273 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) { 282 if (!request.isExternalRequest() && ((m_options.preflightPolicy == ConsiderP reflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request .httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)) {
274 ResourceRequest crossOriginRequest(request); 283 ResourceRequest crossOriginRequest(request);
275 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); 284 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions);
276 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e ffectiveAllowCredentials()); 285 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e ffectiveAllowCredentials());
277 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct. 286 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct.
278 // FIXME: We should set it in the caller of DocumentThreadableLoader. 287 // FIXME: We should set it in the caller of DocumentThreadableLoader.
279 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit); 288 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit);
280 loadRequest(crossOriginRequest, crossOriginOptions); 289 loadRequest(crossOriginRequest, crossOriginOptions);
281 // |this| may be dead here in async mode. 290 // |this| may be dead here in async mode.
282 } else { 291 } else {
283 m_crossOriginNonSimpleRequest = true; 292 m_crossOriginNonSimpleRequest = true;
284 293
285 ResourceRequest crossOriginRequest(request); 294 ResourceRequest crossOriginRequest(request);
286 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); 295 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions);
287 // Do not set the Origin header for preflight requests. 296 // Do not set the Origin header for preflight requests.
288 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede ntials()); 297 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede ntials());
289 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct. 298 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct.
290 // FIXME: We should set it in the caller of DocumentThreadableLoader. 299 // FIXME: We should set it in the caller of DocumentThreadableLoader.
291 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit); 300 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit);
292 m_actualRequest = crossOriginRequest; 301 m_actualRequest = crossOriginRequest;
293 m_actualOptions = crossOriginOptions; 302 m_actualOptions = crossOriginOptions;
294 303
295 bool shouldForcePreflight = InspectorInstrumentation::shouldForceCORSPre flight(m_document); 304 bool shouldForcePreflight = request.isExternalRequest() || InspectorInst rumentation::shouldForceCORSPreflight(m_document);
296 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields() ); 305 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields() );
297 if (canSkipPreflight && !shouldForcePreflight) { 306 if (canSkipPreflight && !shouldForcePreflight) {
298 loadActualRequest(); 307 loadActualRequest();
299 // |this| may be dead here in async mode. 308 // |this| may be dead here in async mode.
300 } else { 309 } else {
301 ResourceRequest preflightRequest = createAccessControlPreflightReque st(m_actualRequest, getSecurityOrigin()); 310 ResourceRequest preflightRequest = createAccessControlPreflightReque st(m_actualRequest, getSecurityOrigin());
302 // Create a ResourceLoaderOptions for preflight. 311 // Create a ResourceLoaderOptions for preflight.
303 ResourceLoaderOptions preflightOptions = m_actualOptions; 312 ResourceLoaderOptions preflightOptions = m_actualOptions;
304 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; 313 preflightOptions.allowCredentials = DoNotAllowStoredCredentials;
305 loadRequest(preflightRequest, preflightOptions); 314 loadRequest(preflightRequest, preflightOptions);
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 // |this| may be dead here in async mode. 600 // |this| may be dead here in async mode.
592 return; 601 return;
593 } 602 }
594 603
595 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { 604 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) {
596 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); 605 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription);
597 // |this| may be dead here in async mode. 606 // |this| may be dead here in async mode.
598 return; 607 return;
599 } 608 }
600 609
610 if (m_actualRequest.isExternalRequest() && !passesExternalPreflightCheck(res ponse, accessControlErrorDescription)) {
611 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription);
612 // |this| may be dead here in async mode.
613 return;
614 }
615
601 OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new C rossOriginPreflightResultCacheItem(effectiveAllowCredentials())); 616 OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new C rossOriginPreflightResultCacheItem(effectiveAllowCredentials()));
602 if (!preflightResult->parse(response, accessControlErrorDescription) 617 if (!preflightResult->parse(response, accessControlErrorDescription)
603 || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod( ), accessControlErrorDescription) 618 || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod( ), accessControlErrorDescription)
604 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeader Fields(), accessControlErrorDescription)) { 619 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeader Fields(), accessControlErrorDescription)) {
605 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); 620 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription);
606 // |this| may be dead here in async mode. 621 // |this| may be dead here in async mode.
607 return; 622 return;
608 } 623 }
609 624
610 CrossOriginPreflightResultCache::shared().appendEntry(getSecurityOrigin()->t oString(), m_actualRequest.url(), preflightResult.release()); 625 CrossOriginPreflightResultCache::shared().appendEntry(getSecurityOrigin()->t oString(), m_actualRequest.url(), preflightResult.release());
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri gin(); 968 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri gin();
954 } 969 }
955 970
956 Document& DocumentThreadableLoader::document() const 971 Document& DocumentThreadableLoader::document() const
957 { 972 {
958 ASSERT(m_document); 973 ASSERT(m_document);
959 return *m_document; 974 return *m_document;
960 } 975 }
961 976
962 } // namespace blink 977 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698