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