Commit 048201a3 authored by lfg's avatar lfg Committed by Commit bot

Allows webview to access extension resources.

BUG=352290

Review URL: https://codereview.chromium.org/573843002

Cr-Commit-Position: refs/heads/master@{#295117}
parent b32ecb13
...@@ -20,10 +20,10 @@ ...@@ -20,10 +20,10 @@
#include "chrome/browser/extensions/chrome_component_extension_resource_manager.h" #include "chrome/browser/extensions/chrome_component_extension_resource_manager.h"
#include "chrome/browser/extensions/chrome_extension_host_delegate.h" #include "chrome/browser/extensions/chrome_extension_host_delegate.h"
#include "chrome/browser/extensions/chrome_process_manager_delegate.h" #include "chrome/browser/extensions/chrome_process_manager_delegate.h"
#include "chrome/browser/extensions/chrome_url_request_util.h"
#include "chrome/browser/extensions/event_router_forwarder.h" #include "chrome/browser/extensions/event_router_forwarder.h"
#include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/extensions/extension_system_factory.h"
#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/url_request_util.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_function_registry.h"
#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs.h"
#include "extensions/browser/pref_names.h" #include "extensions/browser/pref_names.h"
#include "extensions/browser/url_request_util.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
...@@ -125,7 +126,7 @@ ChromeExtensionsBrowserClient::MaybeCreateResourceBundleRequestJob( ...@@ -125,7 +126,7 @@ ChromeExtensionsBrowserClient::MaybeCreateResourceBundleRequestJob(
const base::FilePath& directory_path, const base::FilePath& directory_path,
const std::string& content_security_policy, const std::string& content_security_policy,
bool send_cors_header) { bool send_cors_header) {
return url_request_util::MaybeCreateURLRequestResourceBundleJob( return chrome_url_request_util::MaybeCreateURLRequestResourceBundleJob(
request, request,
network_delegate, network_delegate,
directory_path, directory_path,
...@@ -138,8 +139,13 @@ bool ChromeExtensionsBrowserClient::AllowCrossRendererResourceLoad( ...@@ -138,8 +139,13 @@ bool ChromeExtensionsBrowserClient::AllowCrossRendererResourceLoad(
bool is_incognito, bool is_incognito,
const Extension* extension, const Extension* extension,
InfoMap* extension_info_map) { InfoMap* extension_info_map) {
return url_request_util::AllowCrossRendererResourceLoad( bool allowed = false;
request, is_incognito, extension, extension_info_map); if (chrome_url_request_util::AllowCrossRendererResourceLoad(
request, is_incognito, extension, extension_info_map, &allowed))
return allowed;
// Couldn't determine if resource is allowed. Block the load.
return false;
} }
PrefService* ChromeExtensionsBrowserClient::GetPrefServiceForContext( PrefService* ChromeExtensionsBrowserClient::GetPrefServiceForContext(
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/extensions/url_request_util.h" #include "chrome/browser/extensions/chrome_url_request_util.h"
#include <string> #include <string>
...@@ -20,12 +20,9 @@ ...@@ -20,12 +20,9 @@
#include "extensions/browser/component_extension_resource_manager.h" #include "extensions/browser/component_extension_resource_manager.h"
#include "extensions/browser/extension_protocols.h" #include "extensions/browser/extension_protocols.h"
#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
#include "extensions/browser/info_map.h" #include "extensions/browser/info_map.h"
#include "extensions/browser/url_request_util.h"
#include "extensions/common/file_util.h" #include "extensions/common/file_util.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
#include "extensions/common/manifest_handlers/webview_info.h"
#include "net/base/mime_util.h" #include "net/base/mime_util.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_request_headers.h" #include "net/http/http_request_headers.h"
...@@ -131,76 +128,27 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { ...@@ -131,76 +128,27 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
} // namespace } // namespace
namespace extensions { namespace extensions {
namespace url_request_util { namespace chrome_url_request_util {
bool AllowCrossRendererResourceLoad(net::URLRequest* request, bool AllowCrossRendererResourceLoad(net::URLRequest* request,
bool is_incognito, bool is_incognito,
const Extension* extension, const Extension* extension,
InfoMap* extension_info_map) { InfoMap* extension_info_map,
const content::ResourceRequestInfo* info = bool* allowed) {
content::ResourceRequestInfo::ForRequest(request); if (url_request_util::AllowCrossRendererResourceLoad(
request, is_incognito, extension, extension_info_map, allowed)) {
bool is_guest = false;
// Extensions with webview: allow loading certain resources by guest renderers
// with privileged partition IDs as specified in the manifest file.
WebViewRendererState* web_view_renderer_state =
WebViewRendererState::GetInstance();
std::string partition_id;
is_guest = web_view_renderer_state->GetPartitionID(info->GetChildID(),
&partition_id);
std::string resource_path = request->url().path();
if (is_guest && WebviewInfo::IsResourceWebviewAccessible(
extension, partition_id, resource_path)) {
return true;
}
// If the request is for navigations outside of webviews, then it should be
// allowed. The navigation logic in CrossSiteResourceHandler will properly
// transfer the navigation to a privileged process before it commits.
if (content::IsResourceTypeFrame(info->GetResourceType()) && !is_guest)
return true;
if (!content::PageTransitionIsWebTriggerable(info->GetPageTransition()))
return false;
// The following checks require that we have an actual extension object. If we
// don't have it, allow the request handling to continue with the rest of the
// checks.
if (!extension)
return true;
// Disallow loading of packaged resources for hosted apps. We don't allow
// hybrid hosted/packaged apps. The one exception is access to icons, since
// some extensions want to be able to do things like create their own
// launchers.
std::string resource_root_relative_path =
request->url().path().empty() ? std::string()
: request->url().path().substr(1);
if (extension->is_hosted_app() &&
!IconsInfo::GetIcons(extension)
.ContainsPath(resource_root_relative_path)) {
LOG(ERROR) << "Denying load of " << request->url().spec() << " from "
<< "hosted app.";
return false;
}
// Extensions with web_accessible_resources: allow loading by regular
// renderers. Since not all subresources are required to be listed in a v2
// manifest, we must allow all loads if there are any web accessible
// resources. See http://crbug.com/179127.
if (extension->manifest_version() < 2 ||
WebAccessibleResourcesInfo::HasWebAccessibleResources(extension)) {
return true; return true;
} }
// If there aren't any explicitly marked web accessible resources, the // If there aren't any explicitly marked web accessible resources, the
// load should be allowed only if it is by DevTools. A close approximation is // load should be allowed only if it is by DevTools. A close approximation is
// checking if the extension contains a DevTools page. // checking if the extension contains a DevTools page.
if (!ManifestURL::GetDevToolsPage(extension).is_empty()) if (!ManifestURL::GetDevToolsPage(extension).is_empty()) {
*allowed = true;
return true; return true;
}
// No special exception. Block the load. // Couldn't determine if the resource is allowed or not.
return false; return false;
} }
...@@ -239,14 +187,5 @@ net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob( ...@@ -239,14 +187,5 @@ net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob(
return NULL; return NULL;
} }
bool IsWebViewRequest(net::URLRequest* request) { } // namespace chrome_url_request_util
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
// |info| can be NULL sometimes: http://crbug.com/370070.
if (!info)
return false;
return WebViewRendererState::GetInstance()->IsGuest(info->GetChildID());
}
} // namespace url_request_util
} // namespace extensions } // namespace extensions
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_URL_REQUEST_UTIL_H_ #ifndef CHROME_BROWSER_EXTENSIONS_CHROME_URL_REQUEST_UTIL_H_
#define CHROME_BROWSER_EXTENSIONS_URL_REQUEST_UTIL_H_ #define CHROME_BROWSER_EXTENSIONS_CHROME_URL_REQUEST_UTIL_H_
#include <string> #include <string>
...@@ -23,14 +23,16 @@ class InfoMap; ...@@ -23,14 +23,16 @@ class InfoMap;
// Utilities related to URLRequest jobs for extension resources. See // Utilities related to URLRequest jobs for extension resources. See
// chrome/browser/extensions/extension_protocols_unittest.cc for related tests. // chrome/browser/extensions/extension_protocols_unittest.cc for related tests.
namespace url_request_util { namespace chrome_url_request_util {
// Returns true to allow a chrome-extension:// resource request coming from // Sets allowed=true to allow a chrome-extension:// resource request coming from
// renderer A to access a resource in an extension running in renderer B. // renderer A to access a resource in an extension running in renderer B.\
// Returns false when it couldn't determine if the resource is allowed or not
bool AllowCrossRendererResourceLoad(net::URLRequest* request, bool AllowCrossRendererResourceLoad(net::URLRequest* request,
bool is_incognito, bool is_incognito,
const Extension* extension, const Extension* extension,
InfoMap* extension_info_map); InfoMap* extension_info_map,
bool* allowed);
// Creates a URLRequestJob for loading component extension resources out of // Creates a URLRequestJob for loading component extension resources out of
// a Chrome resource bundle. Returns NULL if the requested resource is not a // a Chrome resource bundle. Returns NULL if the requested resource is not a
...@@ -42,11 +44,7 @@ net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob( ...@@ -42,11 +44,7 @@ net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob(
const std::string& content_security_policy, const std::string& content_security_policy,
bool send_cors_header); bool send_cors_header);
// Returns true if |request| corresponds to a resource request from a } // namespace chrome_url_request_util
// <webview>.
bool IsWebViewRequest(net::URLRequest* request);
} // namespace url_request_util
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_URL_REQUEST_UTIL_H_ #endif // CHROME_BROWSER_EXTENSIONS_CHROME_URL_REQUEST_UTIL_H_
...@@ -93,7 +93,7 @@ scoped_refptr<Extension> CreateTestResponseHeaderExtension() { ...@@ -93,7 +93,7 @@ scoped_refptr<Extension> CreateTestResponseHeaderExtension() {
// This test lives in src/chrome instead of src/extensions because it tests // This test lives in src/chrome instead of src/extensions because it tests
// functionality delegated back to Chrome via ChromeExtensionsBrowserClient. // functionality delegated back to Chrome via ChromeExtensionsBrowserClient.
// See chrome/browser/extensions/url_request_util.cc. // See chrome/browser/extensions/chrome_url_request_util.cc.
class ExtensionProtocolTest : public testing::Test { class ExtensionProtocolTest : public testing::Test {
public: public:
ExtensionProtocolTest() ExtensionProtocolTest()
......
...@@ -551,6 +551,8 @@ ...@@ -551,6 +551,8 @@
'browser/extensions/chrome_notification_observer.h', 'browser/extensions/chrome_notification_observer.h',
'browser/extensions/chrome_process_manager_delegate.cc', 'browser/extensions/chrome_process_manager_delegate.cc',
'browser/extensions/chrome_process_manager_delegate.h', 'browser/extensions/chrome_process_manager_delegate.h',
'browser/extensions/chrome_url_request_util.cc',
'browser/extensions/chrome_url_request_util.h',
'browser/extensions/component_loader.cc', 'browser/extensions/component_loader.cc',
'browser/extensions/component_loader.h', 'browser/extensions/component_loader.h',
'browser/extensions/context_menu_matcher.cc', 'browser/extensions/context_menu_matcher.cc',
...@@ -807,8 +809,6 @@ ...@@ -807,8 +809,6 @@
'browser/extensions/updater/request_queue_impl.h', 'browser/extensions/updater/request_queue_impl.h',
'browser/extensions/updater/safe_manifest_parser.cc', 'browser/extensions/updater/safe_manifest_parser.cc',
'browser/extensions/updater/safe_manifest_parser.h', 'browser/extensions/updater/safe_manifest_parser.h',
'browser/extensions/url_request_util.cc',
'browser/extensions/url_request_util.h',
'browser/extensions/user_script_listener.cc', 'browser/extensions/user_script_listener.cc',
'browser/extensions/user_script_listener.h', 'browser/extensions/user_script_listener.h',
'browser/extensions/user_script_loader.cc', 'browser/extensions/user_script_loader.cc',
......
...@@ -394,6 +394,8 @@ source_set("browser") { ...@@ -394,6 +394,8 @@ source_set("browser") {
"suggest_permission_util.h", "suggest_permission_util.h",
"uninstall_reason.h", "uninstall_reason.h",
"update_observer.h", "update_observer.h",
"url_request_util.cc",
"url_request_util.h",
"value_store/leveldb_value_store.cc", "value_store/leveldb_value_store.cc",
"value_store/leveldb_value_store.h", "value_store/leveldb_value_store.h",
"value_store/testing_value_store.cc", "value_store/testing_value_store.cc",
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/browser/url_request_util.h"
#include <string>
#include "content/public/browser/resource_request_info.h"
#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
#include "extensions/browser/info_map.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
#include "extensions/common/manifest_handlers/webview_info.h"
#include "net/url_request/url_request.h"
namespace extensions {
namespace url_request_util {
bool AllowCrossRendererResourceLoad(net::URLRequest* request,
bool is_incognito,
const Extension* extension,
InfoMap* extension_info_map,
bool* allowed) {
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
// Extensions with webview: allow loading certain resources by guest renderers
// with privileged partition IDs as specified in the manifest file.
std::string partition_id;
bool is_guest = WebViewRendererState::GetInstance()->GetPartitionID(
info->GetChildID(), &partition_id);
std::string resource_path = request->url().path();
if (is_guest && WebviewInfo::IsResourceWebviewAccessible(
extension, partition_id, resource_path)) {
*allowed = true;
return true;
}
// If the request is for navigations outside of webviews, then it should be
// allowed. The navigation logic in CrossSiteResourceHandler will properly
// transfer the navigation to a privileged process before it commits.
if (content::IsResourceTypeFrame(info->GetResourceType()) && !is_guest) {
*allowed = true;
return true;
}
if (!content::PageTransitionIsWebTriggerable(info->GetPageTransition())) {
*allowed = false;
return true;
}
// The following checks require that we have an actual extension object. If we
// don't have it, allow the request handling to continue with the rest of the
// checks.
if (!extension) {
*allowed = true;
return true;
}
// Disallow loading of packaged resources for hosted apps. We don't allow
// hybrid hosted/packaged apps. The one exception is access to icons, since
// some extensions want to be able to do things like create their own
// launchers.
std::string resource_root_relative_path =
request->url().path().empty() ? std::string()
: request->url().path().substr(1);
if (extension->is_hosted_app() &&
!IconsInfo::GetIcons(extension)
.ContainsPath(resource_root_relative_path)) {
LOG(ERROR) << "Denying load of " << request->url().spec() << " from "
<< "hosted app.";
*allowed = false;
return true;
}
// Extensions with web_accessible_resources: allow loading by regular
// renderers. Since not all subresources are required to be listed in a v2
// manifest, we must allow all loads if there are any web accessible
// resources. See http://crbug.com/179127.
if (extension->manifest_version() < 2 ||
WebAccessibleResourcesInfo::HasWebAccessibleResources(extension)) {
*allowed = true;
return true;
}
// Couldn't determine if the resource is allowed or not.
return false;
}
bool IsWebViewRequest(net::URLRequest* request) {
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
// |info| can be NULL sometimes: http://crbug.com/370070.
if (!info)
return false;
return WebViewRendererState::GetInstance()->IsGuest(info->GetChildID());
}
} // namespace url_request_util
} // namespace extensions
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_URL_REQUEST_UTIL_H_
#define EXTENSIONS_BROWSER_URL_REQUEST_UTIL_H_
namespace net {
class URLRequest;
}
namespace extensions {
class Extension;
class InfoMap;
// Utilities related to URLRequest jobs for extension resources. See
// chrome/browser/extensions/extension_protocols_unittest.cc for related tests.
namespace url_request_util {
// Sets allowed=true to allow a chrome-extension:// resource request coming from
// renderer A to access a resource in an extension running in renderer B.\
// Returns false when it couldn't determine if the resource is allowed or not
bool AllowCrossRendererResourceLoad(net::URLRequest* request,
bool is_incognito,
const Extension* extension,
InfoMap* extension_info_map,
bool* allowed);
// Returns true if |request| corresponds to a resource request from a
// <webview>.
bool IsWebViewRequest(net::URLRequest* request);
} // namespace url_request_util
} // namespace extensions
#endif // EXTENSIONS_BROWSER_URL_REQUEST_UTIL_H_
...@@ -667,6 +667,8 @@ ...@@ -667,6 +667,8 @@
'browser/suggest_permission_util.h', 'browser/suggest_permission_util.h',
'browser/uninstall_reason.h', 'browser/uninstall_reason.h',
'browser/update_observer.h', 'browser/update_observer.h',
'browser/url_request_util.cc',
'browser/url_request_util.h',
'browser/value_store/leveldb_value_store.cc', 'browser/value_store/leveldb_value_store.cc',
'browser/value_store/leveldb_value_store.h', 'browser/value_store/leveldb_value_store.h',
'browser/value_store/testing_value_store.cc', 'browser/value_store/testing_value_store.cc',
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/omaha_query_params/omaha_query_params.h" #include "components/omaha_query_params/omaha_query_params.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/context_factory.h" #include "content/public/browser/context_factory.h"
#include "content/public/common/result_codes.h" #include "content/public/common/result_codes.h"
#include "content/shell/browser/shell_devtools_delegate.h" #include "content/shell/browser/shell_devtools_delegate.h"
...@@ -15,6 +16,7 @@ ...@@ -15,6 +16,7 @@
#include "extensions/browser/app_window/apps_client.h" #include "extensions/browser/app_window/apps_client.h"
#include "extensions/browser/browser_context_keyed_service_factories.h" #include "extensions/browser/browser_context_keyed_service_factories.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
#include "extensions/common/constants.cc"
#include "extensions/shell/browser/shell_browser_context.h" #include "extensions/shell/browser/shell_browser_context.h"
#include "extensions/shell/browser/shell_browser_main_delegate.h" #include "extensions/shell/browser/shell_browser_main_delegate.h"
#include "extensions/shell/browser/shell_desktop_controller.h" #include "extensions/shell/browser/shell_desktop_controller.h"
...@@ -96,6 +98,11 @@ void ShellBrowserMainParts::PreEarlyInitialization() { ...@@ -96,6 +98,11 @@ void ShellBrowserMainParts::PreEarlyInitialization() {
int ShellBrowserMainParts::PreCreateThreads() { int ShellBrowserMainParts::PreCreateThreads() {
// TODO(jamescook): Initialize chromeos::CrosSettings here? // TODO(jamescook): Initialize chromeos::CrosSettings here?
content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
kExtensionScheme);
content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
kExtensionResourceScheme);
// Return no error. // Return no error.
return 0; return 0;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_function_registry.h"
#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs.h"
#include "extensions/browser/null_app_sorting.h" #include "extensions/browser/null_app_sorting.h"
#include "extensions/browser/url_request_util.h"
#include "extensions/shell/browser/shell_extension_host_delegate.h" #include "extensions/shell/browser/shell_extension_host_delegate.h"
#include "extensions/shell/browser/shell_extension_system_factory.h" #include "extensions/shell/browser/shell_extension_system_factory.h"
#include "extensions/shell/browser/shell_runtime_api_delegate.h" #include "extensions/shell/browser/shell_runtime_api_delegate.h"
...@@ -127,7 +128,13 @@ bool ShellExtensionsBrowserClient::AllowCrossRendererResourceLoad( ...@@ -127,7 +128,13 @@ bool ShellExtensionsBrowserClient::AllowCrossRendererResourceLoad(
bool is_incognito, bool is_incognito,
const Extension* extension, const Extension* extension,
InfoMap* extension_info_map) { InfoMap* extension_info_map) {
// Note: This may need to change if app_shell supports webview. bool allowed = false;
if (url_request_util::AllowCrossRendererResourceLoad(
request, is_incognito, extension, extension_info_map, &allowed)) {
return allowed;
}
// Couldn't determine if resource is allowed. Block the load.
return false; return false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment