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

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

Issue 2535383003: Collapse images disallowed by the Safe Browsing Subresource Filter. (Closed)
Patch Set: Initial draft. Created 4 years 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) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google 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 are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } else { 559 } else {
560 message = "Unsafe attempt to load URL " + url.elidedString() + 560 message = "Unsafe attempt to load URL " + url.elidedString() +
561 " from frame with URL " + m_document->url().elidedString() + 561 " from frame with URL " + m_document->url().elidedString() +
562 ". Domains, protocols and ports must match.\n"; 562 ". Domains, protocols and ports must match.\n";
563 } 563 }
564 564
565 frame()->document()->addConsoleMessage(ConsoleMessage::create( 565 frame()->document()->addConsoleMessage(ConsoleMessage::create(
566 SecurityMessageSource, ErrorMessageLevel, message)); 566 SecurityMessageSource, ErrorMessageLevel, message));
567 } 567 }
568 568
569 bool FrameFetchContext::canRequest( 569 ResourceRequestBlockedReason FrameFetchContext::canRequest(
570 Resource::Type type, 570 Resource::Type type,
571 const ResourceRequest& resourceRequest, 571 const ResourceRequest& resourceRequest,
572 const KURL& url, 572 const KURL& url,
573 const ResourceLoaderOptions& options, 573 const ResourceLoaderOptions& options,
574 bool forPreload, 574 bool forPreload,
575 FetchRequest::OriginRestriction originRestriction) const { 575 FetchRequest::OriginRestriction originRestriction) const {
576 ResourceRequestBlockedReason reason = 576 ResourceRequestBlockedReason blockedReason =
577 canRequestInternal(type, resourceRequest, url, options, forPreload, 577 canRequestInternal(type, resourceRequest, url, options, forPreload,
578 originRestriction, resourceRequest.redirectStatus()); 578 originRestriction, resourceRequest.redirectStatus());
579 if (reason != ResourceRequestBlockedReasonNone) { 579 if (blockedReason != ResourceRequestBlockedReason::None && !forPreload) {
580 if (!forPreload) { 580 InspectorInstrumentation::didBlockRequest(
581 InspectorInstrumentation::didBlockRequest(frame(), resourceRequest, 581 frame(), resourceRequest, masterDocumentLoader(), options.initiatorInfo,
582 masterDocumentLoader(), 582 blockedReason);
583 options.initiatorInfo, reason);
584 }
585 return false;
586 } 583 }
587 return true; 584 return blockedReason;
588 } 585 }
589 586
590 bool FrameFetchContext::allowResponse( 587 ResourceRequestBlockedReason FrameFetchContext::allowResponse(
591 Resource::Type type, 588 Resource::Type type,
592 const ResourceRequest& resourceRequest, 589 const ResourceRequest& resourceRequest,
593 const KURL& url, 590 const KURL& url,
594 const ResourceLoaderOptions& options) const { 591 const ResourceLoaderOptions& options) const {
595 ResourceRequestBlockedReason reason = 592 ResourceRequestBlockedReason blockedReason =
596 canRequestInternal(type, resourceRequest, url, options, false, 593 canRequestInternal(type, resourceRequest, url, options, false,
597 FetchRequest::UseDefaultOriginRestrictionForType, 594 FetchRequest::UseDefaultOriginRestrictionForType,
598 RedirectStatus::FollowedRedirect); 595 RedirectStatus::FollowedRedirect);
599 if (reason != ResourceRequestBlockedReasonNone) { 596 if (blockedReason != ResourceRequestBlockedReason::None) {
600 InspectorInstrumentation::didBlockRequest(frame(), resourceRequest, 597 InspectorInstrumentation::didBlockRequest(
601 masterDocumentLoader(), 598 frame(), resourceRequest, masterDocumentLoader(), options.initiatorInfo,
602 options.initiatorInfo, reason); 599 blockedReason);
603 return false;
604 } 600 }
605 return true; 601 return blockedReason;
606 } 602 }
607 603
608 ResourceRequestBlockedReason FrameFetchContext::canRequestInternal( 604 ResourceRequestBlockedReason FrameFetchContext::canRequestInternal(
609 Resource::Type type, 605 Resource::Type type,
610 const ResourceRequest& resourceRequest, 606 const ResourceRequest& resourceRequest,
611 const KURL& url, 607 const KURL& url,
612 const ResourceLoaderOptions& options, 608 const ResourceLoaderOptions& options,
613 bool forPreload, 609 bool forPreload,
614 FetchRequest::OriginRestriction originRestriction, 610 FetchRequest::OriginRestriction originRestriction,
615 ResourceRequest::RedirectStatus redirectStatus) const { 611 ResourceRequest::RedirectStatus redirectStatus) const {
616 if (InspectorInstrumentation::shouldBlockRequest(frame(), resourceRequest)) 612 if (InspectorInstrumentation::shouldBlockRequest(frame(), resourceRequest))
617 return ResourceRequestBlockedReasonInspector; 613 return ResourceRequestBlockedReason::Inspector;
618 614
619 SecurityOrigin* securityOrigin = options.securityOrigin.get(); 615 SecurityOrigin* securityOrigin = options.securityOrigin.get();
620 if (!securityOrigin && m_document) 616 if (!securityOrigin && m_document)
621 securityOrigin = m_document->getSecurityOrigin(); 617 securityOrigin = m_document->getSecurityOrigin();
622 618
623 if (originRestriction != FetchRequest::NoOriginRestriction && 619 if (originRestriction != FetchRequest::NoOriginRestriction &&
624 securityOrigin && !securityOrigin->canDisplay(url)) { 620 securityOrigin && !securityOrigin->canDisplay(url)) {
625 if (!forPreload) 621 if (!forPreload)
626 FrameLoader::reportLocalLoadFailed(frame(), url.elidedString()); 622 FrameLoader::reportLocalLoadFailed(frame(), url.elidedString());
627 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not " 623 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not "
628 "allowed by SecurityOrigin::canDisplay"; 624 "allowed by SecurityOrigin::canDisplay";
629 return ResourceRequestBlockedReasonOther; 625 return ResourceRequestBlockedReason::Other;
630 } 626 }
631 627
632 // Some types of resources can be loaded only from the same origin. Other 628 // Some types of resources can be loaded only from the same origin. Other
633 // types of resources, like Images, Scripts, and CSS, can be loaded from 629 // types of resources, like Images, Scripts, and CSS, can be loaded from
634 // any URL. 630 // any URL.
635 switch (type) { 631 switch (type) {
636 case Resource::MainResource: 632 case Resource::MainResource:
637 case Resource::Image: 633 case Resource::Image:
638 case Resource::CSSStyleSheet: 634 case Resource::CSSStyleSheet:
639 case Resource::Script: 635 case Resource::Script:
640 case Resource::Font: 636 case Resource::Font:
641 case Resource::Raw: 637 case Resource::Raw:
642 case Resource::LinkPrefetch: 638 case Resource::LinkPrefetch:
643 case Resource::TextTrack: 639 case Resource::TextTrack:
644 case Resource::ImportResource: 640 case Resource::ImportResource:
645 case Resource::Media: 641 case Resource::Media:
646 case Resource::Manifest: 642 case Resource::Manifest:
647 // By default these types of resources can be loaded from any origin. 643 // By default these types of resources can be loaded from any origin.
648 // FIXME: Are we sure about Resource::Font? 644 // FIXME: Are we sure about Resource::Font?
649 if (originRestriction == FetchRequest::RestrictToSameOrigin && 645 if (originRestriction == FetchRequest::RestrictToSameOrigin &&
650 !securityOrigin->canRequest(url)) { 646 !securityOrigin->canRequest(url)) {
651 printAccessDeniedMessage(url); 647 printAccessDeniedMessage(url);
652 return ResourceRequestBlockedReasonOrigin; 648 return ResourceRequestBlockedReason::Origin;
653 } 649 }
654 break; 650 break;
655 case Resource::XSLStyleSheet: 651 case Resource::XSLStyleSheet:
656 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); 652 DCHECK(RuntimeEnabledFeatures::xsltEnabled());
657 case Resource::SVGDocument: 653 case Resource::SVGDocument:
658 if (!securityOrigin->canRequest(url)) { 654 if (!securityOrigin->canRequest(url)) {
659 printAccessDeniedMessage(url); 655 printAccessDeniedMessage(url);
660 return ResourceRequestBlockedReasonOrigin; 656 return ResourceRequestBlockedReason::Origin;
661 } 657 }
662 break; 658 break;
663 } 659 }
664 660
665 // FIXME: Convert this to check the isolated world's Content Security Policy 661 // FIXME: Convert this to check the isolated world's Content Security Policy
666 // once webkit.org/b/104520 is solved. 662 // once webkit.org/b/104520 is solved.
667 bool shouldBypassMainWorldCSP = 663 bool shouldBypassMainWorldCSP =
668 frame()->script().shouldBypassMainWorldCSP() || 664 frame()->script().shouldBypassMainWorldCSP() ||
669 options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy; 665 options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy;
670 666
671 // Don't send CSP messages for preloads, we might never actually display those 667 // Don't send CSP messages for preloads, we might never actually display those
672 // items. 668 // items.
673 ContentSecurityPolicy::ReportingStatus cspReporting = 669 ContentSecurityPolicy::ReportingStatus cspReporting =
674 forPreload ? ContentSecurityPolicy::SuppressReport 670 forPreload ? ContentSecurityPolicy::SuppressReport
675 : ContentSecurityPolicy::SendReport; 671 : ContentSecurityPolicy::SendReport;
676 672
677 if (m_document) { 673 if (m_document) {
678 DCHECK(m_document->contentSecurityPolicy()); 674 DCHECK(m_document->contentSecurityPolicy());
679 if (!shouldBypassMainWorldCSP && 675 if (!shouldBypassMainWorldCSP &&
680 !m_document->contentSecurityPolicy()->allowRequest( 676 !m_document->contentSecurityPolicy()->allowRequest(
681 resourceRequest.requestContext(), url, 677 resourceRequest.requestContext(), url,
682 options.contentSecurityPolicyNonce, options.integrityMetadata, 678 options.contentSecurityPolicyNonce, options.integrityMetadata,
683 options.parserDisposition, redirectStatus, cspReporting)) 679 options.parserDisposition, redirectStatus, cspReporting))
684 return ResourceRequestBlockedReasonCSP; 680 return ResourceRequestBlockedReason::CSP;
685 } 681 }
686 682
687 if (type == Resource::Script || type == Resource::ImportResource) { 683 if (type == Resource::Script || type == Resource::ImportResource) {
688 DCHECK(frame()); 684 DCHECK(frame());
689 if (!frame()->loader().client()->allowScriptFromSource( 685 if (!frame()->loader().client()->allowScriptFromSource(
690 !frame()->settings() || frame()->settings()->scriptEnabled(), 686 !frame()->settings() || frame()->settings()->scriptEnabled(),
691 url)) { 687 url)) {
692 frame()->loader().client()->didNotAllowScript(); 688 frame()->loader().client()->didNotAllowScript();
693 // TODO(estark): Use a different ResourceRequestBlockedReason here, since 689 // TODO(estark): Use a different ResourceRequestBlockedReason here, since
694 // this check has nothing to do with CSP. https://crbug.com/600795 690 // this check has nothing to do with CSP. https://crbug.com/600795
695 return ResourceRequestBlockedReasonCSP; 691 return ResourceRequestBlockedReason::CSP;
696 } 692 }
697 } else if (type == Resource::Media || type == Resource::TextTrack) { 693 } else if (type == Resource::Media || type == Resource::TextTrack) {
698 DCHECK(frame()); 694 DCHECK(frame());
699 if (!frame()->loader().client()->allowMedia(url)) 695 if (!frame()->loader().client()->allowMedia(url))
700 return ResourceRequestBlockedReasonOther; 696 return ResourceRequestBlockedReason::Other;
701 } 697 }
702 698
703 // SVG Images have unique security rules that prevent all subresource requests 699 // SVG Images have unique security rules that prevent all subresource requests
704 // except for data urls. 700 // except for data urls.
705 if (type != Resource::MainResource && 701 if (type != Resource::MainResource &&
706 frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData()) 702 frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData())
707 return ResourceRequestBlockedReasonOrigin; 703 return ResourceRequestBlockedReason::Origin;
708 704
709 // Measure the number of legacy URL schemes ('ftp://') and the number of 705 // Measure the number of legacy URL schemes ('ftp://') and the number of
710 // embedded-credential ('http://user:password@...') resources embedded as 706 // embedded-credential ('http://user:password@...') resources embedded as
711 // subresources. in the hopes that we can block them at some point in the 707 // subresources. in the hopes that we can block them at some point in the
712 // future. 708 // future.
713 if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) { 709 if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) {
714 DCHECK(frame()->document()); 710 DCHECK(frame()->document());
715 if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && 711 if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) &&
716 !SchemeRegistry::shouldTreatURLSchemeAsLegacy( 712 !SchemeRegistry::shouldTreatURLSchemeAsLegacy(
717 frame()->document()->getSecurityOrigin()->protocol())) { 713 frame()->document()->getSecurityOrigin()->protocol())) {
718 UseCounter::count(frame()->document(), 714 UseCounter::count(frame()->document(),
719 UseCounter::LegacyProtocolEmbeddedAsSubresource); 715 UseCounter::LegacyProtocolEmbeddedAsSubresource);
720 } 716 }
721 if (!url.user().isEmpty() || !url.pass().isEmpty()) { 717 if (!url.user().isEmpty() || !url.pass().isEmpty()) {
722 UseCounter::count( 718 UseCounter::count(
723 frame()->document(), 719 frame()->document(),
724 UseCounter::RequestedSubresourceWithEmbeddedCredentials); 720 UseCounter::RequestedSubresourceWithEmbeddedCredentials);
725 } 721 }
726 } 722 }
727 723
728 // Check for mixed content. We do this second-to-last so that when folks block 724 // Check for mixed content. We do this second-to-last so that when folks block
729 // mixed content with a CSP policy, they don't get a warning. They'll still 725 // mixed content with a CSP policy, they don't get a warning. They'll still
730 // get a warning in the console about CSP blocking the load. 726 // get a warning in the console about CSP blocking the load.
731 MixedContentChecker::ReportingStatus mixedContentReporting = 727 MixedContentChecker::ReportingStatus mixedContentReporting =
732 forPreload ? MixedContentChecker::SuppressReport 728 forPreload ? MixedContentChecker::SuppressReport
733 : MixedContentChecker::SendReport; 729 : MixedContentChecker::SendReport;
734 if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url, 730 if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url,
735 mixedContentReporting)) 731 mixedContentReporting))
736 return ResourceRequestBlockedReasonMixedContent; 732 return ResourceRequestBlockedReason::MixedContent;
737 733
738 // Let the client have the final say into whether or not the load should 734 // Let the client have the final say into whether or not the load should
739 // proceed. 735 // proceed.
740 DocumentLoader* documentLoader = masterDocumentLoader(); 736 DocumentLoader* documentLoader = masterDocumentLoader();
741 if (documentLoader && documentLoader->subresourceFilter() && 737 if (documentLoader && documentLoader->subresourceFilter() &&
742 type != Resource::MainResource && type != Resource::ImportResource && 738 type != Resource::MainResource && type != Resource::ImportResource &&
743 !documentLoader->subresourceFilter()->allowLoad( 739 !documentLoader->subresourceFilter()->allowLoad(
744 url, resourceRequest.requestContext())) 740 url, resourceRequest.requestContext()))
745 return ResourceRequestBlockedReasonSubresourceFilter; 741 return ResourceRequestBlockedReason::SubresourceFilter;
746 742
747 return ResourceRequestBlockedReasonNone; 743 return ResourceRequestBlockedReason::None;
748 } 744 }
749 745
750 bool FrameFetchContext::isControlledByServiceWorker() const { 746 bool FrameFetchContext::isControlledByServiceWorker() const {
751 DCHECK(m_documentLoader || frame()->loader().documentLoader()); 747 DCHECK(m_documentLoader || frame()->loader().documentLoader());
752 748
753 // Service workers are bypassed by suborigins (see 749 // Service workers are bypassed by suborigins (see
754 // https://w3c.github.io/webappsec-suborigins/). Since service worker 750 // https://w3c.github.io/webappsec-suborigins/). Since service worker
755 // controllers are assigned based on physical origin, without knowledge of 751 // controllers are assigned based on physical origin, without knowledge of
756 // whether the context is in a suborigin, it is necessary to explicitly bypass 752 // whether the context is in a suborigin, it is necessary to explicitly bypass
757 // service workers on a per-request basis. Additionally, it is necessary to 753 // service workers on a per-request basis. Additionally, it is necessary to
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 response); 1000 response);
1005 } 1001 }
1006 1002
1007 DEFINE_TRACE(FrameFetchContext) { 1003 DEFINE_TRACE(FrameFetchContext) {
1008 visitor->trace(m_document); 1004 visitor->trace(m_document);
1009 visitor->trace(m_documentLoader); 1005 visitor->trace(m_documentLoader);
1010 FetchContext::trace(visitor); 1006 FetchContext::trace(visitor);
1011 } 1007 }
1012 1008
1013 } // namespace blink 1009 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698