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

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

Issue 544573002: Mixed Content: Move subframe checks into ResourceFetcher. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: printf Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/fetch/ResourceFetcher.h ('k') | Source/core/loader/DocumentLoader.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
7 7
8 This library is free software; you can redistribute it and/or 8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 options.synchronousPolicy = RequestSynchronously; 295 options.synchronousPolicy = RequestSynchronously;
296 request.setOptions(options); 296 request.setOptions(options);
297 return requestResource(Resource::Raw, request); 297 return requestResource(Resource::Raw, request);
298 } 298 }
299 299
300 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request) 300 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request)
301 { 301 {
302 if (LocalFrame* f = frame()) { 302 if (LocalFrame* f = frame()) {
303 if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDi smissal) { 303 if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDi smissal) {
304 KURL requestURL = request.resourceRequest().url(); 304 KURL requestURL = request.resourceRequest().url();
305 if (requestURL.isValid() && canRequest(Resource::Image, requestURL, request.options(), request.forPreload(), request.originRestriction())) 305 if (requestURL.isValid() && canRequest(Resource::Image, request.reso urceRequest(), requestURL, request.options(), request.forPreload(), request.orig inRestriction()))
306 PingLoader::loadImage(f, requestURL); 306 PingLoader::loadImage(f, requestURL);
307 return 0; 307 return 0;
308 } 308 }
309 } 309 }
310 310
311 if (request.resourceRequest().url().protocolIsData()) 311 if (request.resourceRequest().url().protocolIsData())
312 preCacheDataURIImage(request); 312 preCacheDataURIImage(request);
313 313
314 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR equest::DeferredByClient : FetchRequest::NoDefer); 314 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR equest::DeferredByClient : FetchRequest::NoDefer);
315 ResourcePtr<Resource> resource = requestResource(Resource::Image, request); 315 ResourcePtr<Resource> resource = requestResource(Resource::Image, request);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 resource->setNeedsSynchronousCacheHit(substituteData.forceSynchronousLoad()) ; 424 resource->setNeedsSynchronousCacheHit(substituteData.forceSynchronousLoad()) ;
425 resource->setOptions(request.options()); 425 resource->setOptions(request.options());
426 resource->setDataBufferingPolicy(BufferData); 426 resource->setDataBufferingPolicy(BufferData);
427 resource->responseReceived(response); 427 resource->responseReceived(response);
428 if (substituteData.content()->size()) 428 if (substituteData.content()->size())
429 resource->setResourceBuffer(substituteData.content()); 429 resource->setResourceBuffer(substituteData.content());
430 resource->finish(); 430 resource->finish();
431 memoryCache()->add(resource.get()); 431 memoryCache()->add(resource.get());
432 } 432 }
433 433
434 bool ResourceFetcher::checkInsecureContent(Resource::Type type, const KURL& url, MixedContentBlockingTreatment treatment) const 434 bool ResourceFetcher::checkInsecureContent(Resource::Type type, const KURL& url, LocalFrame* frame, MixedContentBlockingTreatment treatment) const
435 { 435 {
436 if (treatment == TreatAsDefaultForType) { 436 if (treatment == TreatAsDefaultForType) {
437 switch (type) { 437 switch (type) {
438 case Resource::XSLStyleSheet: 438 case Resource::XSLStyleSheet:
439 ASSERT(RuntimeEnabledFeatures::xsltEnabled()); 439 ASSERT(RuntimeEnabledFeatures::xsltEnabled());
440 case Resource::Script: 440 case Resource::Script:
441 case Resource::SVGDocument: 441 case Resource::SVGDocument:
442 case Resource::CSSStyleSheet: 442 case Resource::CSSStyleSheet:
443 case Resource::ImportResource: 443 case Resource::ImportResource:
444 // These resource can inject script into the current document (Scrip t, 444 // These resource can inject script into the current document (Scrip t,
(...skipping 16 matching lines...) Expand all
461 break; 461 break;
462 462
463 case Resource::MainResource: 463 case Resource::MainResource:
464 case Resource::LinkPrefetch: 464 case Resource::LinkPrefetch:
465 case Resource::LinkSubresource: 465 case Resource::LinkSubresource:
466 // These cannot affect the current document. 466 // These cannot affect the current document.
467 treatment = TreatAsAlwaysAllowedContent; 467 treatment = TreatAsAlwaysAllowedContent;
468 break; 468 break;
469 } 469 }
470 } 470 }
471
472 // No frame, no mixed content.
473 if (!frame)
474 return true;
475
471 if (treatment == TreatAsActiveContent) { 476 if (treatment == TreatAsActiveContent) {
472 if (LocalFrame* f = frame()) { 477 if (!frame->loader().mixedContentChecker()->canRunInsecureContent(frame- >document()->securityOrigin(), url))
473 if (!f->loader().mixedContentChecker()->canRunInsecureContent(m_docu ment->securityOrigin(), url)) 478 return false;
474 return false;
475 }
476 } else if (treatment == TreatAsPassiveContent) { 479 } else if (treatment == TreatAsPassiveContent) {
477 if (LocalFrame* f = frame()) { 480 if (!frame->loader().mixedContentChecker()->canDisplayInsecureContent(fr ame->document()->securityOrigin(), url))
478 if (!f->loader().mixedContentChecker()->canDisplayInsecureContent(m_ document->securityOrigin(), url)) 481 return false;
479 return false; 482 if (MixedContentChecker::isMixedContent(frame->document()->securityOrigi n(), url) || MixedContentChecker::isMixedContent(toLocalFrame(frame->tree().top( ))->document()->securityOrigin(), url)) {
480 if (MixedContentChecker::isMixedContent(f->document()->securityOrigi n(), url) || MixedContentChecker::isMixedContent(toLocalFrame(frame()->tree().to p())->document()->securityOrigin(), url)) { 483 switch (type) {
481 switch (type) { 484 case Resource::Raw:
482 case Resource::Raw: 485 UseCounter::count(frame->document(), UseCounter::MixedContentRaw );
483 UseCounter::count(f->document(), UseCounter::MixedContentRaw ); 486 break;
484 break;
485 487
486 case Resource::Image: 488 case Resource::Image:
487 UseCounter::count(f->document(), UseCounter::MixedContentIma ge); 489 UseCounter::count(frame->document(), UseCounter::MixedContentIma ge);
488 break; 490 break;
489 491
490 case Resource::Media: 492 case Resource::Media:
491 UseCounter::count(f->document(), UseCounter::MixedContentMed ia); 493 UseCounter::count(frame->document(), UseCounter::MixedContentMed ia);
492 break; 494 break;
493 495
494 default: 496 default:
495 ASSERT_NOT_REACHED(); 497 ASSERT_NOT_REACHED();
496 }
497 } 498 }
498 } 499 }
499 } else { 500 } else {
500 ASSERT(treatment == TreatAsAlwaysAllowedContent); 501 ASSERT(treatment == TreatAsAlwaysAllowedContent);
501 } 502 }
502 return true; 503 return true;
503 } 504 }
504 505
505 bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res ourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction or iginRestriction) const 506 bool ResourceFetcher::canRequest(Resource::Type type, const ResourceRequest& res ourceRequest, const KURL& url, const ResourceLoaderOptions& options, bool forPre load, FetchRequest::OriginRestriction originRestriction) const
506 { 507 {
507 SecurityOrigin* securityOrigin = options.securityOrigin.get(); 508 SecurityOrigin* securityOrigin = options.securityOrigin.get();
508 if (!securityOrigin && document()) 509 if (!securityOrigin && document())
509 securityOrigin = document()->securityOrigin(); 510 securityOrigin = document()->securityOrigin();
510 511
511 if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin && !securityOrigin->canDisplay(url)) { 512 if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin && !securityOrigin->canDisplay(url)) {
512 if (!forPreload) 513 if (!forPreload)
513 context().reportLocalLoadFailed(url); 514 context().reportLocalLoadFailed(url);
514 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not a llowed by SecurityOrigin::canDisplay"); 515 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not a llowed by SecurityOrigin::canDisplay");
515 return 0; 516 return 0;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 // except for data urls. 617 // except for data urls.
617 if (type != Resource::MainResource) { 618 if (type != Resource::MainResource) {
618 if (frame() && frame()->chromeClient().isSVGImageChromeClient() && !url. protocolIsData()) 619 if (frame() && frame()->chromeClient().isSVGImageChromeClient() && !url. protocolIsData())
619 return false; 620 return false;
620 } 621 }
621 622
622 // Last of all, check for insecure content. We do this last so that when 623 // Last of all, check for insecure content. We do this last so that when
623 // folks block insecure content with a CSP policy, they don't get a warning. 624 // folks block insecure content with a CSP policy, they don't get a warning.
624 // They'll still get a warning in the console about CSP blocking the load. 625 // They'll still get a warning in the console about CSP blocking the load.
625 626
627 // If we're loading the main resource of a subframe, ensure that we treat th e resource as active
628 // content for the purposes of mixed content checks, and that we check again st the parent of the
629 // active frame, rather than the frame itself.
630 LocalFrame* effectiveFrame = frame();
631 MixedContentBlockingTreatment effectiveTreatment = options.mixedContentBlock ingTreatment;
632 if (resourceRequest.frameType() == WebURLRequest::FrameTypeNested) {
633 effectiveTreatment = TreatAsActiveContent;
634 // FIXME: Deal with RemoteFrames.
635 if (frame()->tree().parent()->isLocalFrame())
636 effectiveFrame = toLocalFrame(frame()->tree().parent());
637 }
638
626 // FIXME: Should we consider forPreload here? 639 // FIXME: Should we consider forPreload here?
627 if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment)) 640 if (!checkInsecureContent(type, url, effectiveFrame, effectiveTreatment))
628 return false; 641 return false;
629 642
630 return true; 643 return true;
631 } 644 }
632 645
633 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url) const 646 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url) const
634 { 647 {
635 // Redirects can change the response URL different from one of request. 648 // Redirects can change the response URL different from one of request.
636 if (!canRequest(resource->type(), url, resource->options(), resource->isUnus edPreload(), FetchRequest::UseDefaultOriginRestrictionForType)) 649 if (!canRequest(resource->type(), resource->resourceRequest(), url, resource ->options(), resource->isUnusedPreload(), FetchRequest::UseDefaultOriginRestrict ionForType))
637 return false; 650 return false;
638 651
639 if (!sourceOrigin && document()) 652 if (!sourceOrigin && document())
640 sourceOrigin = document()->securityOrigin(); 653 sourceOrigin = document()->securityOrigin();
641 654
642 if (sourceOrigin->canRequest(url)) 655 if (sourceOrigin->canRequest(url))
643 return true; 656 return true;
644 657
645 String errorDescription; 658 String errorDescription;
646 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) { 659 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 KURL url = request.resourceRequest().url(); 719 KURL url = request.resourceRequest().url();
707 720
708 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour ceTypeName(type)); 721 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour ceTypeName(type));
709 722
710 // If only the fragment identifiers differ, it is the same resource. 723 // If only the fragment identifiers differ, it is the same resource.
711 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); 724 url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
712 725
713 if (!url.isValid()) 726 if (!url.isValid())
714 return 0; 727 return 0;
715 728
716 if (!canRequest(type, url, request.options(), request.forPreload(), request. originRestriction())) 729 if (!canRequest(type, request.resourceRequest(), url, request.options(), req uest.forPreload(), request.originRestriction()))
717 return 0; 730 return 0;
718 731
719 if (LocalFrame* f = frame()) 732 if (LocalFrame* f = frame())
720 f->loader().client()->dispatchWillRequestResource(&request); 733 f->loader().client()->dispatchWillRequestResource(&request);
721 734
722 if (!request.forPreload()) { 735 if (!request.forPreload()) {
723 V8DOMActivityLogger* activityLogger = 0; 736 V8DOMActivityLogger* activityLogger = 0;
724 if (request.options().initiatorInfo.name == FetchInitiatorTypeNames::xml httprequest) 737 if (request.options().initiatorInfo.name == FetchInitiatorTypeNames::xml httprequest)
725 activityLogger = V8DOMActivityLogger::currentActivityLogger(); 738 activityLogger = V8DOMActivityLogger::currentActivityLogger();
726 else 739 else
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 1342
1330 void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& in itiatorInfo) 1343 void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& in itiatorInfo)
1331 { 1344 {
1332 context().dispatchWillSendRequest(m_documentLoader, identifier, request, red irectResponse, initiatorInfo); 1345 context().dispatchWillSendRequest(m_documentLoader, identifier, request, red irectResponse, initiatorInfo);
1333 } 1346 }
1334 1347
1335 void ResourceFetcher::didReceiveResponse(const Resource* resource, const Resourc eResponse& response) 1348 void ResourceFetcher::didReceiveResponse(const Resource* resource, const Resourc eResponse& response)
1336 { 1349 {
1337 // If the response is fetched via ServiceWorker, the original URL of the res ponse could be different from the URL of the request. 1350 // If the response is fetched via ServiceWorker, the original URL of the res ponse could be different from the URL of the request.
1338 if (response.wasFetchedViaServiceWorker()) { 1351 if (response.wasFetchedViaServiceWorker()) {
1339 if (!canRequest(resource->type(), response.url(), resource->options(), f alse, FetchRequest::UseDefaultOriginRestrictionForType)) { 1352 if (!canRequest(resource->type(), resource->resourceRequest(), response. url(), resource->options(), false, FetchRequest::UseDefaultOriginRestrictionForT ype)) {
1340 resource->loader()->cancel(); 1353 resource->loader()->cancel();
1341 context().dispatchDidFail(m_documentLoader, resource->identifier(), ResourceError(errorDomainBlinkInternal, 0, response.url().string(), "Unsafe atte mpt to load URL " + response.url().elidedString() + " fetched by a ServiceWorker .")); 1354 context().dispatchDidFail(m_documentLoader, resource->identifier(), ResourceError(errorDomainBlinkInternal, 0, response.url().string(), "Unsafe atte mpt to load URL " + response.url().elidedString() + " fetched by a ServiceWorker ."));
1342 return; 1355 return;
1343 } 1356 }
1344 } 1357 }
1345 context().dispatchDidReceiveResponse(m_documentLoader, resource->identifier( ), response, resource->loader()); 1358 context().dispatchDidReceiveResponse(m_documentLoader, resource->identifier( ), response, resource->loader());
1346 } 1359 }
1347 1360
1348 void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength) 1361 void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength)
1349 { 1362 {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 return false; 1433 return false;
1421 } 1434 }
1422 1435
1423 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const 1436 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const
1424 { 1437 {
1425 return this == possibleOwner; 1438 return this == possibleOwner;
1426 } 1439 }
1427 1440
1428 bool ResourceFetcher::canAccessRedirect(Resource* resource, ResourceRequest& req uest, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options) 1441 bool ResourceFetcher::canAccessRedirect(Resource* resource, ResourceRequest& req uest, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options)
1429 { 1442 {
1430 if (!canRequest(resource->type(), request.url(), options, resource->isUnused Preload(), FetchRequest::UseDefaultOriginRestrictionForType)) 1443 if (!canRequest(resource->type(), request, request.url(), options, resource- >isUnusedPreload(), FetchRequest::UseDefaultOriginRestrictionForType))
1431 return false; 1444 return false;
1432 if (options.corsEnabled == IsCORSEnabled) { 1445 if (options.corsEnabled == IsCORSEnabled) {
1433 SecurityOrigin* sourceOrigin = options.securityOrigin.get(); 1446 SecurityOrigin* sourceOrigin = options.securityOrigin.get();
1434 if (!sourceOrigin && document()) 1447 if (!sourceOrigin && document())
1435 sourceOrigin = document()->securityOrigin(); 1448 sourceOrigin = document()->securityOrigin();
1436 1449
1437 String errorMessage; 1450 String errorMessage;
1438 if (!CrossOriginAccessControl::handleRedirect(resource, sourceOrigin, re quest, redirectResponse, options, errorMessage)) { 1451 if (!CrossOriginAccessControl::handleRedirect(resource, sourceOrigin, re quest, redirectResponse, options, errorMessage)) {
1439 if (resource->type() == Resource::Font) 1452 if (resource->type() == Resource::Font)
1440 toFontResource(resource)->setCORSFailed(); 1453 toFontResource(resource)->setCORSFailed();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1553 1566
1554 void ResourceFetcher::trace(Visitor* visitor) 1567 void ResourceFetcher::trace(Visitor* visitor)
1555 { 1568 {
1556 visitor->trace(m_document); 1569 visitor->trace(m_document);
1557 visitor->trace(m_loaders); 1570 visitor->trace(m_loaders);
1558 visitor->trace(m_multipartLoaders); 1571 visitor->trace(m_multipartLoaders);
1559 ResourceLoaderHost::trace(visitor); 1572 ResourceLoaderHost::trace(visitor);
1560 } 1573 }
1561 1574
1562 } 1575 }
OLDNEW
« no previous file with comments | « Source/core/fetch/ResourceFetcher.h ('k') | Source/core/loader/DocumentLoader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698