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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 type, resource_request, url, options, reporting_policy, | 679 type, resource_request, url, options, reporting_policy, |
680 origin_restriction, resource_request.GetRedirectStatus()); | 680 origin_restriction, resource_request.GetRedirectStatus()); |
681 if (blocked_reason != ResourceRequestBlockedReason::kNone && | 681 if (blocked_reason != ResourceRequestBlockedReason::kNone && |
682 reporting_policy == SecurityViolationReportingPolicy::kReport) { | 682 reporting_policy == SecurityViolationReportingPolicy::kReport) { |
683 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), | 683 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), |
684 options.initiator_info, blocked_reason); | 684 options.initiator_info, blocked_reason); |
685 } | 685 } |
686 return blocked_reason; | 686 return blocked_reason; |
687 } | 687 } |
688 | 688 |
| 689 ResourceRequestBlockedReason FrameFetchContext::CanFollowRedirect( |
| 690 Resource::Type type, |
| 691 const ResourceRequest& resource_request, |
| 692 const KURL& url, |
| 693 const ResourceLoaderOptions& options, |
| 694 SecurityViolationReportingPolicy reporting_policy, |
| 695 FetchParameters::OriginRestriction origin_restriction) const { |
| 696 // CanRequestInternal checks enforced CSP, so check report-only here to ensure |
| 697 // that violations are sent. |
| 698 CheckCSPForRequest(resource_request, url, options, reporting_policy, |
| 699 RedirectStatus::kFollowedRedirect, |
| 700 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); |
| 701 return CanRequest(type, resource_request, url, options, reporting_policy, |
| 702 origin_restriction); |
| 703 } |
| 704 |
689 ResourceRequestBlockedReason FrameFetchContext::AllowResponse( | 705 ResourceRequestBlockedReason FrameFetchContext::AllowResponse( |
690 Resource::Type type, | 706 Resource::Type type, |
691 const ResourceRequest& resource_request, | 707 const ResourceRequest& resource_request, |
692 const KURL& url, | 708 const KURL& url, |
693 const ResourceLoaderOptions& options) const { | 709 const ResourceLoaderOptions& options) const { |
| 710 // canRequestInternal only checks enforced policies: check report-only here |
| 711 // to ensure violations are sent. |
| 712 CheckCSPForRequest(resource_request, url, options, |
| 713 SecurityViolationReportingPolicy::kReport, |
| 714 RedirectStatus::kFollowedRedirect, |
| 715 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); |
694 ResourceRequestBlockedReason blocked_reason = | 716 ResourceRequestBlockedReason blocked_reason = |
695 CanRequestInternal(type, resource_request, url, options, | 717 CanRequestInternal(type, resource_request, url, options, |
696 SecurityViolationReportingPolicy::kReport, | 718 SecurityViolationReportingPolicy::kReport, |
697 FetchParameters::kUseDefaultOriginRestrictionForType, | 719 FetchParameters::kUseDefaultOriginRestrictionForType, |
698 RedirectStatus::kFollowedRedirect); | 720 RedirectStatus::kFollowedRedirect); |
699 if (blocked_reason != ResourceRequestBlockedReason::kNone) { | 721 if (blocked_reason != ResourceRequestBlockedReason::kNone) { |
700 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), | 722 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), |
701 options.initiator_info, blocked_reason); | 723 options.initiator_info, blocked_reason); |
702 } | 724 } |
703 return blocked_reason; | 725 return blocked_reason; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 case Resource::kXSLStyleSheet: | 779 case Resource::kXSLStyleSheet: |
758 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); | 780 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); |
759 case Resource::kSVGDocument: | 781 case Resource::kSVGDocument: |
760 if (!security_origin->CanRequest(url)) { | 782 if (!security_origin->CanRequest(url)) { |
761 PrintAccessDeniedMessage(url); | 783 PrintAccessDeniedMessage(url); |
762 return ResourceRequestBlockedReason::kOrigin; | 784 return ResourceRequestBlockedReason::kOrigin; |
763 } | 785 } |
764 break; | 786 break; |
765 } | 787 } |
766 | 788 |
767 // FIXME: Convert this to check the isolated world's Content Security Policy | 789 // We check the 'report-only' headers before upgrading the request (in |
768 // once webkit.org/b/104520 is solved. | 790 // populateResourceRequest). We check the enforced headers here to ensure we |
769 bool should_bypass_main_world_csp = | 791 // block things we ought to block. |
770 GetFrame()->GetScriptController().ShouldBypassMainWorldCSP() || | 792 if (CheckCSPForRequest( |
771 options.content_security_policy_option == | 793 resource_request, url, options, reporting_policy, redirect_status, |
772 kDoNotCheckContentSecurityPolicy; | 794 ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) == |
773 | 795 ResourceRequestBlockedReason::CSP) { |
774 if (document_) { | 796 return ResourceRequestBlockedReason::CSP; |
775 DCHECK(document_->GetContentSecurityPolicy()); | |
776 if (!should_bypass_main_world_csp && | |
777 !document_->GetContentSecurityPolicy()->AllowRequest( | |
778 resource_request.GetRequestContext(), url, | |
779 options.content_security_policy_nonce, options.integrity_metadata, | |
780 options.parser_disposition, redirect_status, reporting_policy)) | |
781 return ResourceRequestBlockedReason::CSP; | |
782 } | 797 } |
783 | 798 |
784 if (type == Resource::kScript || type == Resource::kImportResource) { | 799 if (type == Resource::kScript || type == Resource::kImportResource) { |
785 DCHECK(GetFrame()); | 800 DCHECK(GetFrame()); |
786 if (!GetContentSettingsClient()->AllowScriptFromSource( | 801 if (!GetContentSettingsClient()->AllowScriptFromSource( |
787 !GetFrame()->GetSettings() || | 802 !GetFrame()->GetSettings() || |
788 GetFrame()->GetSettings()->GetScriptEnabled(), | 803 GetFrame()->GetSettings()->GetScriptEnabled(), |
789 url)) { | 804 url)) { |
790 GetContentSettingsClient()->DidNotAllowScript(); | 805 GetContentSettingsClient()->DidNotAllowScript(); |
791 // TODO(estark): Use a different ResourceRequestBlockedReason here, since | 806 // TODO(estark): Use a different ResourceRequestBlockedReason here, since |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 type != Resource::kMainResource && type != Resource::kImportResource) { | 874 type != Resource::kMainResource && type != Resource::kImportResource) { |
860 if (!document_loader->GetSubresourceFilter()->AllowLoad( | 875 if (!document_loader->GetSubresourceFilter()->AllowLoad( |
861 url, resource_request.GetRequestContext(), reporting_policy)) { | 876 url, resource_request.GetRequestContext(), reporting_policy)) { |
862 return ResourceRequestBlockedReason::kSubresourceFilter; | 877 return ResourceRequestBlockedReason::kSubresourceFilter; |
863 } | 878 } |
864 } | 879 } |
865 | 880 |
866 return ResourceRequestBlockedReason::kNone; | 881 return ResourceRequestBlockedReason::kNone; |
867 } | 882 } |
868 | 883 |
| 884 ResourceRequestBlockedReason FrameFetchContext::CheckCSPForRequest( |
| 885 const ResourceRequest& resource_request, |
| 886 const KURL& url, |
| 887 const ResourceLoaderOptions& options, |
| 888 SecurityViolationReportingPolicy reporting_policy, |
| 889 ResourceRequest::RedirectStatus redirect_status, |
| 890 ContentSecurityPolicy::CheckHeaderType check_header_type) const { |
| 891 if (GetFrame()->GetScriptController().ShouldBypassMainWorldCSP() || |
| 892 options.content_security_policy_option == |
| 893 kDoNotCheckContentSecurityPolicy) { |
| 894 return ResourceRequestBlockedReason::kNone; |
| 895 } |
| 896 |
| 897 if (document_) { |
| 898 DCHECK(document_->GetContentSecurityPolicy()); |
| 899 if (!document_->GetContentSecurityPolicy()->AllowRequest( |
| 900 resource_request.GetRequestContext(), url, |
| 901 options.content_security_policy_nonce, options.integrity_metadata, |
| 902 options.parser_disposition, redirect_status, reporting_policy, |
| 903 check_header_type)) |
| 904 return ResourceRequestBlockedReason::CSP; |
| 905 } |
| 906 return ResourceRequestBlockedReason::kNone; |
| 907 } |
| 908 |
869 bool FrameFetchContext::IsControlledByServiceWorker() const { | 909 bool FrameFetchContext::IsControlledByServiceWorker() const { |
870 DCHECK(MasterDocumentLoader()); | 910 DCHECK(MasterDocumentLoader()); |
871 | 911 |
872 // Service workers are bypassed by suborigins (see | 912 // Service workers are bypassed by suborigins (see |
873 // https://w3c.github.io/webappsec-suborigins/). Since service worker | 913 // https://w3c.github.io/webappsec-suborigins/). Since service worker |
874 // controllers are assigned based on physical origin, without knowledge of | 914 // controllers are assigned based on physical origin, without knowledge of |
875 // whether the context is in a suborigin, it is necessary to explicitly bypass | 915 // whether the context is in a suborigin, it is necessary to explicitly bypass |
876 // service workers on a per-request basis. Additionally, it is necessary to | 916 // service workers on a per-request basis. Additionally, it is necessary to |
877 // explicitly return |false| here so that it is clear that the SW will be | 917 // explicitly return |false| here so that it is clear that the SW will be |
878 // bypassed. In particular, this is important for | 918 // bypassed. In particular, this is important for |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 ResourceRequest& request) { | 1039 ResourceRequest& request) { |
1000 if (!document_) | 1040 if (!document_) |
1001 return; | 1041 return; |
1002 | 1042 |
1003 const ContentSecurityPolicy* csp = document_->GetContentSecurityPolicy(); | 1043 const ContentSecurityPolicy* csp = document_->GetContentSecurityPolicy(); |
1004 if (csp->ShouldSendCSPHeader(type)) | 1044 if (csp->ShouldSendCSPHeader(type)) |
1005 request.AddHTTPHeaderField("CSP", "active"); | 1045 request.AddHTTPHeaderField("CSP", "active"); |
1006 } | 1046 } |
1007 | 1047 |
1008 void FrameFetchContext::PopulateResourceRequest( | 1048 void FrameFetchContext::PopulateResourceRequest( |
| 1049 const KURL& url, |
1009 Resource::Type type, | 1050 Resource::Type type, |
1010 const ClientHintsPreferences& hints_preferences, | 1051 const ClientHintsPreferences& hints_preferences, |
1011 const FetchParameters::ResourceWidth& resource_width, | 1052 const FetchParameters::ResourceWidth& resource_width, |
| 1053 const ResourceLoaderOptions& options, |
| 1054 SecurityViolationReportingPolicy reporting_policy, |
1012 ResourceRequest& request) { | 1055 ResourceRequest& request) { |
1013 SetFirstPartyCookieAndRequestorOrigin(request); | 1056 SetFirstPartyCookieAndRequestorOrigin(request); |
| 1057 |
| 1058 // Before modifying the request for CSP, evaluate report-only headers. This |
| 1059 // allows site owners to learn about requests that are being modified |
| 1060 // (e.g. mixed content that is being upgraded by upgrade-insecure-requests). |
| 1061 CheckCSPForRequest(request, url, options, reporting_policy, |
| 1062 request.GetRedirectStatus(), |
| 1063 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); |
| 1064 |
1014 ModifyRequestForCSP(request); | 1065 ModifyRequestForCSP(request); |
1015 AddClientHintsIfNecessary(hints_preferences, resource_width, request); | 1066 AddClientHintsIfNecessary(hints_preferences, resource_width, request); |
1016 AddCSPHeaderIfNecessary(type, request); | 1067 AddCSPHeaderIfNecessary(type, request); |
1017 } | 1068 } |
1018 | 1069 |
1019 void FrameFetchContext::SetFirstPartyCookieAndRequestorOrigin( | 1070 void FrameFetchContext::SetFirstPartyCookieAndRequestorOrigin( |
1020 ResourceRequest& request) { | 1071 ResourceRequest& request) { |
1021 if (!document_) | 1072 if (!document_) |
1022 return; | 1073 return; |
1023 | 1074 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 return GetFrame()->FrameScheduler()->LoadingTaskRunner(); | 1126 return GetFrame()->FrameScheduler()->LoadingTaskRunner(); |
1076 } | 1127 } |
1077 | 1128 |
1078 DEFINE_TRACE(FrameFetchContext) { | 1129 DEFINE_TRACE(FrameFetchContext) { |
1079 visitor->Trace(document_); | 1130 visitor->Trace(document_); |
1080 visitor->Trace(document_loader_); | 1131 visitor->Trace(document_loader_); |
1081 FetchContext::Trace(visitor); | 1132 FetchContext::Trace(visitor); |
1082 } | 1133 } |
1083 | 1134 |
1084 } // namespace blink | 1135 } // namespace blink |
OLD | NEW |