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

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: Remove the extension origin interceptor class. 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 starts_with = other.starts_with;
440 interceptor = other.interceptor;
441 }
442
496 // static 443 // static
497 ResourceDispatcherHost* ResourceDispatcherHost::Get() { 444 ResourceDispatcherHost* ResourceDispatcherHost::Get() {
498 return g_resource_dispatcher_host; 445 return g_resource_dispatcher_host;
499 } 446 }
500 447
501 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() 448 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
502 : save_file_manager_(new SaveFileManager()), 449 : save_file_manager_(new SaveFileManager()),
503 request_id_(-1), 450 request_id_(-1),
504 is_shutdown_(false), 451 is_shutdown_(false),
505 num_in_flight_requests_(0), 452 num_in_flight_requests_(0),
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( 689 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest(
743 net::URLRequest* request) { 690 net::URLRequest* request) {
744 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); 691 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
745 if (info) { 692 if (info) {
746 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); 693 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID());
747 if (loader) 694 if (loader)
748 loader->ClearLoginDelegate(); 695 loader->ClearLoginDelegate();
749 } 696 }
750 } 697 }
751 698
699 void ResourceDispatcherHostImpl::RegisterInterceptor(
700 const std::string& http_header,
701 const std::string& starts_with,
702 const InterceptorCallback& interceptor) {
703 DCHECK(!http_header.empty());
704 DCHECK(interceptor);
705 // Only one interceptor per header is supported.
706 DCHECK(http_header_interceptor_map_.find(http_header) ==
707 http_header_interceptor_map_.end());
708
709 HeaderInterceptorInfo interceptor_info;
710 interceptor_info.starts_with = starts_with;
711 interceptor_info.interceptor = interceptor;
712
713 http_header_interceptor_map_[http_header] = interceptor_info;
714 }
715
752 void ResourceDispatcherHostImpl::Shutdown() { 716 void ResourceDispatcherHostImpl::Shutdown() {
753 DCHECK_CURRENTLY_ON(BrowserThread::UI); 717 DCHECK_CURRENTLY_ON(BrowserThread::UI);
754 BrowserThread::PostTask(BrowserThread::IO, 718 BrowserThread::PostTask(BrowserThread::IO,
755 FROM_HERE, 719 FROM_HERE,
756 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, 720 base::Bind(&ResourceDispatcherHostImpl::OnShutdown,
757 base::Unretained(this))); 721 base::Unretained(this)));
758 } 722 }
759 723
760 std::unique_ptr<ResourceHandler> 724 std::unique_ptr<ResourceHandler>
761 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( 725 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 ResourceContext* resource_context = NULL; 1314 ResourceContext* resource_context = NULL;
1351 net::URLRequestContext* request_context = NULL; 1315 net::URLRequestContext* request_context = NULL;
1352 filter_->GetContexts(request_data.resource_type, &resource_context, 1316 filter_->GetContexts(request_data.resource_type, &resource_context,
1353 &request_context); 1317 &request_context);
1354 1318
1355 // Parse the headers before calling ShouldServiceRequest, so that they are 1319 // Parse the headers before calling ShouldServiceRequest, so that they are
1356 // available to be validated. 1320 // available to be validated.
1357 net::HttpRequestHeaders headers; 1321 net::HttpRequestHeaders headers;
1358 headers.AddHeadersFromString(request_data.headers); 1322 headers.AddHeadersFromString(request_data.headers);
1359 1323
1360 if (is_shutdown_ || 1324 BeginRequestStatus begin_request_status = CONTINUE;
1361 !ShouldServiceRequest(process_type, child_id, request_data, headers, 1325 OnHeaderProcessedCallback callback;
1362 filter_, resource_context)) { 1326 if (!is_shutdown_) {
1327 callback =
1328 base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest,
1329 base::Unretained(this), request_id, request_data,
1330 sync_result, route_id, headers);
1331 begin_request_status =
1332 ShouldServiceRequest(process_type, child_id, request_data, headers,
1333 filter_, resource_context, callback);
1334 } else {
1335 begin_request_status = ABORT;
1336 }
1337 if (begin_request_status == ABORT) {
1338 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1339 return;
1340 } else if (begin_request_status == CONTINUE) {
1341 callback.Run(true, 0);
1342 }
1343 }
1344
1345 void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
1346 int request_id,
1347 const ResourceRequest& request_data,
1348 IPC::Message* sync_result, // only valid for sync
1349 int route_id,
1350 const net::HttpRequestHeaders& headers,
1351 bool continue_request,
1352 int error_code) {
1353 if (!continue_request) {
1354 bad_message::ReceivedBadMessage(
1355 filter_, static_cast<bad_message::BadMessageReason>(error_code));
1363 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1356 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1364 return; 1357 return;
1365 } 1358 }
1366 1359
1360 int process_type = filter_->process_type();
1361 int child_id = filter_->child_id();
1362
1363 bool is_navigation_stream_request =
1364 IsBrowserSideNavigationEnabled() &&
1365 IsResourceTypeFrame(request_data.resource_type);
1366
1367 ResourceContext* resource_context = NULL;
1368 net::URLRequestContext* request_context = NULL;
1369 filter_->GetContexts(request_data.resource_type, &resource_context,
1370 &request_context);
1371
1367 // Allow the observer to block/handle the request. 1372 // Allow the observer to block/handle the request.
1368 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, 1373 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method,
1369 request_data.url, 1374 request_data.url,
1370 request_data.resource_type, 1375 request_data.resource_type,
1371 resource_context)) { 1376 resource_context)) {
1372 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1377 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1373 return; 1378 return;
1374 } 1379 }
1375 1380
1376 // Construct the request. 1381 // Construct the request.
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 DCHECK(deserialized); 2603 DCHECK(deserialized);
2599 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); 2604 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id);
2600 response->head.security_info = SerializeSecurityInfo(ssl); 2605 response->head.security_info = SerializeSecurityInfo(ssl);
2601 } 2606 }
2602 2607
2603 CertStore* ResourceDispatcherHostImpl::GetCertStore() { 2608 CertStore* ResourceDispatcherHostImpl::GetCertStore() {
2604 return cert_store_for_testing_ ? cert_store_for_testing_ 2609 return cert_store_for_testing_ ? cert_store_for_testing_
2605 : CertStore::GetInstance(); 2610 : CertStore::GetInstance();
2606 } 2611 }
2607 2612
2613 ResourceDispatcherHostImpl::BeginRequestStatus
2614 ResourceDispatcherHostImpl::ShouldServiceRequest(
2615 int process_type,
2616 int child_id,
2617 const ResourceRequest& request_data,
2618 const net::HttpRequestHeaders& headers,
2619 ResourceMessageFilter* filter,
2620 ResourceContext* resource_context,
2621 OnHeaderProcessedCallback callback) {
2622 ChildProcessSecurityPolicyImpl* policy =
2623 ChildProcessSecurityPolicyImpl::GetInstance();
2624
2625 // Check if the renderer is permitted to request the requested URL.
2626 if (!policy->CanRequestURL(child_id, request_data.url)) {
2627 VLOG(1) << "Denied unauthorized request for "
2628 << request_data.url.possibly_invalid_spec();
2629 return ABORT;
2630 }
2631
2632 // Check if the renderer is using an illegal Origin header. If so, kill it.
2633 std::string origin_string;
2634 bool has_origin =
2635 headers.GetHeader("Origin", &origin_string) && origin_string != "null";
2636 if (has_origin) {
2637 GURL origin(origin_string);
2638 if (!policy->CanCommitURL(child_id, origin)) {
2639 VLOG(1) << "Killed renderer for illegal origin: " << origin_string;
2640 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN);
2641 return ABORT;
2642 }
2643 }
2644
2645 // Check if the renderer is permitted to upload the requested files.
2646 if (request_data.request_body.get()) {
2647 const std::vector<ResourceRequestBodyImpl::Element>* uploads =
2648 request_data.request_body->elements();
2649 std::vector<ResourceRequestBodyImpl::Element>::const_iterator iter;
2650 for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
2651 if (iter->type() == ResourceRequestBodyImpl::Element::TYPE_FILE &&
2652 !policy->CanReadFile(child_id, iter->path())) {
2653 NOTREACHED() << "Denied unauthorized upload of "
2654 << iter->path().value();
2655 return ABORT;
2656 }
2657 if (iter->type() ==
2658 ResourceRequestBodyImpl::Element::TYPE_FILE_FILESYSTEM) {
2659 storage::FileSystemURL url =
2660 filter->file_system_context()->CrackURL(iter->filesystem_url());
2661 if (!policy->CanReadFileSystemFile(child_id, url)) {
2662 NOTREACHED() << "Denied unauthorized upload of "
2663 << iter->filesystem_url().spec();
2664 return ABORT;
2665 }
2666 }
2667 }
2668 }
2669
2670 // Check if we have a registered interceptor for the headers passed in. If
2671 // yes then we need to mark the current request as pending and wait for the
2672 // interceptor to invoke the |callback| with a status code indicating whether
2673 // the request needs to be aborted or continued.
2674 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
2675 HeaderInterceptorMap::iterator index =
2676 http_header_interceptor_map_.find(it.name());
2677 if (index != http_header_interceptor_map_.end()) {
2678 HeaderInterceptorInfo& interceptor_info = index->second;
2679
2680 bool call_interceptor = true;
2681 if (!interceptor_info.starts_with.empty()) {
2682 call_interceptor =
2683 base::StartsWith(it.value(), interceptor_info.starts_with,
2684 base::CompareCase::INSENSITIVE_ASCII);
2685 }
2686 if (call_interceptor) {
2687 interceptor_info.interceptor.Run(it.name(), it.value(), child_id,
2688 resource_context, callback);
2689 return PENDING;
2690 }
2691 }
2692 }
2693 return CONTINUE;
2694 }
2695
2608 } // namespace content 2696 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698