1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "extensions/browser/url_request_util.h" 6 7 #include <string> 8 9 #include "content/public/browser/resource_request_info.h" 10 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" 11 #include "extensions/browser/info_map.h" 12 #include "extensions/common/extension.h" 13 #include "extensions/common/manifest_handlers/icons_handler.h" 14 #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" 15 #include "extensions/common/manifest_handlers/webview_info.h" 16 #include "net/url_request/url_request.h" 17 18 namespace extensions { 19 namespace url_request_util { 20 21 bool AllowCrossRendererResourceLoad(net::URLRequest* request, 22 bool is_incognito, 23 const Extension* extension, 24 InfoMap* extension_info_map, 25 bool* allowed) { 26 const content::ResourceRequestInfo* info = 27 content::ResourceRequestInfo::ForRequest(request); 28 29 // Extensions with webview: allow loading certain resources by guest renderers 30 // with privileged partition IDs as specified in the manifest file. 31 std::string partition_id; 32 bool is_guest = WebViewRendererState::GetInstance()->GetPartitionID( 33 info->GetChildID(), &partition_id); 34 std::string resource_path = request->url().path(); 35 if (is_guest && WebviewInfo::IsResourceWebviewAccessible( 36 extension, partition_id, resource_path)) { 37 *allowed = true; 38 return true; 39 } 40 41 // If the request is for navigations outside of webviews, then it should be 42 // allowed. The navigation logic in CrossSiteResourceHandler will properly 43 // transfer the navigation to a privileged process before it commits. 44 if (content::IsResourceTypeFrame(info->GetResourceType()) && !is_guest) { 45 *allowed = true; 46 return true; 47 } 48 49 if (!ui::PageTransitionIsWebTriggerable(info->GetPageTransition())) { 50 *allowed = false; 51 return true; 52 } 53 54 // The following checks require that we have an actual extension object. If we 55 // don't have it, allow the request handling to continue with the rest of the 56 // checks. 57 if (!extension) { 58 *allowed = true; 59 return true; 60 } 61 62 // Disallow loading of packaged resources for hosted apps. We don't allow 63 // hybrid hosted/packaged apps. The one exception is access to icons, since 64 // some extensions want to be able to do things like create their own 65 // launchers. 66 std::string resource_root_relative_path = 67 request->url().path().empty() ? std::string() 68 : request->url().path().substr(1); 69 if (extension->is_hosted_app() && 70 !IconsInfo::GetIcons(extension) 71 .ContainsPath(resource_root_relative_path)) { 72 LOG(ERROR) << "Denying load of " << request->url().spec() << " from " 73 << "hosted app."; 74 *allowed = false; 75 return true; 76 } 77 78 // Extensions with web_accessible_resources: allow loading by regular 79 // renderers. Since not all subresources are required to be listed in a v2 80 // manifest, we must allow all loads if there are any web accessible 81 // resources. See http://crbug.com/179127. 82 if (extension->manifest_version() < 2 || 83 WebAccessibleResourcesInfo::HasWebAccessibleResources(extension)) { 84 *allowed = true; 85 return true; 86 } 87 88 // Couldn't determine if the resource is allowed or not. 89 return false; 90 } 91 92 bool IsWebViewRequest(net::URLRequest* request) { 93 const content::ResourceRequestInfo* info = 94 content::ResourceRequestInfo::ForRequest(request); 95 // |info| can be NULL sometimes: http://crbug.com/370070. 96 if (!info) 97 return false; 98 return WebViewRendererState::GetInstance()->IsGuest(info->GetChildID()); 99 } 100 101 } // namespace url_request_util 102 } // namespace extensions 103