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

Unified Diff: chrome/browser/extensions/process_manager_browsertest.cc

Issue 2437753003: Tighten IO thread blob/filesystem URL checks for apps with webview permission. (Closed)
Patch Set: Add base::debug::Alias for two vars before DWOC Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/process_manager_browsertest.cc
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc
index 620e8779287d4b74d0820bb886b279f39f69cd43..4eb01637969e0c40940c1723ab6892c13bacad31 100644
--- a/chrome/browser/extensions/process_manager_browsertest.cc
+++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -9,25 +9,33 @@
#include "base/callback.h"
#include "base/macros.h"
+#include "base/path_service.h"
#include "base/run_loop.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_dir.h"
+#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_process_policy.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "components/guest_view/browser/test_guest_view_manager.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
+#include "extensions/browser/app_window/app_window.h"
+#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/process_manager.h"
+#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/value_builder.h"
#include "extensions/test/background_page_watcher.h"
#include "net/dns/mock_host_resolver.h"
@@ -862,6 +870,96 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
}
}
+// Test that navigations to blob: and filesystem: URLs with extension origins
+// are disallowed in an unprivileged, non-guest web process when the extension
+// origin corresponds to a Chrome app with the "webview" permission. See
+// https://crbug.com/656752. These requests should still be allowed inside
+// actual <webview> guest processes created by a Chrome app; this is checked in
+// WebViewTest.Shim_TestBlobURL.
asargent_no_longer_on_chrome 2016/10/20 22:14:25 Maybe I'm missing something, but does this test ac
alexmos 2016/10/21 00:49:59 This test reuses a lot of functionality from the t
asargent_no_longer_on_chrome 2016/10/21 17:33:17 Ok, sounds good.
+IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
+ NestedURLNavigationsToAppBlocked) {
+ // TODO(alexmos): Re-enable this test for PlzNavigate after tightening
+ // nested URL blocking for apps with the "webview" permission in
+ // ExtensionNavigationThrottle and removing the corresponding check from
+ // ChromeExtensionsNetworkDelegate. The latter is incompatible with
+ // PlzNavigate.
+ if (content::IsBrowserSideNavigationEnabled())
+ return;
+
+ // Disabling web security is necessary to test the browser enforcement;
+ // without it, the loads in this test would be blocked by
+ // SecurityOrigin::canDisplay() as invalid local resource loads.
+ PrefService* prefs = browser()->profile()->GetPrefs();
+ prefs->SetBoolean(prefs::kWebKitWebSecurityEnabled, false);
+
+ // Load a simple app that has the "webview" permission. The app will also
+ // open a <webview> when it's loaded.
+ ASSERT_TRUE(embedded_test_server()->Start());
+ base::FilePath dir;
+ PathService::Get(chrome::DIR_TEST_DATA, &dir);
+ dir = dir.AppendASCII("extensions")
+ .AppendASCII("platform_apps")
+ .AppendASCII("web_view")
+ .AppendASCII("simple");
+ const Extension* app = LoadAndLaunchApp(dir);
+ EXPECT_TRUE(app->permissions_data()->HasAPIPermission(
+ extensions::APIPermission::kWebView));
+
+ auto app_windows = AppWindowRegistry::Get(browser()->profile())
+ ->GetAppWindowsForApp(app->id());
+ EXPECT_EQ(1u, app_windows.size());
+ content::WebContents* app_tab = (*app_windows.begin())->web_contents();
+ content::RenderFrameHost* app_rfh = app_tab->GetMainFrame();
+ url::Origin app_origin(app_rfh->GetLastCommittedOrigin());
+ EXPECT_EQ(url::Origin(app->url()), app_rfh->GetLastCommittedOrigin());
+
+ // Wait for the app's guest WebContents to load.
+ guest_view::TestGuestViewManager* guest_manager =
+ static_cast<guest_view::TestGuestViewManager*>(
+ guest_view::TestGuestViewManager::FromBrowserContext(
+ browser()->profile()));
+ content::WebContents* guest = guest_manager->WaitForSingleGuestCreated();
+
+ // Create valid blob and filesystem URLs in the app's origin.
+ GURL blob_url(CreateBlobURL(app_rfh, "foo"));
+ EXPECT_EQ(app_origin, url::Origin(blob_url));
+ GURL filesystem_url(CreateFileSystemURL(app_rfh, "foo"));
+ EXPECT_EQ(app_origin, url::Origin(filesystem_url));
+
+ // Create a new tab, unrelated to the app, and navigate it to a web URL.
+ chrome::NewTab(browser());
+ content::WebContents* web_tab =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ GURL web_url(embedded_test_server()->GetURL("/title1.html"));
+ ui_test_utils::NavigateToURL(browser(), web_url);
+ EXPECT_NE(web_tab, app_tab);
+ EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess());
+
+ // The web process shouldn't have permission to request URLs in the app's
+ // origin, but the guest process should.
+ content::ChildProcessSecurityPolicy* policy =
+ content::ChildProcessSecurityPolicy::GetInstance();
+ EXPECT_FALSE(policy->HasSpecificPermissionForOrigin(
+ web_tab->GetRenderProcessHost()->GetID(), app_origin));
+ EXPECT_TRUE(policy->HasSpecificPermissionForOrigin(
+ guest->GetRenderProcessHost()->GetID(), app_origin));
+
+ // Try navigating the web tab to each nested URL with the app's origin. This
+ // should be blocked.
+ GURL nested_urls[] = {blob_url, filesystem_url};
+ for (size_t i = 0; i < arraysize(nested_urls); i++) {
+ content::TestNavigationObserver observer(web_tab);
+ EXPECT_TRUE(ExecuteScript(
+ web_tab, "location.href = '" + nested_urls[i].spec() + "';"));
+ observer.Wait();
+ EXPECT_NE(nested_urls[i], web_tab->GetLastCommittedURL());
+ EXPECT_FALSE(app_origin.IsSameOriginWith(
+ web_tab->GetMainFrame()->GetLastCommittedOrigin()));
+ EXPECT_NE("foo", GetTextContent(web_tab->GetMainFrame()));
+ EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess());
+ }
+}
+
// Verify that a web popup created via window.open from an extension page can
// communicate with the extension page via window.opener. See
// https://crbug.com/590068.

Powered by Google App Engine
This is Rietveld 408576698