Index: extensions/browser/extension_navigation_throttle.cc |
diff --git a/extensions/browser/extension_navigation_throttle.cc b/extensions/browser/extension_navigation_throttle.cc |
index bdf1a27af56d003b7374132a946fb4c715992407..8d2061e45d3de694eac4372ecd54f7b0d4877f1a 100644 |
--- a/extensions/browser/extension_navigation_throttle.cc |
+++ b/extensions/browser/extension_navigation_throttle.cc |
@@ -14,6 +14,8 @@ |
#include "extensions/common/extension.h" |
#include "extensions/common/extension_set.h" |
#include "extensions/common/manifest_handlers/web_accessible_resources_info.h" |
+#include "extensions/common/permissions/api_permission.h" |
+#include "extensions/common/permissions/permissions_data.h" |
namespace extensions { |
@@ -26,14 +28,44 @@ ExtensionNavigationThrottle::~ExtensionNavigationThrottle() {} |
content::NavigationThrottle::ThrottleCheckResult |
ExtensionNavigationThrottle::WillStartRequest() { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ GURL url(navigation_handle()->GetURL()); |
+ ExtensionRegistry* registry = ExtensionRegistry::Get( |
+ navigation_handle()->GetWebContents()->GetBrowserContext()); |
+ |
+ if (navigation_handle()->IsInMainFrame()) { |
+ // Block top-level navigations to blob: or filesystem: URLs with extension |
+ // origin from non-extension processes. See https://crbug.com/645028. |
+ bool is_nested_url = url.SchemeIsFileSystem() || url.SchemeIsBlob(); |
+ bool is_extension = false; |
+ if (registry) { |
+ is_extension = !!registry->enabled_extensions().GetExtensionOrAppByURL( |
jam
2016/10/11 19:09:06
fyi this is based on translating the previous chec
nasko
2016/10/12 17:00:35
Ideally, I'd like to keep the process id check as
jam
2016/10/12 22:10:45
The old code didn't check that it was in the map,
alexmos
2016/10/12 23:13:28
Yes, Nasko meant the reverse (what you tried).
|
+ navigation_handle()->GetSiteURL()); |
+ } |
- // This method for now enforces only web_accessible_resources for navigations. |
- // Top-level navigations should always be allowed. |
- DCHECK(!navigation_handle()->IsInMainFrame()); |
+ url::Origin origin(url); |
+ if (is_nested_url && origin.scheme() == extensions::kExtensionScheme && |
+ !is_extension) { |
+ // Relax this restriction for apps that use <webview>. See |
+ // https://crbug.com/652077. |
+ const extensions::Extension* extension = |
+ registry->enabled_extensions().GetByID(origin.host()); |
+ bool has_webview_permission = |
+ extension && |
+ extension->permissions_data()->HasAPIPermission( |
+ extensions::APIPermission::kWebView); |
+ if (!has_webview_permission) |
+ return content::NavigationThrottle::CANCEL; |
+ } |
+ |
+ return content::NavigationThrottle::PROCEED; |
+ } |
+ |
+ // Now enforce web_accessible_resources for navigations. Top-level navigations |
+ // should always be allowed. |
// If the navigation is not to a chrome-extension:// URL, no need to perform |
// any more checks. |
- if (!navigation_handle()->GetURL().SchemeIs(extensions::kExtensionScheme)) |
+ if (!url.SchemeIs(extensions::kExtensionScheme)) |
return content::NavigationThrottle::PROCEED; |
// The subframe which is navigated needs to have all of its ancestors be |
@@ -58,8 +90,7 @@ ExtensionNavigationThrottle::WillStartRequest() { |
content::RenderFrameHost* ancestor = navigating_frame->GetParent(); |
bool external_ancestor = false; |
while (ancestor) { |
- if (ancestor->GetLastCommittedURL().GetOrigin() != |
- navigation_handle()->GetURL().GetOrigin()) { |
+ if (ancestor->GetLastCommittedURL().GetOrigin() != url.GetOrigin()) { |
// Ignore DevTools, as it is allowed to embed extension pages. |
if (!ancestor->GetLastCommittedURL().SchemeIs( |
content::kChromeDevToolsScheme)) { |
@@ -75,15 +106,12 @@ ExtensionNavigationThrottle::WillStartRequest() { |
// Since there was at least one origin different than the navigation URL, |
// explicitly check for the resource in web_accessible_resources. |
- std::string resource_path = navigation_handle()->GetURL().path(); |
- ExtensionRegistry* registry = ExtensionRegistry::Get( |
- navigation_handle()->GetWebContents()->GetBrowserContext()); |
+ std::string resource_path = url.path(); |
if (!registry) |
return content::NavigationThrottle::BLOCK_REQUEST; |
const extensions::Extension* extension = |
- registry->enabled_extensions().GetByID( |
- navigation_handle()->GetURL().host()); |
+ registry->enabled_extensions().GetByID(url.host()); |
if (!extension) |
return content::NavigationThrottle::BLOCK_REQUEST; |