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

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

Issue 891263002: Prevent calling didReceiveData()/didFinishLoading() after didFailAccessControlCheck() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: More assert. Created 5 years, 10 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 , m_options(options) 85 , m_options(options)
86 , m_resourceLoaderOptions(resourceLoaderOptions) 86 , m_resourceLoaderOptions(resourceLoaderOptions)
87 , m_forceDoNotAllowStoredCredentials(false) 87 , m_forceDoNotAllowStoredCredentials(false)
88 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) 88 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin)
89 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) 89 , m_sameOriginRequest(securityOrigin()->canRequest(request.url()))
90 , m_simpleRequest(true) 90 , m_simpleRequest(true)
91 , m_async(blockingBehavior == LoadAsynchronously) 91 , m_async(blockingBehavior == LoadAsynchronously)
92 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) 92 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout)
93 , m_requestStartedSeconds(0.0) 93 , m_requestStartedSeconds(0.0)
94 , m_corsRedirectLimit(kMaxCORSRedirects) 94 , m_corsRedirectLimit(kMaxCORSRedirects)
95 , m_accessControlCheckFailed(false)
95 { 96 {
96 ASSERT(client); 97 ASSERT(client);
97 // Setting an outgoing referer is only supported in the async code path. 98 // Setting an outgoing referer is only supported in the async code path.
98 ASSERT(m_async || request.httpReferrer().isEmpty()); 99 ASSERT(m_async || request.httpReferrer().isEmpty());
99 100
100 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { 101 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) {
101 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url ().string(), "Cross origin requests are not supported.")); 102 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url ().string(), "Cross origin requests are not supported."));
102 return; 103 return;
103 } 104 }
104 105
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 156
156 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) 157 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request)
157 { 158 {
158 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 159 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
159 160
160 // Cross-origin requests are only allowed certain registered schemes. 161 // Cross-origin requests are only allowed certain registered schemes.
161 // We would catch this when checking response headers later, but there 162 // We would catch this when checking response headers later, but there
162 // is no reason to send a request, preflighted or not, that's guaranteed 163 // is no reason to send a request, preflighted or not, that's guaranteed
163 // to be denied. 164 // to be denied.
164 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { 165 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) {
165 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIntern al, 0, request.url().string(), "Cross origin requests are only supported for pro tocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); 166 handlePreflightFailure(request.url().string(), "Cross origin requests ar e only supported for protocol schemes: " + SchemeRegistry::listOfCORSEnabledURLS chemes() + ".");
166 return; 167 return;
167 } 168 }
168 169
169 // We use isSimpleOrForbiddenRequest() here since |request| may have been 170 // We use isSimpleOrForbiddenRequest() here since |request| may have been
170 // modified in the process of loading (not from the user's input). For 171 // modified in the process of loading (not from the user's input). For
171 // example, referrer. We need to accept them. For security, we must reject 172 // example, referrer. We need to accept them. For security, we must reject
172 // forbidden headers/methods at the point we accept user's input. Not here. 173 // forbidden headers/methods at the point we accept user's input. Not here.
173 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) { 174 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) {
174 ResourceRequest crossOriginRequest(request); 175 ResourceRequest crossOriginRequest(request);
175 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); 176 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 request.clearHTTPReferrer(); 329 request.clearHTTPReferrer();
329 request.clearHTTPOrigin(); 330 request.clearHTTPOrigin();
330 request.clearHTTPUserAgent(); 331 request.clearHTTPUserAgent();
331 // Add any CORS simple request headers which we previously saved fro m the original request. 332 // Add any CORS simple request headers which we previously saved fro m the original request.
332 for (const auto& header : m_simpleRequestHeaders) 333 for (const auto& header : m_simpleRequestHeaders)
333 request.setHTTPHeaderField(header.key, header.value); 334 request.setHTTPHeaderField(header.key, header.value);
334 makeCrossOriginAccessRequest(request); 335 makeCrossOriginAccessRequest(request);
335 return; 336 return;
336 } 337 }
337 338
338 ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url(). string(), accessControlErrorDescription); 339 handlePreflightFailure(redirectResponse.url().string(), accessControlErr orDescription);
339 m_client->didFailAccessControlCheck(error);
340 } else { 340 } else {
341 m_client->didFailRedirectCheck(); 341 m_client->didFailRedirectCheck();
342 } 342 }
343 343
344 clearResource(); 344 clearResource();
345 request = ResourceRequest(); 345 request = ResourceRequest();
346 346
347 m_requestStartedSeconds = 0.0; 347 m_requestStartedSeconds = 0.0;
348 } 348 }
349 349
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 m_client->didReceiveResponse(identifier, response, handle); 429 m_client->didReceiveResponse(identifier, response, handle);
430 return; 430 return;
431 } 431 }
432 432
433 ASSERT(!m_fallbackRequestForServiceWorker); 433 ASSERT(!m_fallbackRequestForServiceWorker);
434 434
435 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { 435 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) {
436 String accessControlErrorDescription; 436 String accessControlErrorDescription;
437 if (!passesAccessControlCheck(&m_document, response, effectiveAllowCrede ntials(), securityOrigin(), accessControlErrorDescription)) { 437 if (!passesAccessControlCheck(&m_document, response, effectiveAllowCrede ntials(), securityOrigin(), accessControlErrorDescription)) {
438 reportResponseReceived(identifier, response); 438 reportResponseReceived(identifier, response);
439 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIn ternal, 0, response.url().string(), accessControlErrorDescription)); 439 handlePreflightFailure(response.url().string(), accessControlErrorDe scription);
440 return; 440 return;
441 } 441 }
442 } 442 }
443 443
444 m_client->didReceiveResponse(identifier, response, handle); 444 m_client->didReceiveResponse(identifier, response, handle);
445 } 445 }
446 446
447 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , unsigned dataLength) 447 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , unsigned dataLength)
448 { 448 {
449 ASSERT_UNUSED(resource, resource == this->resource()); 449 ASSERT_UNUSED(resource, resource == this->resource());
450 ASSERT(m_async); 450 ASSERT(m_async);
451 451
452 handleReceivedData(data, dataLength); 452 handleReceivedData(data, dataLength);
453 } 453 }
454 454
455 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat aLength) 455 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat aLength)
456 { 456 {
457 ASSERT(m_client); 457 ASSERT(m_client);
458 458
459 // Preflight data should be invisible to clients. 459 // Preflight data should be invisible to clients.
460 if (m_actualRequest) 460 if (m_actualRequest)
461 return; 461 return;
462 462
463 ASSERT(!m_fallbackRequestForServiceWorker); 463 ASSERT(!m_fallbackRequestForServiceWorker);
464 464
465 m_client->didReceiveData(data, dataLength); 465 if (!m_accessControlCheckFailed)
466 m_client->didReceiveData(data, dataLength);
466 } 467 }
467 468
468 void DocumentThreadableLoader::notifyFinished(Resource* resource) 469 void DocumentThreadableLoader::notifyFinished(Resource* resource)
469 { 470 {
470 ASSERT(m_client); 471 ASSERT(m_client);
471 ASSERT(resource == this->resource()); 472 ASSERT(resource == this->resource());
472 ASSERT(m_async); 473 ASSERT(m_async);
473 474
474 m_timeoutTimer.stop(); 475 m_timeoutTimer.stop();
475 476
476 if (resource->errorOccurred()) 477 if (resource->errorOccurred())
477 m_client->didFail(resource->resourceError()); 478 m_client->didFail(resource->resourceError());
478 else 479 else
479 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); 480 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( ));
480 } 481 }
481 482
482 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) 483 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime)
483 { 484 {
484 ASSERT(!m_fallbackRequestForServiceWorker); 485 ASSERT(!m_fallbackRequestForServiceWorker);
485 486
486 if (m_actualRequest) { 487 if (m_actualRequest) {
487 ASSERT(!m_sameOriginRequest); 488 ASSERT(!m_sameOriginRequest);
488 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 489 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
489 loadActualRequest(); 490 loadActualRequest();
490 } else { 491 } else {
491 // FIXME: Should prevent timeout from being overridden after finished lo ading, without 492 // FIXME: Should prevent timeout from being overridden after finished lo ading, without
492 // resetting m_requestStartedSeconds to 0.0 493 // resetting m_requestStartedSeconds to 0.0
493 m_client->didFinishLoading(identifier, finishTime); 494 if (!m_accessControlCheckFailed)
495 m_client->didFinishLoading(identifier, finishTime);
494 } 496 }
495 } 497 }
496 498
497 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) 499 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer )
498 { 500 {
499 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); 501 ASSERT_UNUSED(timer, timer == &m_timeoutTimer);
500 502
501 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, 503 // Using values from net/base/net_error_list.h ERR_TIMED_OUT,
502 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. 504 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable.
503 static const int timeoutError = -7; 505 static const int timeoutError = -7;
(...skipping 16 matching lines...) Expand all
520 OwnPtr<ResourceLoaderOptions> actualOptions; 522 OwnPtr<ResourceLoaderOptions> actualOptions;
521 actualOptions.swap(m_actualOptions); 523 actualOptions.swap(m_actualOptions);
522 524
523 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); 525 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString());
524 526
525 clearResource(); 527 clearResource();
526 528
527 loadRequest(*actualRequest, *actualOptions); 529 loadRequest(*actualRequest, *actualOptions);
528 } 530 }
529 531
532 // Call handlePreflightFailure() instead of didFailAccessControlCheck()
533 // from other places in DocumentThreadableLoader.
kinuko 2015/02/03 02:35:36 nit: putting this comment in the header feels more
hiroshige 2015/02/03 08:19:44 Done.
530 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) 534 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription)
tyoshino (SeeGerritForStatus) 2015/02/03 06:22:02 rename this as it's no longer specific to prefligh
hiroshige 2015/02/03 08:19:43 Done.
531 { 535 {
532 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); 536 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription);
533 537
534 // Prevent handleSuccessfulFinish() from bypassing access check. 538 // Prevent handleSuccessfulFinish() from bypassing access check.
535 m_actualRequest = nullptr; 539 m_actualRequest = nullptr;
536 540
541 // Prevent m_client->didReceiveData()/didFinishLoading() from being called
542 // after m_client->didFailAccessControlCheck() is called here.
543 m_accessControlCheckFailed = true;
544
537 // FIXME: Should prevent timeout from being overridden after preflight failu re, without 545 // FIXME: Should prevent timeout from being overridden after preflight failu re, without
538 // resetting m_requestStartedSeconds to 0.0 546 // resetting m_requestStartedSeconds to 0.0
539 m_client->didFailAccessControlCheck(error); 547 m_client->didFailAccessControlCheck(error);
540 } 548 }
541 549
542 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) 550 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions)
543 { 551 {
544 // Any credential should have been removed from the cross-site requests. 552 // Any credential should have been removed from the cross-site requests.
545 const KURL& requestURL = request.url(); 553 const KURL& requestURL = request.url();
546 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); 554 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 return DoNotAllowStoredCredentials; 640 return DoNotAllowStoredCredentials;
633 return m_resourceLoaderOptions.allowCredentials; 641 return m_resourceLoaderOptions.allowCredentials;
634 } 642 }
635 643
636 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const 644 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const
637 { 645 {
638 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); 646 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin ();
639 } 647 }
640 648
641 } // namespace blink 649 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698