Commit fb17c42a authored by Karandeep Bhatia's avatar Karandeep Bhatia Committed by Commit Bot

Extensions: Prevent background page from navigating away.

Prevent the extension background page from undergoing a navigation away
from its initial url since this effectively makes the extension
non-functional. Note this doesn't prevent navigations for which the
NavigationThrottles are skipped (e.g. crbug.com/1036603).

BUG=1130083

Change-Id: Ieba83f16520d8631662969c07402e0a49c2bce0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2419659
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810565}
parent 148889ea
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_navigation_observer.h"
#include "extensions/browser/extension_api_frame_id_map.h" #include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_navigation_ui_data.h" #include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/background_info.h"
namespace extensions { namespace extensions {
...@@ -122,6 +124,66 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TabNavigationToPlatformApp) { ...@@ -122,6 +124,66 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TabNavigationToPlatformApp) {
} }
} }
// Ensure that the extension's background page can't be navigated away.
// Regression test for crbug.com/1130083.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, BackgroundPageNavigation) {
ASSERT_TRUE(embedded_test_server()->Start());
const Extension* extension = LoadExtension(
test_data_dir_.AppendASCII("common").AppendASCII("background_page"));
ASSERT_TRUE(extension);
ExtensionHost* host =
ProcessManager::Get(profile())->GetBackgroundHostForExtension(
extension->id());
ASSERT_TRUE(host);
content::WebContents* background_contents = host->web_contents();
// Navigation to a different url should be disallowed.
{
GURL target_url = embedded_test_server()->GetURL("/body1.html");
content::TestNavigationManager navigation_observer(background_contents,
target_url);
constexpr char kScript[] = "window.location.href = '%s'";
ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
extension->id(),
base::StringPrintf(kScript, target_url.spec().c_str())));
navigation_observer.WaitForNavigationFinished();
EXPECT_FALSE(navigation_observer.was_committed());
EXPECT_EQ(extension->GetResourceURL("background.html"),
background_contents->GetLastCommittedURL());
}
// A same-document navigation is still permitted.
{
GURL target_url = extension->GetResourceURL("background.html#fragment");
content::TestNavigationManager navigation_observer(background_contents,
target_url);
constexpr char kScript[] = "window.location.href = '%s'";
ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
extension->id(),
base::StringPrintf(kScript, target_url.spec().c_str())));
navigation_observer.WaitForNavigationFinished();
EXPECT_TRUE(navigation_observer.was_committed());
EXPECT_EQ(target_url, background_contents->GetLastCommittedURL());
}
// Another same-document navigation case.
{
GURL target_url = extension->GetResourceURL("bar.html");
content::TestNavigationManager navigation_observer(background_contents,
target_url);
constexpr char kScript[] = "history.pushState({}, '', '%s')";
ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
extension->id(),
base::StringPrintf(kScript, target_url.spec().c_str())));
navigation_observer.WaitForNavigationFinished();
EXPECT_TRUE(navigation_observer.was_committed());
EXPECT_EQ(target_url, background_contents->GetLastCommittedURL());
}
}
// Test that we correctly set up the ExtensionNavigationUIData for each // Test that we correctly set up the ExtensionNavigationUIData for each
// navigation. // navigation.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ExtensionNavigationUIData) { IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ExtensionNavigationUIData) {
......
<div>Hello World!</div> <div id="fragment">Hello World!</div>
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/guest_view/app_view/app_view_guest.h" #include "extensions/browser/guest_view/app_view/app_view_guest.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h" #include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/url_request_util.h" #include "extensions/browser/url_request_util.h"
#include "extensions/browser/view_type_utils.h" #include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
...@@ -104,10 +106,29 @@ content::NavigationThrottle::ThrottleCheckResult ...@@ -104,10 +106,29 @@ content::NavigationThrottle::ThrottleCheckResult
ExtensionNavigationThrottle::WillStartOrRedirectRequest() { ExtensionNavigationThrottle::WillStartOrRedirectRequest() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
content::WebContents* web_contents = navigation_handle()->GetWebContents(); content::WebContents* web_contents = navigation_handle()->GetWebContents();
ExtensionRegistry* registry = content::BrowserContext* browser_context = web_contents->GetBrowserContext();
ExtensionRegistry::Get(web_contents->GetBrowserContext());
// Prevent the extension's background page from being navigated away. See
// crbug.com/1130083.
if (navigation_handle()->IsInMainFrame()) {
ProcessManager* process_manager = ProcessManager::Get(browser_context);
DCHECK(process_manager);
ExtensionHost* host = process_manager->GetExtensionHostForRenderFrameHost(
web_contents->GetMainFrame());
// Navigation throttles don't intercept same document navigations, hence we
// can ignore that case.
DCHECK(!navigation_handle()->IsSameDocument());
if (host &&
host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE &&
host->initial_url() != navigation_handle()->GetURL()) {
return content::NavigationThrottle::CANCEL;
}
}
// Is this navigation targeting an extension resource? // Is this navigation targeting an extension resource?
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
const GURL& url = navigation_handle()->GetURL(); const GURL& url = navigation_handle()->GetURL();
bool url_has_extension_scheme = url.SchemeIs(kExtensionScheme); bool url_has_extension_scheme = url.SchemeIs(kExtensionScheme);
url::Origin target_origin = url::Origin::Create(url); url::Origin target_origin = url::Origin::Create(url);
......
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