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

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

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

Powered by Google App Engine
This is Rietveld 408576698