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

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

Issue 2790693002: Split CSP into pre- and post-upgrade checks (Closed)
Patch Set: add unit 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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 FetchRequest::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 kContentSecurityPolicyHeaderTypeReport);
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 kContentSecurityPolicyHeaderTypeReport);
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 FetchRequest::kUseDefaultOriginRestrictionForType, 719 FetchRequest::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
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(resource_request, url, options, reporting_policy,
771 options.content_security_policy_option == 793 redirect_status,
772 kDoNotCheckContentSecurityPolicy; 794 kContentSecurityPolicyHeaderTypeEnforce) ==
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 type != Resource::kMainResource && type != Resource::kImportResource) { 871 type != Resource::kMainResource && type != Resource::kImportResource) {
857 if (!document_loader->GetSubresourceFilter()->AllowLoad( 872 if (!document_loader->GetSubresourceFilter()->AllowLoad(
858 url, resource_request.GetRequestContext(), reporting_policy)) { 873 url, resource_request.GetRequestContext(), reporting_policy)) {
859 return ResourceRequestBlockedReason::kSubresourceFilter; 874 return ResourceRequestBlockedReason::kSubresourceFilter;
860 } 875 }
861 } 876 }
862 877
863 return ResourceRequestBlockedReason::kNone; 878 return ResourceRequestBlockedReason::kNone;
864 } 879 }
865 880
881 ResourceRequestBlockedReason FrameFetchContext::CheckCSPForRequest(
882 const ResourceRequest& resource_request,
883 const KURL& url,
884 const ResourceLoaderOptions& options,
885 SecurityViolationReportingPolicy reporting_policy,
886 ResourceRequest::RedirectStatus redirect_status,
887 ContentSecurityPolicyHeaderType header_type) const {
888 if (GetFrame()->GetScriptController().ShouldBypassMainWorldCSP() ||
889 options.content_security_policy_option ==
890 kDoNotCheckContentSecurityPolicy) {
891 return ResourceRequestBlockedReason::kNone;
892 }
893
894 if (document_) {
895 DCHECK(document_->GetContentSecurityPolicy());
896 if (!document_->GetContentSecurityPolicy()->AllowRequest(
897 resource_request.GetRequestContext(), url,
898 options.content_security_policy_nonce, options.integrity_metadata,
899 options.parser_disposition, redirect_status, reporting_policy,
900 header_type))
901 return ResourceRequestBlockedReason::CSP;
902 }
903 return ResourceRequestBlockedReason::kNone;
904 }
905
866 bool FrameFetchContext::IsControlledByServiceWorker() const { 906 bool FrameFetchContext::IsControlledByServiceWorker() const {
867 DCHECK(MasterDocumentLoader()); 907 DCHECK(MasterDocumentLoader());
868 908
869 // Service workers are bypassed by suborigins (see 909 // Service workers are bypassed by suborigins (see
870 // https://w3c.github.io/webappsec-suborigins/). Since service worker 910 // https://w3c.github.io/webappsec-suborigins/). Since service worker
871 // controllers are assigned based on physical origin, without knowledge of 911 // controllers are assigned based on physical origin, without knowledge of
872 // whether the context is in a suborigin, it is necessary to explicitly bypass 912 // whether the context is in a suborigin, it is necessary to explicitly bypass
873 // service workers on a per-request basis. Additionally, it is necessary to 913 // service workers on a per-request basis. Additionally, it is necessary to
874 // explicitly return |false| here so that it is clear that the SW will be 914 // explicitly return |false| here so that it is clear that the SW will be
875 // bypassed. In particular, this is important for 915 // bypassed. In particular, this is important for
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 ResourceRequest& request) { 1036 ResourceRequest& request) {
997 if (!document_) 1037 if (!document_)
998 return; 1038 return;
999 1039
1000 const ContentSecurityPolicy* csp = document_->GetContentSecurityPolicy(); 1040 const ContentSecurityPolicy* csp = document_->GetContentSecurityPolicy();
1001 if (csp->ShouldSendCSPHeader(type)) 1041 if (csp->ShouldSendCSPHeader(type))
1002 request.AddHTTPHeaderField("CSP", "active"); 1042 request.AddHTTPHeaderField("CSP", "active");
1003 } 1043 }
1004 1044
1005 void FrameFetchContext::PopulateResourceRequest( 1045 void FrameFetchContext::PopulateResourceRequest(
1046 const KURL& url,
1006 Resource::Type type, 1047 Resource::Type type,
1007 const ClientHintsPreferences& hints_preferences, 1048 const ClientHintsPreferences& hints_preferences,
1008 const FetchRequest::ResourceWidth& resource_width, 1049 const FetchRequest::ResourceWidth& resource_width,
1050 const ResourceLoaderOptions& options,
1051 SecurityViolationReportingPolicy reporting_policy,
1009 ResourceRequest& request) { 1052 ResourceRequest& request) {
1010 SetFirstPartyCookieAndRequestorOrigin(request); 1053 SetFirstPartyCookieAndRequestorOrigin(request);
1054
1055 // Before modifying the request for CSP, evaluate report-only headers. This
1056 // allows site owners to learn about requests that are being modified
1057 // (e.g. mixed content that is being upgraded by upgrade-insecure-requests).
1058 CheckCSPForRequest(request, url, options, reporting_policy,
1059 request.GetRedirectStatus(),
1060 kContentSecurityPolicyHeaderTypeReport);
1061
1011 ModifyRequestForCSP(request); 1062 ModifyRequestForCSP(request);
1012 AddClientHintsIfNecessary(hints_preferences, resource_width, request); 1063 AddClientHintsIfNecessary(hints_preferences, resource_width, request);
1013 AddCSPHeaderIfNecessary(type, request); 1064 AddCSPHeaderIfNecessary(type, request);
1014 } 1065 }
1015 1066
1016 void FrameFetchContext::SetFirstPartyCookieAndRequestorOrigin( 1067 void FrameFetchContext::SetFirstPartyCookieAndRequestorOrigin(
1017 ResourceRequest& request) { 1068 ResourceRequest& request) {
1018 if (!document_) 1069 if (!document_)
1019 return; 1070 return;
1020 1071
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 return GetFrame()->FrameScheduler()->LoadingTaskRunner(); 1123 return GetFrame()->FrameScheduler()->LoadingTaskRunner();
1073 } 1124 }
1074 1125
1075 DEFINE_TRACE(FrameFetchContext) { 1126 DEFINE_TRACE(FrameFetchContext) {
1076 visitor->Trace(document_); 1127 visitor->Trace(document_);
1077 visitor->Trace(document_loader_); 1128 visitor->Trace(document_loader_);
1078 FetchContext::Trace(visitor); 1129 FetchContext::Trace(visitor);
1079 } 1130 }
1080 1131
1081 } // namespace blink 1132 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698