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 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 type, resource_request, url, options, reporting_policy, | 647 type, resource_request, url, options, reporting_policy, |
648 origin_restriction, resource_request.GetRedirectStatus()); | 648 origin_restriction, resource_request.GetRedirectStatus()); |
649 if (blocked_reason != ResourceRequestBlockedReason::kNone && | 649 if (blocked_reason != ResourceRequestBlockedReason::kNone && |
650 reporting_policy == SecurityViolationReportingPolicy::kReport) { | 650 reporting_policy == SecurityViolationReportingPolicy::kReport) { |
651 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), | 651 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), |
652 options.initiator_info, blocked_reason); | 652 options.initiator_info, blocked_reason); |
653 } | 653 } |
654 return blocked_reason; | 654 return blocked_reason; |
655 } | 655 } |
656 | 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 |
657 ResourceRequestBlockedReason FrameFetchContext::AllowResponse( | 673 ResourceRequestBlockedReason FrameFetchContext::AllowResponse( |
658 Resource::Type type, | 674 Resource::Type type, |
659 const ResourceRequest& resource_request, | 675 const ResourceRequest& resource_request, |
660 const KURL& url, | 676 const KURL& url, |
661 const ResourceLoaderOptions& options) const { | 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); |
662 ResourceRequestBlockedReason blocked_reason = | 684 ResourceRequestBlockedReason blocked_reason = |
663 CanRequestInternal(type, resource_request, url, options, | 685 CanRequestInternal(type, resource_request, url, options, |
664 SecurityViolationReportingPolicy::kReport, | 686 SecurityViolationReportingPolicy::kReport, |
665 FetchParameters::kUseDefaultOriginRestrictionForType, | 687 FetchParameters::kUseDefaultOriginRestrictionForType, |
666 RedirectStatus::kFollowedRedirect); | 688 RedirectStatus::kFollowedRedirect); |
667 if (blocked_reason != ResourceRequestBlockedReason::kNone) { | 689 if (blocked_reason != ResourceRequestBlockedReason::kNone) { |
668 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), | 690 probe::didBlockRequest(GetFrame(), resource_request, MasterDocumentLoader(), |
669 options.initiator_info, blocked_reason); | 691 options.initiator_info, blocked_reason); |
670 } | 692 } |
671 return blocked_reason; | 693 return blocked_reason; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 case Resource::kXSLStyleSheet: | 747 case Resource::kXSLStyleSheet: |
726 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); | 748 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); |
727 case Resource::kSVGDocument: | 749 case Resource::kSVGDocument: |
728 if (!security_origin->CanRequest(url)) { | 750 if (!security_origin->CanRequest(url)) { |
729 PrintAccessDeniedMessage(url); | 751 PrintAccessDeniedMessage(url); |
730 return ResourceRequestBlockedReason::kOrigin; | 752 return ResourceRequestBlockedReason::kOrigin; |
731 } | 753 } |
732 break; | 754 break; |
733 } | 755 } |
734 | 756 |
735 // FIXME: Convert this to check the isolated world's Content Security Policy | 757 // We check the 'report-only' headers before upgrading the request (in |
736 // once webkit.org/b/104520 is solved. | 758 // populateResourceRequest). We check the enforced headers here to ensure we |
737 bool should_bypass_main_world_csp = | 759 // block things we ought to block. |
738 GetFrame()->GetScriptController().ShouldBypassMainWorldCSP() || | 760 if (CheckCSPForRequest( |
739 options.content_security_policy_option == | 761 resource_request, url, options, reporting_policy, redirect_status, |
740 kDoNotCheckContentSecurityPolicy; | 762 ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) == |
741 | 763 ResourceRequestBlockedReason::CSP) { |
742 if (execution_context_) { | 764 return ResourceRequestBlockedReason::CSP; |
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 } | 765 } |
751 | 766 |
752 if (type == Resource::kScript || type == Resource::kImportResource) { | 767 if (type == Resource::kScript || type == Resource::kImportResource) { |
753 DCHECK(GetFrame()); | 768 DCHECK(GetFrame()); |
754 if (!GetContentSettingsClient()->AllowScriptFromSource( | 769 if (!GetContentSettingsClient()->AllowScriptFromSource( |
755 !GetFrame()->GetSettings() || | 770 !GetFrame()->GetSettings() || |
756 GetFrame()->GetSettings()->GetScriptEnabled(), | 771 GetFrame()->GetSettings()->GetScriptEnabled(), |
757 url)) { | 772 url)) { |
758 GetContentSettingsClient()->DidNotAllowScript(); | 773 GetContentSettingsClient()->DidNotAllowScript(); |
759 // TODO(estark): Use a different ResourceRequestBlockedReason here, since | 774 // TODO(estark): Use a different ResourceRequestBlockedReason here, since |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 type != Resource::kMainResource && type != Resource::kImportResource) { | 842 type != Resource::kMainResource && type != Resource::kImportResource) { |
828 if (!document_loader->GetSubresourceFilter()->AllowLoad( | 843 if (!document_loader->GetSubresourceFilter()->AllowLoad( |
829 url, resource_request.GetRequestContext(), reporting_policy)) { | 844 url, resource_request.GetRequestContext(), reporting_policy)) { |
830 return ResourceRequestBlockedReason::kSubresourceFilter; | 845 return ResourceRequestBlockedReason::kSubresourceFilter; |
831 } | 846 } |
832 } | 847 } |
833 | 848 |
834 return ResourceRequestBlockedReason::kNone; | 849 return ResourceRequestBlockedReason::kNone; |
835 } | 850 } |
836 | 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 |
837 bool FrameFetchContext::IsControlledByServiceWorker() const { | 877 bool FrameFetchContext::IsControlledByServiceWorker() const { |
838 DCHECK(MasterDocumentLoader()); | 878 DCHECK(MasterDocumentLoader()); |
839 | 879 |
840 // Service workers are bypassed by suborigins (see | 880 // Service workers are bypassed by suborigins (see |
841 // https://w3c.github.io/webappsec-suborigins/). Since service worker | 881 // https://w3c.github.io/webappsec-suborigins/). Since service worker |
842 // controllers are assigned based on physical origin, without knowledge of | 882 // controllers are assigned based on physical origin, without knowledge of |
843 // whether the context is in a suborigin, it is necessary to explicitly bypass | 883 // 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 | 884 // 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 | 885 // explicitly return |false| here so that it is clear that the SW will be |
846 // bypassed. In particular, this is important for | 886 // bypassed. In particular, this is important for |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 } | 993 } |
954 | 994 |
955 if (should_send_viewport_width && GetFrame()->View()) { | 995 if (should_send_viewport_width && GetFrame()->View()) { |
956 request.AddHTTPHeaderField( | 996 request.AddHTTPHeaderField( |
957 "Viewport-Width", | 997 "Viewport-Width", |
958 AtomicString(String::Number(GetFrame()->View()->ViewportWidth()))); | 998 AtomicString(String::Number(GetFrame()->View()->ViewportWidth()))); |
959 } | 999 } |
960 } | 1000 } |
961 | 1001 |
962 void FrameFetchContext::PopulateResourceRequest( | 1002 void FrameFetchContext::PopulateResourceRequest( |
| 1003 const KURL& url, |
963 Resource::Type type, | 1004 Resource::Type type, |
964 const ClientHintsPreferences& hints_preferences, | 1005 const ClientHintsPreferences& hints_preferences, |
965 const FetchParameters::ResourceWidth& resource_width, | 1006 const FetchParameters::ResourceWidth& resource_width, |
| 1007 const ResourceLoaderOptions& options, |
| 1008 SecurityViolationReportingPolicy reporting_policy, |
966 ResourceRequest& request) { | 1009 ResourceRequest& request) { |
967 SetFirstPartyCookieAndRequestorOrigin(request); | 1010 SetFirstPartyCookieAndRequestorOrigin(request); |
| 1011 |
| 1012 // Before modifying the request for CSP, evaluate report-only headers. This |
| 1013 // allows site owners to learn about requests that are being modified |
| 1014 // (e.g. mixed content that is being upgraded by upgrade-insecure-requests). |
| 1015 CheckCSPForRequest(request, url, options, reporting_policy, |
| 1016 request.GetRedirectStatus(), |
| 1017 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); |
| 1018 |
968 ModifyRequestForCSP(request); | 1019 ModifyRequestForCSP(request); |
969 AddClientHintsIfNecessary(hints_preferences, resource_width, request); | 1020 AddClientHintsIfNecessary(hints_preferences, resource_width, request); |
970 AddCSPHeaderIfNecessary(type, request); | 1021 AddCSPHeaderIfNecessary(type, request); |
971 } | 1022 } |
972 | 1023 |
973 void FrameFetchContext::SetFirstPartyCookieAndRequestorOrigin( | 1024 void FrameFetchContext::SetFirstPartyCookieAndRequestorOrigin( |
974 ResourceRequest& request) { | 1025 ResourceRequest& request) { |
975 if (!GetDocument()) | 1026 if (!GetDocument()) |
976 return; | 1027 return; |
977 | 1028 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 RefPtr<WebTaskRunner> FrameFetchContext::LoadingTaskRunner() const { | 1080 RefPtr<WebTaskRunner> FrameFetchContext::LoadingTaskRunner() const { |
1030 return GetFrame()->FrameScheduler()->LoadingTaskRunner(); | 1081 return GetFrame()->FrameScheduler()->LoadingTaskRunner(); |
1031 } | 1082 } |
1032 | 1083 |
1033 DEFINE_TRACE(FrameFetchContext) { | 1084 DEFINE_TRACE(FrameFetchContext) { |
1034 visitor->Trace(document_loader_); | 1085 visitor->Trace(document_loader_); |
1035 BaseFetchContext::Trace(visitor); | 1086 BaseFetchContext::Trace(visitor); |
1036 } | 1087 } |
1037 | 1088 |
1038 } // namespace blink | 1089 } // namespace blink |
OLD | NEW |