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

Side by Side Diff: content/browser/loader/resource_dispatcher_host_impl.cc

Issue 2222723002: Avoid calling into the ContentBrowserClient interface from ResourceDispatcherHostImpl to determine … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Attempt to fix 64 bit windows redness Created 4 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/browser/loader/resource_dispatcher_host_impl.h" 7 #include "content/browser/loader/resource_dispatcher_host_impl.h"
8 8
9 #include <stddef.h> 9 #include <stddef.h>
10 10
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE; 279 CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
280 break; 280 break;
281 case blink::WebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin: 281 case blink::WebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin:
282 net_referrer_policy = net::URLRequest:: 282 net_referrer_policy = net::URLRequest::
283 REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN; 283 REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN;
284 break; 284 break;
285 } 285 }
286 request->set_referrer_policy(net_referrer_policy); 286 request->set_referrer_policy(net_referrer_policy);
287 } 287 }
288 288
289 // Consults the RendererSecurity policy to determine whether the
290 // ResourceDispatcherHostImpl should service this request. A request might be
291 // disallowed if the renderer is not authorized to retrieve the request URL or
292 // if the renderer is attempting to upload an unauthorized file.
293 bool ShouldServiceRequest(int process_type,
294 int child_id,
295 const ResourceRequest& request_data,
296 const net::HttpRequestHeaders& headers,
297 ResourceMessageFilter* filter,
298 ResourceContext* resource_context) {
299 ChildProcessSecurityPolicyImpl* policy =
300 ChildProcessSecurityPolicyImpl::GetInstance();
301
302 // Check if the renderer is permitted to request the requested URL.
303 if (!policy->CanRequestURL(child_id, request_data.url)) {
304 VLOG(1) << "Denied unauthorized request for "
305 << request_data.url.possibly_invalid_spec();
306 return false;
307 }
308
309 // Check if the renderer is using an illegal Origin header. If so, kill it.
310 std::string origin_string;
311 bool has_origin = headers.GetHeader("Origin", &origin_string) &&
312 origin_string != "null";
313 if (has_origin) {
314 GURL origin(origin_string);
315 if (!policy->CanCommitURL(child_id, origin) ||
316 GetContentClient()->browser()->IsIllegalOrigin(resource_context,
317 child_id, origin)) {
318 VLOG(1) << "Killed renderer for illegal origin: " << origin_string;
319 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN);
320 return false;
321 }
322 }
323
324 // Check if the renderer is permitted to upload the requested files.
325 if (request_data.request_body.get()) {
326 const std::vector<ResourceRequestBodyImpl::Element>* uploads =
327 request_data.request_body->elements();
328 std::vector<ResourceRequestBodyImpl::Element>::const_iterator iter;
329 for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
330 if (iter->type() == ResourceRequestBodyImpl::Element::TYPE_FILE &&
331 !policy->CanReadFile(child_id, iter->path())) {
332 NOTREACHED() << "Denied unauthorized upload of "
333 << iter->path().value();
334 return false;
335 }
336 if (iter->type() ==
337 ResourceRequestBodyImpl::Element::TYPE_FILE_FILESYSTEM) {
338 storage::FileSystemURL url =
339 filter->file_system_context()->CrackURL(iter->filesystem_url());
340 if (!policy->CanReadFileSystemFile(child_id, url)) {
341 NOTREACHED() << "Denied unauthorized upload of "
342 << iter->filesystem_url().spec();
343 return false;
344 }
345 }
346 }
347 }
348
349 return true;
350 }
351
352 void RemoveDownloadFileFromChildSecurityPolicy(int child_id, 289 void RemoveDownloadFileFromChildSecurityPolicy(int child_id,
353 const base::FilePath& path) { 290 const base::FilePath& path) {
354 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( 291 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
355 child_id, path); 292 child_id, path);
356 } 293 }
357 294
358 int GetCertID(CertStore* cert_store, net::URLRequest* request, int child_id) { 295 int GetCertID(CertStore* cert_store, net::URLRequest* request, int child_id) {
359 if (request->ssl_info().cert.get()) 296 if (request->ssl_info().cert.get())
360 return cert_store->StoreCert(request->ssl_info().cert.get(), child_id); 297 return cert_store->StoreCert(request->ssl_info().cert.get(), child_id);
361 return 0; 298 return 0;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 if (pending_frame_host) 423 if (pending_frame_host)
487 routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId()); 424 routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId());
488 } 425 }
489 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 426 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
490 base::Bind(&NotifyForRouteSetOnIO, frame_callback, 427 base::Bind(&NotifyForRouteSetOnIO, frame_callback,
491 base::Passed(std::move(routing_ids)))); 428 base::Passed(std::move(routing_ids))));
492 } 429 }
493 430
494 } // namespace 431 } // namespace
495 432
433 ResourceDispatcherHostImpl::HeaderInterceptorInfo::HeaderInterceptorInfo() {}
434
435 ResourceDispatcherHostImpl::HeaderInterceptorInfo::~HeaderInterceptorInfo() {}
436
437 ResourceDispatcherHostImpl::HeaderInterceptorInfo::HeaderInterceptorInfo(
438 const HeaderInterceptorInfo& other) {}
439
496 // static 440 // static
497 ResourceDispatcherHost* ResourceDispatcherHost::Get() { 441 ResourceDispatcherHost* ResourceDispatcherHost::Get() {
498 return g_resource_dispatcher_host; 442 return g_resource_dispatcher_host;
499 } 443 }
500 444
501 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() 445 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
502 : save_file_manager_(new SaveFileManager()), 446 : save_file_manager_(new SaveFileManager()),
503 request_id_(-1), 447 request_id_(-1),
504 is_shutdown_(false), 448 is_shutdown_(false),
505 num_in_flight_requests_(0), 449 num_in_flight_requests_(0),
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( 686 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest(
743 net::URLRequest* request) { 687 net::URLRequest* request) {
744 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); 688 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
745 if (info) { 689 if (info) {
746 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); 690 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID());
747 if (loader) 691 if (loader)
748 loader->ClearLoginDelegate(); 692 loader->ClearLoginDelegate();
749 } 693 }
750 } 694 }
751 695
696 void ResourceDispatcherHostImpl::RegisterInterceptor(
697 const std::string& http_header,
698 const std::string& starts_with,
699 const InterceptorCallback& interceptor) {
700 DCHECK(!http_header.empty());
701 DCHECK(interceptor);
702 // Only one interceptor per header is supported.
703 DCHECK(http_header_interceptor_map_.find(http_header) ==
704 http_header_interceptor_map_.end());
705
706 HeaderInterceptorInfo interceptor_info;
707 interceptor_info.starts_with = starts_with;
708 interceptor_info.interceptor = interceptor;
709
710 http_header_interceptor_map_[http_header] = interceptor_info;
711 }
712
752 void ResourceDispatcherHostImpl::Shutdown() { 713 void ResourceDispatcherHostImpl::Shutdown() {
753 DCHECK_CURRENTLY_ON(BrowserThread::UI); 714 DCHECK_CURRENTLY_ON(BrowserThread::UI);
754 BrowserThread::PostTask(BrowserThread::IO, 715 BrowserThread::PostTask(BrowserThread::IO,
755 FROM_HERE, 716 FROM_HERE,
756 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, 717 base::Bind(&ResourceDispatcherHostImpl::OnShutdown,
757 base::Unretained(this))); 718 base::Unretained(this)));
758 } 719 }
759 720
760 std::unique_ptr<ResourceHandler> 721 std::unique_ptr<ResourceHandler>
761 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( 722 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 ResourceContext* resource_context = NULL; 1311 ResourceContext* resource_context = NULL;
1351 net::URLRequestContext* request_context = NULL; 1312 net::URLRequestContext* request_context = NULL;
1352 filter_->GetContexts(request_data.resource_type, &resource_context, 1313 filter_->GetContexts(request_data.resource_type, &resource_context,
1353 &request_context); 1314 &request_context);
1354 1315
1355 // Parse the headers before calling ShouldServiceRequest, so that they are 1316 // Parse the headers before calling ShouldServiceRequest, so that they are
1356 // available to be validated. 1317 // available to be validated.
1357 net::HttpRequestHeaders headers; 1318 net::HttpRequestHeaders headers;
1358 headers.AddHeadersFromString(request_data.headers); 1319 headers.AddHeadersFromString(request_data.headers);
1359 1320
1360 if (is_shutdown_ || 1321 BeginRequestStatus begin_request_status = CONTINUE;
1361 !ShouldServiceRequest(process_type, child_id, request_data, headers, 1322 OnHeaderProcessedCallback callback;
1362 filter_, resource_context)) { 1323 if (!is_shutdown_) {
1324 callback =
1325 base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest,
1326 base::Unretained(this), request_id, request_data,
1327 sync_result, route_id, headers);
1328 begin_request_status =
1329 ShouldServiceRequest(process_type, child_id, request_data, headers,
1330 filter_, resource_context, callback);
1331 } else {
1332 begin_request_status = ABORT;
1333 }
1334 if (begin_request_status == ABORT) {
1335 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1336 return;
1337 } else if (begin_request_status == CONTINUE) {
1338 callback.Run(true, 0);
1339 }
1340 }
1341
1342 void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
1343 int request_id,
1344 const ResourceRequest& request_data,
1345 IPC::Message* sync_result, // only valid for sync
1346 int route_id,
1347 const net::HttpRequestHeaders& headers,
1348 bool continue_request,
1349 int error_code) {
1350 if (!continue_request) {
1351 bad_message::ReceivedBadMessage(
1352 filter_, static_cast<bad_message::BadMessageReason>(error_code));
Charlie Reis 2016/08/10 20:44:02 This is not a safe cast. The INVALID_ORIGIN code
1363 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1353 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1364 return; 1354 return;
1365 } 1355 }
1366 1356
1357 int process_type = filter_->process_type();
1358 int child_id = filter_->child_id();
1359
1360 bool is_navigation_stream_request =
1361 IsBrowserSideNavigationEnabled() &&
1362 IsResourceTypeFrame(request_data.resource_type);
1363
1364 ResourceContext* resource_context = NULL;
1365 net::URLRequestContext* request_context = NULL;
1366 filter_->GetContexts(request_data.resource_type, &resource_context,
1367 &request_context);
1368
1367 // Allow the observer to block/handle the request. 1369 // Allow the observer to block/handle the request.
1368 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, 1370 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method,
1369 request_data.url, 1371 request_data.url,
1370 request_data.resource_type, 1372 request_data.resource_type,
1371 resource_context)) { 1373 resource_context)) {
1372 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1374 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1373 return; 1375 return;
1374 } 1376 }
1375 1377
1376 // Construct the request. 1378 // Construct the request.
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 DCHECK(deserialized); 2600 DCHECK(deserialized);
2599 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); 2601 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id);
2600 response->head.security_info = SerializeSecurityInfo(ssl); 2602 response->head.security_info = SerializeSecurityInfo(ssl);
2601 } 2603 }
2602 2604
2603 CertStore* ResourceDispatcherHostImpl::GetCertStore() { 2605 CertStore* ResourceDispatcherHostImpl::GetCertStore() {
2604 return cert_store_for_testing_ ? cert_store_for_testing_ 2606 return cert_store_for_testing_ ? cert_store_for_testing_
2605 : CertStore::GetInstance(); 2607 : CertStore::GetInstance();
2606 } 2608 }
2607 2609
2610 ResourceDispatcherHostImpl::BeginRequestStatus
2611 ResourceDispatcherHostImpl::ShouldServiceRequest(
2612 int process_type,
2613 int child_id,
2614 const ResourceRequest& request_data,
2615 const net::HttpRequestHeaders& headers,
2616 ResourceMessageFilter* filter,
2617 ResourceContext* resource_context,
2618 OnHeaderProcessedCallback callback) {
2619 ChildProcessSecurityPolicyImpl* policy =
2620 ChildProcessSecurityPolicyImpl::GetInstance();
2621
2622 // Check if the renderer is permitted to request the requested URL.
2623 if (!policy->CanRequestURL(child_id, request_data.url)) {
2624 VLOG(1) << "Denied unauthorized request for "
2625 << request_data.url.possibly_invalid_spec();
2626 return ABORT;
2627 }
2628
2629 // Check if the renderer is using an illegal Origin header. If so, kill it.
2630 std::string origin_string;
2631 bool has_origin =
2632 headers.GetHeader("Origin", &origin_string) && origin_string != "null";
2633 if (has_origin) {
2634 GURL origin(origin_string);
2635 if (!policy->CanCommitURL(child_id, origin)) {
2636 VLOG(1) << "Killed renderer for illegal origin: " << origin_string;
2637 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN);
2638 return ABORT;
2639 }
2640 }
2641
2642 // Check if the renderer is permitted to upload the requested files.
2643 if (request_data.request_body.get()) {
2644 const std::vector<ResourceRequestBodyImpl::Element>* uploads =
2645 request_data.request_body->elements();
2646 std::vector<ResourceRequestBodyImpl::Element>::const_iterator iter;
2647 for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
2648 if (iter->type() == ResourceRequestBodyImpl::Element::TYPE_FILE &&
2649 !policy->CanReadFile(child_id, iter->path())) {
2650 NOTREACHED() << "Denied unauthorized upload of "
2651 << iter->path().value();
2652 return ABORT;
2653 }
2654 if (iter->type() ==
2655 ResourceRequestBodyImpl::Element::TYPE_FILE_FILESYSTEM) {
2656 storage::FileSystemURL url =
2657 filter->file_system_context()->CrackURL(iter->filesystem_url());
2658 if (!policy->CanReadFileSystemFile(child_id, url)) {
2659 NOTREACHED() << "Denied unauthorized upload of "
2660 << iter->filesystem_url().spec();
2661 return ABORT;
2662 }
2663 }
2664 }
2665 }
2666
2667 // Check if we have a registered interceptor for the headers passed in. If
2668 // yes then we need to mark the current request as pending and wait for the
2669 // interceptor to invoke the |callback| with a status code indicating whether
2670 // the request needs to be aborted or continued.
2671 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
2672 HeaderInterceptorMap::iterator index =
2673 http_header_interceptor_map_.find(it.name());
2674 if (index != http_header_interceptor_map_.end()) {
2675 HeaderInterceptorInfo& interceptor_info = index->second;
2676
2677 bool call_interceptor = true;
2678 if (!interceptor_info.starts_with.empty()) {
2679 call_interceptor =
2680 base::StartsWith(it.value(), interceptor_info.starts_with,
2681 base::CompareCase::INSENSITIVE_ASCII);
2682 }
2683 if (call_interceptor) {
2684 interceptor_info.interceptor.Run(it.name(), it.value(), child_id,
2685 resource_context, callback);
2686 return PENDING;
2687 }
2688 }
2689 }
2690 return CONTINUE;
2691 }
2692
2608 } // namespace content 2693 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698