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

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

Issue 2182633007: Avoid using ContentBrowserClient::IsIllegalOrigin in ResourceDispatcherHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove the IsIllegalOrigin function from ContentBrowserClient 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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 288
289 // Consults the RendererSecurity policy to determine whether the 289 // Consults the RendererSecurity policy to determine whether the
290 // ResourceDispatcherHostImpl should service this request. A request might be 290 // ResourceDispatcherHostImpl should service this request. A request might be
291 // disallowed if the renderer is not authorized to retrieve the request URL or 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. 292 // if the renderer is attempting to upload an unauthorized file.
293 bool ShouldServiceRequest(int process_type, 293 bool ShouldServiceRequest(int process_type,
294 int child_id, 294 int child_id,
295 const ResourceRequest& request_data, 295 const ResourceRequest& request_data,
296 const net::HttpRequestHeaders& headers, 296 const net::HttpRequestHeaders& headers,
297 ResourceMessageFilter* filter, 297 ResourceMessageFilter* filter,
298 ResourceContext* resource_context) { 298 ResourceContext* resource_context,
299 ResourceDispatcherHostImpl* host) {
299 ChildProcessSecurityPolicyImpl* policy = 300 ChildProcessSecurityPolicyImpl* policy =
300 ChildProcessSecurityPolicyImpl::GetInstance(); 301 ChildProcessSecurityPolicyImpl::GetInstance();
301 302
302 // Check if the renderer is permitted to request the requested URL. 303 // Check if the renderer is permitted to request the requested URL.
303 if (!policy->CanRequestURL(child_id, request_data.url)) { 304 if (!policy->CanRequestURL(child_id, request_data.url)) {
304 VLOG(1) << "Denied unauthorized request for " 305 VLOG(1) << "Denied unauthorized request for "
305 << request_data.url.possibly_invalid_spec(); 306 << request_data.url.possibly_invalid_spec();
306 return false; 307 return false;
307 } 308 }
308 309
309 // Check if the renderer is using an illegal Origin header. If so, kill it. 310 // Check if the renderer is using an illegal Origin header. If so, kill it.
310 std::string origin_string; 311 std::string origin_string;
311 bool has_origin = headers.GetHeader("Origin", &origin_string) && 312 bool has_origin = headers.GetHeader("Origin", &origin_string) &&
312 origin_string != "null"; 313 origin_string != "null";
313 if (has_origin) { 314 if (has_origin) {
314 GURL origin(origin_string); 315 GURL origin(origin_string);
315 if (!policy->CanCommitURL(child_id, origin) || 316 if (!policy->CanCommitURL(child_id, origin) ||
316 GetContentClient()->browser()->IsIllegalOrigin(resource_context, 317 host->IsIllegalOrigin(resource_context, origin, child_id)) {
317 child_id, origin)) {
318 VLOG(1) << "Killed renderer for illegal origin: " << origin_string; 318 VLOG(1) << "Killed renderer for illegal origin: " << origin_string;
319 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN); 319 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN);
320 return false; 320 return false;
321 } 321 }
322 } 322 }
323 323
324 // Check if the renderer is permitted to upload the requested files. 324 // Check if the renderer is permitted to upload the requested files.
325 if (request_data.request_body.get()) { 325 if (request_data.request_body.get()) {
326 const std::vector<ResourceRequestBodyImpl::Element>* uploads = 326 const std::vector<ResourceRequestBodyImpl::Element>* uploads =
327 request_data.request_body->elements(); 327 request_data.request_body->elements();
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 if (pending_frame_host) 486 if (pending_frame_host)
487 routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId()); 487 routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId());
488 } 488 }
489 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 489 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
490 base::Bind(&NotifyForRouteSetOnIO, frame_callback, 490 base::Bind(&NotifyForRouteSetOnIO, frame_callback,
491 base::Passed(std::move(routing_ids)))); 491 base::Passed(std::move(routing_ids))));
492 } 492 }
493 493
494 } // namespace 494 } // namespace
495 495
496 ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo() {
497 }
498
499 ResourceDispatcherHostImpl::OriginAccessInfo::~OriginAccessInfo() {
500 }
501
502 ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo(
503 const OriginAccessInfo& other) {
504 }
505
496 // static 506 // static
497 ResourceDispatcherHost* ResourceDispatcherHost::Get() { 507 ResourceDispatcherHost* ResourceDispatcherHost::Get() {
498 return g_resource_dispatcher_host; 508 return g_resource_dispatcher_host;
499 } 509 }
500 510
501 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() 511 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
502 : save_file_manager_(new SaveFileManager()), 512 : save_file_manager_(new SaveFileManager()),
503 request_id_(-1), 513 request_id_(-1),
504 is_shutdown_(false), 514 is_shutdown_(false),
505 num_in_flight_requests_(0), 515 num_in_flight_requests_(0),
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( 754 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest(
745 net::URLRequest* request) { 755 net::URLRequest* request) {
746 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); 756 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
747 if (info) { 757 if (info) {
748 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); 758 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID());
749 if (loader) 759 if (loader)
750 loader->ClearLoginDelegate(); 760 loader->ClearLoginDelegate();
751 } 761 }
752 } 762 }
753 763
764 void ResourceDispatcherHostImpl::AddSchemeForAccessCheck(
765 const std::string& scheme) {
766 origins_for_access_check_.insert(scheme);
767 }
768
769 void ResourceDispatcherHostImpl::RegisterOriginForAccessChecks(
770 const ResourceContext* context,
771 const std::string& origin,
772 OriginAccessCheckMask access_check_mask) {
773 DCHECK_CURRENTLY_ON(BrowserThread::IO);
774
775 GURL url(origin);
776 // The following conditions need to apply before we can add access
777 // information for an origin.
778 // 1. The URL has to be valid.
779 // 2. It has to have a valid host.
780 // 3. The scheme has to be registered in the list of schemes being access
781 // checked.
782 if (!url.is_valid() || !url.has_host() ||
783 origins_for_access_check_.find(url.scheme()) ==
784 origins_for_access_check_.end()) {
785 NOTREACHED() << "Invalid URL or unregistered scheme.";
786 return;
787 }
788
789 OriginAccessInfoMap* origin_access_info_map =
790 GetOriginAccessMapForResourceContext(context);
791 DCHECK(origin_access_info_map->find(url.host()) ==
792 origin_access_info_map->end());
793
794 OriginAccessInfo access_info;
795 access_info.access_check_mask = access_check_mask;
796
797 (*origin_access_info_map)[url.host()] = access_info;
798 }
799
800 void ResourceDispatcherHostImpl::UnregisterOriginForAccessChecks(
801 const ResourceContext* context,
802 const std::string& origin) {
803 DCHECK_CURRENTLY_ON(BrowserThread::IO);
804
805 GURL url(origin);
806 // The scheme has to be registered in the list of schemes being access
807 // checked.
808 if (origins_for_access_check_.find(url.scheme()) ==
809 origins_for_access_check_.end()) {
810 NOTREACHED() << "Unregistered scheme for access check";
811 return;
812 }
813 OriginAccessInfoMap* origin_access_info_map =
814 GetOriginAccessMapForResourceContext(context);
815 OriginAccessInfoMap::iterator index = origin_access_info_map->find(
816 url.host());
817 if (index != origin_access_info_map->end())
818 origin_access_info_map->erase(index);
819 }
820
821 void ResourceDispatcherHostImpl::AddProcessForOrigin(
822 const ResourceContext* context,
823 const std::string& origin,
824 int process_id,
825 bool owner_process) {
826 DCHECK_CURRENTLY_ON(BrowserThread::IO);
827
828 GURL url(origin);
829 // The following conditions need to apply before we can add the process to
830 // the list of allowed processes for an origin.
831 // 1. The URL has to be valid.
832 // 2. It has to have a valid host.
833 // 3. The scheme has to be registered in the list of schemes being access
834 // checked.
835 if (!url.is_valid() || !url.has_host() ||
836 origins_for_access_check_.find(url.scheme()) ==
837 origins_for_access_check_.end()) {
838 NOTREACHED() << "Invalid URL or unregistered scheme.";
839 return;
840 }
841
842 OriginAccessInfoMap* origin_access_info_map =
843 GetOriginAccessMapForResourceContext(context);
844 DCHECK(origin_access_info_map);
845
846 OriginAccessInfoMap::iterator index = origin_access_info_map->find(
847 url.host());
848 // No need to add access information for an unregistered host.
849 if (index == origin_access_info_map->end())
850 return;
851
852 OriginAccessInfo& access_info = index->second;
853 if (owner_process) {
854 access_info.owner_processes[process_id]++;
855 } else {
856 access_info.other_processes[process_id]++;
857 }
858 }
859
860 void ResourceDispatcherHostImpl::RemoveProcessForOrigin(
861 const ResourceContext* context,
862 const std::string& origin,
863 int process_id,
864 bool owner_process) {
865 DCHECK_CURRENTLY_ON(BrowserThread::IO);
866
867 GURL url(origin);
868 // The scheme has to be registered in the list of schemes being access
869 // checked.
870 if (origins_for_access_check_.find(url.scheme()) ==
871 origins_for_access_check_.end()) {
872 DCHECK(false);
873 return;
874 }
875
876 OriginAccessInfoMap* origin_access_info_map =
877 GetOriginAccessMapForResourceContext(context);
878 DCHECK(origin_access_info_map);
879
880 OriginAccessInfoMap::iterator index = origin_access_info_map->find(
881 url.host());
882 // No need to add access information for an unregistered host.
883 if (index == origin_access_info_map->end())
884 return;
885
886 OriginAccessInfo& access_info = index->second;
887
888 std::map<int, int>::iterator process_index;
889 std::map<int, int>* process_map = nullptr;
890 if (owner_process) {
891 process_map = &access_info.owner_processes;
892 } else {
893 process_map = &access_info.other_processes;
894 }
895 process_index = process_map->find(process_id);
896 // The process has to be there in the list.
897 DCHECK(process_index != process_map->end());
898 process_index->second--;
899 if (process_index->second == 0)
900 process_map->erase(process_index);
901 }
902
754 void ResourceDispatcherHostImpl::Shutdown() { 903 void ResourceDispatcherHostImpl::Shutdown() {
755 DCHECK_CURRENTLY_ON(BrowserThread::UI); 904 DCHECK_CURRENTLY_ON(BrowserThread::UI);
756 BrowserThread::PostTask(BrowserThread::IO, 905 BrowserThread::PostTask(BrowserThread::IO,
757 FROM_HERE, 906 FROM_HERE,
758 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, 907 base::Bind(&ResourceDispatcherHostImpl::OnShutdown,
759 base::Unretained(this))); 908 base::Unretained(this)));
760 } 909 }
761 910
762 std::unique_ptr<ResourceHandler> 911 std::unique_ptr<ResourceHandler>
763 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( 912 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 filter_->GetContexts(request_data.resource_type, &resource_context, 1503 filter_->GetContexts(request_data.resource_type, &resource_context,
1355 &request_context); 1504 &request_context);
1356 1505
1357 // Parse the headers before calling ShouldServiceRequest, so that they are 1506 // Parse the headers before calling ShouldServiceRequest, so that they are
1358 // available to be validated. 1507 // available to be validated.
1359 net::HttpRequestHeaders headers; 1508 net::HttpRequestHeaders headers;
1360 headers.AddHeadersFromString(request_data.headers); 1509 headers.AddHeadersFromString(request_data.headers);
1361 1510
1362 if (is_shutdown_ || 1511 if (is_shutdown_ ||
1363 !ShouldServiceRequest(process_type, child_id, request_data, headers, 1512 !ShouldServiceRequest(process_type, child_id, request_data, headers,
1364 filter_, resource_context)) { 1513 filter_, resource_context, this)) {
1365 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1514 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1366 return; 1515 return;
1367 } 1516 }
1368 1517
1369 // Allow the observer to block/handle the request. 1518 // Allow the observer to block/handle the request.
1370 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, 1519 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method,
1371 request_data.url, 1520 request_data.url,
1372 request_data.resource_type, 1521 request_data.resource_type,
1373 resource_context)) { 1522 resource_context)) {
1374 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1523 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2600 DCHECK(deserialized); 2749 DCHECK(deserialized);
2601 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); 2750 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id);
2602 response->head.security_info = SerializeSecurityInfo(ssl); 2751 response->head.security_info = SerializeSecurityInfo(ssl);
2603 } 2752 }
2604 2753
2605 CertStore* ResourceDispatcherHostImpl::GetCertStore() { 2754 CertStore* ResourceDispatcherHostImpl::GetCertStore() {
2606 return cert_store_for_testing_ ? cert_store_for_testing_ 2755 return cert_store_for_testing_ ? cert_store_for_testing_
2607 : CertStore::GetInstance(); 2756 : CertStore::GetInstance();
2608 } 2757 }
2609 2758
2759 ResourceDispatcherHostImpl::OriginAccessInfoMap*
2760 ResourceDispatcherHostImpl::GetOriginAccessMapForResourceContext(
2761 const ResourceContext* context) {
2762 ResourceContextOriginMap::iterator context_index =
2763 context_origin_access_info_map_.find(context);
2764 if (context_index != context_origin_access_info_map_.end())
2765 return context_index->second.get();
2766
2767 context_origin_access_info_map_[context].reset(new OriginAccessInfoMap);
2768 return context_origin_access_info_map_[context].get();
2769 }
2770
2771 bool ResourceDispatcherHostImpl::IsIllegalOrigin(ResourceContext* context,
2772 const GURL& origin,
2773 int child_process_id) {
2774 if (origins_for_access_check_.find(origin.scheme()) ==
2775 origins_for_access_check_.end()) {
2776 return false;
2777 }
2778
2779 OriginAccessInfoMap* origin_access_info_map =
2780 GetOriginAccessMapForResourceContext(
2781 const_cast<const ResourceContext*>(context));
2782 DCHECK(origin_access_info_map);
2783
2784 // If the origin is not found then this URL cannot be committed.
2785 OriginAccessInfoMap::iterator index =
2786 origin_access_info_map->find(origin.host());
2787 if (index == origin_access_info_map->end())
2788 return false;
2789
2790 OriginAccessInfo& access_info = index->second;
2791 // Owner processes are allowed access by default.
2792 if (access_info.owner_processes.find(child_process_id) !=
2793 access_info.owner_processes.end()) {
2794 return false;
2795 }
2796
2797 DCHECK(access_info.access_check_mask >= DENY_FOR_NON_OWNERS &&
2798 access_info.access_check_mask <= ACCESS_CHECK_MASK_LAST);
2799
2800 if (access_info.access_check_mask == DENY_FOR_NON_OWNERS)
2801 return true;
2802
2803 // No need to check for other processes here.
2804 if (access_info.access_check_mask == ALLOW_EVERYTHING)
2805 return false;
2806
2807 // Processes in the other_processes list are allowed.
2808 if (access_info.other_processes.find(child_process_id) !=
2809 access_info.other_processes.end()) {
2810 return false;
2811 }
2812 // The origin being accessed is not allowed for the |child_process_id|.
2813 return true;
2814 }
2815
2610 } // namespace content 2816 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698