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

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

Issue 2823213002: Implement CanRequest in BaseFetchContext (Closed)
Patch Set: rebase, tests Created 3 years, 8 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) 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 330
331 LocalFrame* frame = document_loader_->GetFrame(); 331 LocalFrame* frame = document_loader_->GetFrame();
332 DCHECK(frame); 332 DCHECK(frame);
333 return frame; 333 return frame;
334 } 334 }
335 335
336 LocalFrameClient* FrameFetchContext::GetLocalFrameClient() const { 336 LocalFrameClient* FrameFetchContext::GetLocalFrameClient() const {
337 return GetFrame()->Client(); 337 return GetFrame()->Client();
338 } 338 }
339 339
340 ContentSettingsClient* FrameFetchContext::GetContentSettingsClient() const {
341 return GetFrame()->GetContentSettingsClient();
342 }
343
344 void FrameFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request, 340 void FrameFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request,
345 FetchResourceType type) { 341 FetchResourceType type) {
346 BaseFetchContext::AddAdditionalRequestHeaders(request, type); 342 BaseFetchContext::AddAdditionalRequestHeaders(request, type);
347 343
348 // The remaining modifications are only necessary for HTTP and HTTPS. 344 // The remaining modifications are only necessary for HTTP and HTTPS.
349 if (!request.Url().IsEmpty() && !request.Url().ProtocolIsInHTTPFamily()) 345 if (!request.Url().IsEmpty() && !request.Url().ProtocolIsInHTTPFamily())
350 return; 346 return;
351 347
352 // Reload should reflect the current data saver setting. 348 // Reload should reflect the current data saver setting.
353 if (IsReloadLoadType(MasterDocumentLoader()->LoadType())) 349 if (IsReloadLoadType(MasterDocumentLoader()->LoadType()))
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 if (!initiator_document || !initiator_document->domWindow()) 625 if (!initiator_document || !initiator_document->domWindow())
630 return; 626 return;
631 DOMWindowPerformance::performance(*initiator_document->domWindow()) 627 DOMWindowPerformance::performance(*initiator_document->domWindow())
632 ->AddResourceTiming(info); 628 ->AddResourceTiming(info);
633 } 629 }
634 630
635 bool FrameFetchContext::AllowImage(bool images_enabled, const KURL& url) const { 631 bool FrameFetchContext::AllowImage(bool images_enabled, const KURL& url) const {
636 return GetContentSettingsClient()->AllowImage(images_enabled, url); 632 return GetContentSettingsClient()->AllowImage(images_enabled, url);
637 } 633 }
638 634
639 ResourceRequestBlockedReason FrameFetchContext::CanRequest(
640 Resource::Type type,
641 const ResourceRequest& resource_request,
642 const KURL& url,
643 const ResourceLoaderOptions& options,
644 SecurityViolationReportingPolicy reporting_policy,
645 FetchParameters::OriginRestriction origin_restriction) const {
646 ResourceRequestBlockedReason blocked_reason = CanRequestInternal(
647 type, resource_request, url, options, reporting_policy,
648 origin_restriction, resource_request.GetRedirectStatus());
649 if (blocked_reason != ResourceRequestBlockedReason::kNone &&
650 reporting_policy == SecurityViolationReportingPolicy::kReport) {
651 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(),
652 options.initiator_info, blocked_reason);
653 }
654 return blocked_reason;
655 }
656
657 ResourceRequestBlockedReason FrameFetchContext::CanFollowRedirect(
658 Resource::Type type,
659 const ResourceRequest& resource_request,
660 const KURL& url,
661 const ResourceLoaderOptions& options,
662 SecurityViolationReportingPolicy reporting_policy,
663 FetchParameters::OriginRestriction origin_restriction) const {
664 // CanRequestInternal checks enforced CSP, so check report-only here to ensure
665 // that violations are sent.
666 CheckCSPForRequest(resource_request, url, options, reporting_policy,
667 RedirectStatus::kFollowedRedirect,
668 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly);
669 return CanRequest(type, resource_request, url, options, reporting_policy,
670 origin_restriction);
671 }
672
673 ResourceRequestBlockedReason FrameFetchContext::AllowResponse(
674 Resource::Type type,
675 const ResourceRequest& resource_request,
676 const KURL& url,
677 const ResourceLoaderOptions& options) const {
678 // canRequestInternal only checks enforced policies: check report-only here
679 // to ensure violations are sent.
680 CheckCSPForRequest(resource_request, url, options,
681 SecurityViolationReportingPolicy::kReport,
682 RedirectStatus::kFollowedRedirect,
683 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly);
684 ResourceRequestBlockedReason blocked_reason =
685 CanRequestInternal(type, resource_request, url, options,
686 SecurityViolationReportingPolicy::kReport,
687 FetchParameters::kUseDefaultOriginRestrictionForType,
688 RedirectStatus::kFollowedRedirect);
689 if (blocked_reason != ResourceRequestBlockedReason::kNone) {
690 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(),
691 options.initiator_info, blocked_reason);
692 }
693 return blocked_reason;
694 }
695
696 ResourceRequestBlockedReason FrameFetchContext::CanRequestInternal(
697 Resource::Type type,
698 const ResourceRequest& resource_request,
699 const KURL& url,
700 const ResourceLoaderOptions& options,
701 SecurityViolationReportingPolicy reporting_policy,
702 FetchParameters::OriginRestriction origin_restriction,
703 ResourceRequest::RedirectStatus redirect_status) const {
704 bool should_block_request = false;
705 probe::shouldBlockRequest(GetFrame(), resource_request,
706 &should_block_request);
707 if (should_block_request)
708 return ResourceRequestBlockedReason::kInspector;
709
710 SecurityOrigin* security_origin = options.security_origin.Get();
711 if (!security_origin && execution_context_)
712 security_origin = execution_context_->GetSecurityOrigin();
713
714 if (origin_restriction != FetchParameters::kNoOriginRestriction &&
715 security_origin && !security_origin->CanDisplay(url)) {
716 if (reporting_policy == SecurityViolationReportingPolicy::kReport)
717 FrameLoader::ReportLocalLoadFailed(GetFrame(), url.ElidedString());
718 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not "
719 "allowed by SecurityOrigin::canDisplay";
720 return ResourceRequestBlockedReason::kOther;
721 }
722
723 // Some types of resources can be loaded only from the same origin. Other
724 // types of resources, like Images, Scripts, and CSS, can be loaded from
725 // any URL.
726 switch (type) {
727 case Resource::kMainResource:
728 case Resource::kImage:
729 case Resource::kCSSStyleSheet:
730 case Resource::kScript:
731 case Resource::kFont:
732 case Resource::kRaw:
733 case Resource::kLinkPrefetch:
734 case Resource::kTextTrack:
735 case Resource::kImportResource:
736 case Resource::kMedia:
737 case Resource::kManifest:
738 case Resource::kMock:
739 // By default these types of resources can be loaded from any origin.
740 // FIXME: Are we sure about Resource::Font?
741 if (origin_restriction == FetchParameters::kRestrictToSameOrigin &&
742 !security_origin->CanRequest(url)) {
743 PrintAccessDeniedMessage(url);
744 return ResourceRequestBlockedReason::kOrigin;
745 }
746 break;
747 case Resource::kXSLStyleSheet:
748 DCHECK(RuntimeEnabledFeatures::xsltEnabled());
749 case Resource::kSVGDocument:
750 if (!security_origin->CanRequest(url)) {
751 PrintAccessDeniedMessage(url);
752 return ResourceRequestBlockedReason::kOrigin;
753 }
754 break;
755 }
756
757 // We check the 'report-only' headers before upgrading the request (in
758 // populateResourceRequest). We check the enforced headers here to ensure we
759 // block things we ought to block.
760 if (CheckCSPForRequest(
761 resource_request, url, options, reporting_policy, redirect_status,
762 ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) ==
763 ResourceRequestBlockedReason::CSP) {
764 return ResourceRequestBlockedReason::CSP;
765 }
766
767 if (type == Resource::kScript || type == Resource::kImportResource) {
768 DCHECK(GetFrame());
769 if (!GetContentSettingsClient()->AllowScriptFromSource(
770 !GetFrame()->GetSettings() ||
771 GetFrame()->GetSettings()->GetScriptEnabled(),
772 url)) {
773 GetContentSettingsClient()->DidNotAllowScript();
774 // TODO(estark): Use a different ResourceRequestBlockedReason here, since
775 // this check has nothing to do with CSP. https://crbug.com/600795
776 return ResourceRequestBlockedReason::CSP;
777 }
778 }
779
780 // SVG Images have unique security rules that prevent all subresource requests
781 // except for data urls.
782 if (type != Resource::kMainResource &&
783 GetFrame()->GetChromeClient().IsSVGImageChromeClient() &&
784 !url.ProtocolIsData())
785 return ResourceRequestBlockedReason::kOrigin;
786
787 // Measure the number of legacy URL schemes ('ftp://') and the number of
788 // embedded-credential ('http://user:password@...') resources embedded as
789 // subresources.
790 if (resource_request.GetFrameType() != WebURLRequest::kFrameTypeTopLevel) {
791 DCHECK(GetFrame()->GetDocument());
792 if (SchemeRegistry::ShouldTreatURLSchemeAsLegacy(url.Protocol()) &&
793 !SchemeRegistry::ShouldTreatURLSchemeAsLegacy(
794 GetFrame()->GetDocument()->GetSecurityOrigin()->Protocol())) {
795 Deprecation::CountDeprecation(
796 GetFrame()->GetDocument(),
797 UseCounter::kLegacyProtocolEmbeddedAsSubresource);
798
799 // TODO(mkwst): Enabled by default in M59. Drop the runtime-enabled check
800 // in M60: https://www.chromestatus.com/feature/5709390967472128
801 if (RuntimeEnabledFeatures::blockLegacySubresourcesEnabled())
802 return ResourceRequestBlockedReason::kOrigin;
803 }
804
805 if ((!url.User().IsEmpty() || !url.Pass().IsEmpty()) &&
806 resource_request.GetRequestContext() !=
807 WebURLRequest::kRequestContextXMLHttpRequest) {
808 Deprecation::CountDeprecation(
809 GetFrame()->GetDocument(),
810 UseCounter::kRequestedSubresourceWithEmbeddedCredentials);
811 // TODO(mkwst): Remove the runtime-enabled check in M59:
812 // https://www.chromestatus.com/feature/5669008342777856
813 if (RuntimeEnabledFeatures::blockCredentialedSubresourcesEnabled())
814 return ResourceRequestBlockedReason::kOrigin;
815 }
816 }
817
818 // Check for mixed content. We do this second-to-last so that when folks block
819 // mixed content with a CSP policy, they don't get a warning. They'll still
820 // get a warning in the console about CSP blocking the load.
821 if (MixedContentChecker::ShouldBlockFetch(GetFrame(), resource_request, url,
822 reporting_policy))
823 return ResourceRequestBlockedReason::kMixedContent;
824
825 if (url.WhitespaceRemoved()) {
826 Deprecation::CountDeprecation(
827 GetFrame()->GetDocument(),
828 UseCounter::kCanRequestURLHTTPContainingNewline);
829 if (url.ProtocolIsInHTTPFamily()) {
830 if (RuntimeEnabledFeatures::restrictCanRequestURLCharacterSetEnabled())
831 return ResourceRequestBlockedReason::kOther;
832 } else {
833 UseCounter::Count(GetFrame()->GetDocument(),
834 UseCounter::kCanRequestURLNonHTTPContainingNewline);
835 }
836 }
837
838 // Let the client have the final say into whether or not the load should
839 // proceed.
840 DocumentLoader* document_loader = MasterDocumentLoader();
841 if (document_loader && document_loader->GetSubresourceFilter() &&
842 type != Resource::kMainResource && type != Resource::kImportResource) {
843 if (!document_loader->GetSubresourceFilter()->AllowLoad(
844 url, resource_request.GetRequestContext(), reporting_policy)) {
845 return ResourceRequestBlockedReason::kSubresourceFilter;
846 }
847 }
848
849 return ResourceRequestBlockedReason::kNone;
850 }
851
852 ResourceRequestBlockedReason FrameFetchContext::CheckCSPForRequest(
853 const ResourceRequest& resource_request,
854 const KURL& url,
855 const ResourceLoaderOptions& options,
856 SecurityViolationReportingPolicy reporting_policy,
857 ResourceRequest::RedirectStatus redirect_status,
858 ContentSecurityPolicy::CheckHeaderType check_header_type) const {
859 if (GetFrame()->GetScriptController().ShouldBypassMainWorldCSP() ||
860 options.content_security_policy_option ==
861 kDoNotCheckContentSecurityPolicy) {
862 return ResourceRequestBlockedReason::kNone;
863 }
864
865 if (execution_context_) {
866 DCHECK(execution_context_->GetContentSecurityPolicy());
867 if (!execution_context_->GetContentSecurityPolicy()->AllowRequest(
868 resource_request.GetRequestContext(), url,
869 options.content_security_policy_nonce, options.integrity_metadata,
870 options.parser_disposition, redirect_status, reporting_policy,
871 check_header_type))
872 return ResourceRequestBlockedReason::CSP;
873 }
874 return ResourceRequestBlockedReason::kNone;
875 }
876
877 bool FrameFetchContext::IsControlledByServiceWorker() const { 635 bool FrameFetchContext::IsControlledByServiceWorker() const {
878 DCHECK(MasterDocumentLoader()); 636 DCHECK(MasterDocumentLoader());
879 637
880 // Service workers are bypassed by suborigins (see 638 // Service workers are bypassed by suborigins (see
881 // https://w3c.github.io/webappsec-suborigins/). Since service worker 639 // https://w3c.github.io/webappsec-suborigins/). Since service worker
882 // controllers are assigned based on physical origin, without knowledge of 640 // controllers are assigned based on physical origin, without knowledge of
883 // whether the context is in a suborigin, it is necessary to explicitly bypass 641 // whether the context is in a suborigin, it is necessary to explicitly bypass
884 // service workers on a per-request basis. Additionally, it is necessary to 642 // service workers on a per-request basis. Additionally, it is necessary to
885 // explicitly return |false| here so that it is clear that the SW will be 643 // explicitly return |false| here so that it is clear that the SW will be
886 // bypassed. In particular, this is important for 644 // bypassed. In particular, this is important for
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 !GetFrame()->IsMainFrame()) 832 !GetFrame()->IsMainFrame())
1075 return kResourceLoadPriorityVeryLow; 833 return kResourceLoadPriorityVeryLow;
1076 834
1077 return priority; 835 return priority;
1078 } 836 }
1079 837
1080 RefPtr<WebTaskRunner> FrameFetchContext::LoadingTaskRunner() const { 838 RefPtr<WebTaskRunner> FrameFetchContext::LoadingTaskRunner() const {
1081 return GetFrame()->FrameScheduler()->LoadingTaskRunner(); 839 return GetFrame()->FrameScheduler()->LoadingTaskRunner();
1082 } 840 }
1083 841
842 ContentSettingsClient* FrameFetchContext::GetContentSettingsClient() const {
843 return GetFrame()->GetContentSettingsClient();
844 }
845
846 Settings* FrameFetchContext::GetSettings() const {
847 DCHECK(GetFrame());
848 return GetFrame()->GetSettings();
849 }
850
851 SubresourceFilter* FrameFetchContext::GetSubresourceFilter() const {
852 DocumentLoader* document_loader = MasterDocumentLoader();
853 return document_loader ? document_loader->GetSubresourceFilter() : nullptr;
854 }
855
856 SecurityContext* FrameFetchContext::GetMainResourceSecurityContext() const {
857 DCHECK(GetFrame()->GetDocument());
858 return GetFrame()->GetDocument();
859 }
860
861 bool FrameFetchContext::ShouldBlockRequestByInspector(
862 const ResourceRequest& resource_request) const {
863 bool should_block_request = false;
864 probe::shouldBlockRequest(GetFrame(), resource_request,
865 &should_block_request);
866 return should_block_request;
867 }
868
869 void FrameFetchContext::DispatchDidBlockRequest(
870 const ResourceRequest& resource_request,
871 const FetchInitiatorInfo& fetch_initiator_info,
872 ResourceRequestBlockedReason blocked_reason) const {
873 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(),
874 fetch_initiator_info, blocked_reason);
875 }
876
877 void FrameFetchContext::ReportLocalLoadFailed(const KURL& url) const {
878 FrameLoader::ReportLocalLoadFailed(GetFrame(), url.ElidedString());
879 }
880
881 bool FrameFetchContext::ShouldBypassMainWorldCSP() const {
882 return GetFrame()->GetScriptController().ShouldBypassMainWorldCSP();
883 }
884
885 bool FrameFetchContext::IsSVGImageChromeClient() const {
886 return GetFrame()->GetChromeClient().IsSVGImageChromeClient();
887 }
888
889 void FrameFetchContext::CountUsage(UseCounter::Feature feature) const {
890 UseCounter::Count(GetFrame()->GetDocument(), feature);
891 }
892
893 void FrameFetchContext::CountDeprecation(UseCounter::Feature feature) const {
894 Deprecation::CountDeprecation(GetFrame()->GetDocument(), feature);
895 }
896
897 bool FrameFetchContext::ShouldBlockFetchByMixedContentCheck(
898 const ResourceRequest& resource_request,
899 const KURL& url,
900 SecurityViolationReportingPolicy reporting_policy) const {
901 return MixedContentChecker::ShouldBlockFetch(GetFrame(), resource_request,
902 url, reporting_policy);
903 }
904
1084 DEFINE_TRACE(FrameFetchContext) { 905 DEFINE_TRACE(FrameFetchContext) {
1085 visitor->Trace(document_loader_); 906 visitor->Trace(document_loader_);
1086 BaseFetchContext::Trace(visitor); 907 BaseFetchContext::Trace(visitor);
1087 } 908 }
1088 909
1089 } // namespace blink 910 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698