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

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

Issue 2823213002: Implement CanRequest in BaseFetchContext (Closed)
Patch Set: fix 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 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/loader/BaseFetchContext.h" 5 #include "core/loader/BaseFetchContext.h"
6 6
7 #include "core/dom/ExecutionContext.h"
8 #include "core/frame/ContentSettingsClient.h"
9 #include "core/frame/Settings.h"
7 #include "core/frame/csp/ContentSecurityPolicy.h" 10 #include "core/frame/csp/ContentSecurityPolicy.h"
8 #include "core/inspector/ConsoleMessage.h" 11 #include "core/inspector/ConsoleMessage.h"
12 #include "core/loader/SubresourceFilter.h"
13 #include "core/loader/private/FrameClientHintsPreferencesContext.h"
14 #include "platform/exported/WrappedResourceRequest.h"
15 #include "platform/loader/fetch/FetchInitiatorTypeNames.h"
16 #include "platform/loader/fetch/Resource.h"
17 #include "platform/loader/fetch/ResourceLoadPriority.h"
18 #include "platform/loader/fetch/ResourceLoadingLog.h"
19 #include "platform/weborigin/SchemeRegistry.h"
9 #include "platform/weborigin/SecurityPolicy.h" 20 #include "platform/weborigin/SecurityPolicy.h"
10 21
11 namespace blink { 22 namespace blink {
12 23
13 BaseFetchContext::BaseFetchContext(ExecutionContext* context) 24 BaseFetchContext::BaseFetchContext(ExecutionContext* context)
14 : execution_context_(context) {} 25 : execution_context_(context) {}
15 26
16 void BaseFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request, 27 void BaseFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request,
17 FetchResourceType type) { 28 FetchResourceType type) {
18 bool is_main_resource = type == kFetchMainResource; 29 bool is_main_resource = type == kFetchMainResource;
(...skipping 17 matching lines...) Expand all
36 if (execution_context_) { 47 if (execution_context_) {
37 request.SetExternalRequestStateFromRequestorAddressSpace( 48 request.SetExternalRequestStateFromRequestorAddressSpace(
38 execution_context_->GetSecurityContext().AddressSpace()); 49 execution_context_->GetSecurityContext().AddressSpace());
39 } 50 }
40 } 51 }
41 52
42 SecurityOrigin* BaseFetchContext::GetSecurityOrigin() const { 53 SecurityOrigin* BaseFetchContext::GetSecurityOrigin() const {
43 return execution_context_ ? execution_context_->GetSecurityOrigin() : nullptr; 54 return execution_context_ ? execution_context_->GetSecurityOrigin() : nullptr;
44 } 55 }
45 56
57 ResourceRequestBlockedReason BaseFetchContext::CanRequest(
58 Resource::Type type,
59 const ResourceRequest& resource_request,
60 const KURL& url,
61 const ResourceLoaderOptions& options,
62 SecurityViolationReportingPolicy reporting_policy,
63 FetchParameters::OriginRestriction origin_restriction) const {
64 ResourceRequestBlockedReason blocked_reason = CanRequestInternal(
65 type, resource_request, url, options, reporting_policy,
66 origin_restriction, resource_request.GetRedirectStatus());
67 if (blocked_reason != ResourceRequestBlockedReason::kNone &&
68 reporting_policy == SecurityViolationReportingPolicy::kReport) {
69 DispatchDidBlockRequest(resource_request, options.initiator_info,
70 blocked_reason);
71 }
72 return blocked_reason;
73 }
74
75 ResourceRequestBlockedReason BaseFetchContext::AllowResponse(
76 Resource::Type type,
77 const ResourceRequest& resource_request,
78 const KURL& url,
79 const ResourceLoaderOptions& options) const {
80 ResourceRequestBlockedReason blocked_reason =
81 CanRequestInternal(type, resource_request, url, options,
82 SecurityViolationReportingPolicy::kReport,
83 FetchParameters::kUseDefaultOriginRestrictionForType,
84 RedirectStatus::kFollowedRedirect);
85
86 if (blocked_reason != ResourceRequestBlockedReason::kNone) {
87 DispatchDidBlockRequest(resource_request, options.initiator_info,
88 blocked_reason);
89 }
90 return blocked_reason;
91 }
92
46 void BaseFetchContext::PrintAccessDeniedMessage(const KURL& url) const { 93 void BaseFetchContext::PrintAccessDeniedMessage(const KURL& url) const {
47 if (url.IsNull()) 94 if (url.IsNull())
48 return; 95 return;
49 96
50 DCHECK(execution_context_); 97 DCHECK(execution_context_);
51 String message; 98 String message;
52 if (execution_context_->Url().IsNull()) { 99 if (execution_context_->Url().IsNull()) {
53 message = "Unsafe attempt to load URL " + url.ElidedString() + '.'; 100 message = "Unsafe attempt to load URL " + url.ElidedString() + '.';
54 } else if (url.IsLocalFile() || execution_context_->Url().IsLocalFile()) { 101 } else if (url.IsLocalFile() || execution_context_->Url().IsLocalFile()) {
55 message = "Unsafe attempt to load URL " + url.ElidedString() + 102 message = "Unsafe attempt to load URL " + url.ElidedString() +
(...skipping 15 matching lines...) Expand all
71 ResourceRequest& request) { 118 ResourceRequest& request) {
72 if (!execution_context_) 119 if (!execution_context_)
73 return; 120 return;
74 121
75 const ContentSecurityPolicy* csp = 122 const ContentSecurityPolicy* csp =
76 execution_context_->GetContentSecurityPolicy(); 123 execution_context_->GetContentSecurityPolicy();
77 if (csp->ShouldSendCSPHeader(type)) 124 if (csp->ShouldSendCSPHeader(type))
78 request.AddHTTPHeaderField("CSP", "active"); 125 request.AddHTTPHeaderField("CSP", "active");
79 } 126 }
80 127
128 ResourceRequestBlockedReason BaseFetchContext::CanRequestInternal(
129 Resource::Type type,
130 const ResourceRequest& resource_request,
131 const KURL& url,
132 const ResourceLoaderOptions& options,
133 SecurityViolationReportingPolicy reporting_policy,
134 FetchParameters::OriginRestriction origin_restriction,
135 ResourceRequest::RedirectStatus redirect_status) const {
136 if (ShouldBlockRequestByInspector(resource_request))
137 return ResourceRequestBlockedReason::kInspector;
138
139 SecurityOrigin* security_origin = options.security_origin.Get();
140 if (!security_origin && execution_context_)
141 security_origin = execution_context_->GetSecurityOrigin();
142
143 if (origin_restriction != FetchParameters::kNoOriginRestriction &&
144 security_origin && !security_origin->CanDisplay(url)) {
145 if (reporting_policy == SecurityViolationReportingPolicy::kReport)
146 ReportLocalLoadFailed(url);
147 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not "
148 "allowed by SecurityOrigin::CanDisplay";
149 return ResourceRequestBlockedReason::kOther;
150 }
151
152 // Some types of resources can be loaded only from the same origin. Other
153 // types of resources, like Images, Scripts, and CSS, can be loaded from
154 // any URL.
155 switch (type) {
156 case Resource::kMainResource:
157 case Resource::kImage:
158 case Resource::kCSSStyleSheet:
159 case Resource::kScript:
160 case Resource::kFont:
161 case Resource::kRaw:
162 case Resource::kLinkPrefetch:
163 case Resource::kTextTrack:
164 case Resource::kImportResource:
165 case Resource::kMedia:
166 case Resource::kManifest:
167 case Resource::kMock:
168 // By default these types of resources can be loaded from any origin.
169 // FIXME: Are we sure about Resource::kFont?
170 if (origin_restriction == FetchParameters::kRestrictToSameOrigin &&
171 !security_origin->CanRequest(url)) {
172 PrintAccessDeniedMessage(url);
173 return ResourceRequestBlockedReason::kOrigin;
174 }
175 break;
176 case Resource::kXSLStyleSheet:
177 DCHECK(RuntimeEnabledFeatures::xsltEnabled());
178 case Resource::kSVGDocument:
179 if (!security_origin->CanRequest(url)) {
180 PrintAccessDeniedMessage(url);
181 return ResourceRequestBlockedReason::kOrigin;
182 }
183 break;
184 }
185
186 // FIXME: Convert this to check the isolated world's Content Security Policy
187 // once webkit.org/b/104520 is solved.
188 bool should_bypass_main_world_csp =
189 ShouldBypassMainWorldCSP() || options.content_security_policy_option ==
190 kDoNotCheckContentSecurityPolicy;
191
192 if (execution_context_) {
193 DCHECK(execution_context_->GetContentSecurityPolicy());
194 if (!should_bypass_main_world_csp &&
195 !execution_context_->GetContentSecurityPolicy()->AllowRequest(
196 resource_request.GetRequestContext(), url,
197 options.content_security_policy_nonce, options.integrity_metadata,
198 options.parser_disposition, redirect_status, reporting_policy))
199 return ResourceRequestBlockedReason::CSP;
200 }
201
202 if (type == Resource::kScript || type == Resource::kImportResource) {
203 if (!GetContentSettingsClient()->AllowScriptFromSource(
horo 2017/04/20 06:00:48 nit: We should check GetContentSettingsClient()
kinuko 2017/04/21 09:45:27 Done.
204 !GetSettings() || GetSettings()->GetScriptEnabled(), url)) {
205 GetContentSettingsClient()->DidNotAllowScript();
206 // TODO(estark): Use a different ResourceRequestBlockedReason here, since
207 // this check has nothing to do with CSP. https://crbug.com/600795
208 return ResourceRequestBlockedReason::CSP;
209 }
210 }
211
212 // SVG Images have unique security rules that prevent all subresource requests
213 // except for data urls.
214 if (type != Resource::kMainResource && IsSVGImageChromeClient() &&
215 !url.ProtocolIsData())
216 return ResourceRequestBlockedReason::kOrigin;
217
218 // Measure the number of legacy URL schemes ('ftp://') and the number of
219 // embedded-credential ('http://user:password@...') resources embedded as
220 // subresources.
221 if (resource_request.GetFrameType() != WebURLRequest::kFrameTypeTopLevel) {
222 if (GetMainResourceSecurityContext() &&
223 SchemeRegistry::ShouldTreatURLSchemeAsLegacy(url.Protocol()) &&
224 !SchemeRegistry::ShouldTreatURLSchemeAsLegacy(
225 GetMainResourceSecurityContext()
226 ->GetSecurityOrigin()
227 ->Protocol())) {
228 CountDeprecation(UseCounter::kLegacyProtocolEmbeddedAsSubresource);
229
230 // TODO(mkwst): Enabled by default in M59. Drop the runtime-enabled check
231 // in M60: https://www.chromestatus.com/feature/5709390967472128
232 if (RuntimeEnabledFeatures::blockLegacySubresourcesEnabled())
233 return ResourceRequestBlockedReason::kOrigin;
234 }
235
236 if ((!url.User().IsEmpty() || !url.Pass().IsEmpty()) &&
237 resource_request.GetRequestContext() !=
238 WebURLRequest::kRequestContextXMLHttpRequest) {
239 CountDeprecation(
240 UseCounter::kRequestedSubresourceWithEmbeddedCredentials);
241 // TODO(mkwst): Remove the runtime-enabled check in M59:
242 // https://www.chromestatus.com/feature/5669008342777856
243 if (RuntimeEnabledFeatures::blockCredentialedSubresourcesEnabled())
244 return ResourceRequestBlockedReason::kOrigin;
245 }
246 }
247
248 // Check for mixed content. We do this second-to-last so that when folks block
249 // mixed content with a CSP policy, they don't get a warning. They'll still
250 // get a warning in the console about CSP blocking the load.
251 if (ShouldBlockFetchByMixedContentCheck(resource_request, url,
252 reporting_policy))
253 return ResourceRequestBlockedReason::kMixedContent;
254
255 if (url.WhitespaceRemoved()) {
256 CountDeprecation(UseCounter::kCanRequestURLHTTPContainingNewline);
257 if (url.ProtocolIsInHTTPFamily()) {
258 if (RuntimeEnabledFeatures::restrictCanRequestURLCharacterSetEnabled())
259 return ResourceRequestBlockedReason::kOther;
260 } else {
261 CountUsage(UseCounter::kCanRequestURLNonHTTPContainingNewline);
262 }
263 }
264
265 // Let the client have the final say into whether or not the load should
266 // proceed.
267 if (GetSubresourceFilter() && type != Resource::kMainResource &&
268 type != Resource::kImportResource) {
269 if (!GetSubresourceFilter()->AllowLoad(
270 url, resource_request.GetRequestContext(), reporting_policy)) {
271 return ResourceRequestBlockedReason::kSubresourceFilter;
272 }
273 }
274
275 return ResourceRequestBlockedReason::kNone;
276 }
277
81 DEFINE_TRACE(BaseFetchContext) { 278 DEFINE_TRACE(BaseFetchContext) {
82 visitor->Trace(execution_context_); 279 visitor->Trace(execution_context_);
83 FetchContext::Trace(visitor); 280 FetchContext::Trace(visitor);
84 } 281 }
85 282
86 } // namespace blink 283 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698