OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/path_service.h" |
12 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
13 #include "chrome/browser/extensions/browser_action_test_util.h" | 14 #include "chrome/browser/extensions/browser_action_test_util.h" |
14 #include "chrome/browser/extensions/extension_browsertest.h" | 15 #include "chrome/browser/extensions/extension_browsertest.h" |
15 #include "chrome/browser/extensions/extension_service.h" | 16 #include "chrome/browser/extensions/extension_service.h" |
16 #include "chrome/browser/extensions/test_extension_dir.h" | 17 #include "chrome/browser/extensions/test_extension_dir.h" |
| 18 #include "chrome/browser/ui/browser_commands.h" |
17 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 19 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 20 #include "chrome/common/chrome_paths.h" |
18 #include "chrome/common/extensions/extension_process_policy.h" | 21 #include "chrome/common/extensions/extension_process_policy.h" |
19 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
20 #include "chrome/test/base/in_process_browser_test.h" | 23 #include "chrome/test/base/in_process_browser_test.h" |
21 #include "chrome/test/base/ui_test_utils.h" | 24 #include "chrome/test/base/ui_test_utils.h" |
| 25 #include "components/guest_view/browser/test_guest_view_manager.h" |
22 #include "content/public/browser/child_process_security_policy.h" | 26 #include "content/public/browser/child_process_security_policy.h" |
23 #include "content/public/browser/notification_service.h" | 27 #include "content/public/browser/notification_service.h" |
24 #include "content/public/browser/render_frame_host.h" | 28 #include "content/public/browser/render_frame_host.h" |
25 #include "content/public/browser/render_process_host.h" | 29 #include "content/public/browser/render_process_host.h" |
26 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
| 31 #include "content/public/common/browser_side_navigation_policy.h" |
27 #include "content/public/test/browser_test_utils.h" | 32 #include "content/public/test/browser_test_utils.h" |
28 #include "content/public/test/test_navigation_observer.h" | 33 #include "content/public/test/test_navigation_observer.h" |
29 #include "content/public/test/test_utils.h" | 34 #include "content/public/test/test_utils.h" |
| 35 #include "extensions/browser/app_window/app_window.h" |
| 36 #include "extensions/browser/app_window/app_window_registry.h" |
30 #include "extensions/browser/process_manager.h" | 37 #include "extensions/browser/process_manager.h" |
| 38 #include "extensions/common/permissions/permissions_data.h" |
31 #include "extensions/common/value_builder.h" | 39 #include "extensions/common/value_builder.h" |
32 #include "extensions/test/background_page_watcher.h" | 40 #include "extensions/test/background_page_watcher.h" |
33 #include "net/dns/mock_host_resolver.h" | 41 #include "net/dns/mock_host_resolver.h" |
34 #include "net/test/embedded_test_server/embedded_test_server.h" | 42 #include "net/test/embedded_test_server/embedded_test_server.h" |
35 | 43 |
36 namespace extensions { | 44 namespace extensions { |
37 | 45 |
38 namespace { | 46 namespace { |
39 | 47 |
40 void AddFrameToSet(std::set<content::RenderFrameHost*>* frames, | 48 void AddFrameToSet(std::set<content::RenderFrameHost*>* frames, |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 EXPECT_EQ(extension_origin, | 863 EXPECT_EQ(extension_origin, |
856 popup->GetMainFrame()->GetLastCommittedOrigin()); | 864 popup->GetMainFrame()->GetLastCommittedOrigin()); |
857 EXPECT_EQ("foo", GetTextContent(popup->GetMainFrame())); | 865 EXPECT_EQ("foo", GetTextContent(popup->GetMainFrame())); |
858 | 866 |
859 EXPECT_EQ(3 + i, | 867 EXPECT_EQ(3 + i, |
860 pm->GetRenderFrameHostsForExtension(extension->id()).size()); | 868 pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
861 EXPECT_EQ(3 + i, pm->GetAllFrames().size()); | 869 EXPECT_EQ(3 + i, pm->GetAllFrames().size()); |
862 } | 870 } |
863 } | 871 } |
864 | 872 |
| 873 // Test that navigations to blob: and filesystem: URLs with extension origins |
| 874 // are disallowed in an unprivileged, non-guest web process when the extension |
| 875 // origin corresponds to a Chrome app with the "webview" permission. See |
| 876 // https://crbug.com/656752. These requests should still be allowed inside |
| 877 // actual <webview> guest processes created by a Chrome app; this is checked in |
| 878 // WebViewTest.Shim_TestBlobURL. |
| 879 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, |
| 880 NestedURLNavigationsToAppBlocked) { |
| 881 // TODO(alexmos): Re-enable this test for PlzNavigate after tightening |
| 882 // nested URL blocking for apps with the "webview" permission in |
| 883 // ExtensionNavigationThrottle and removing the corresponding check from |
| 884 // ChromeExtensionsNetworkDelegate. The latter is incompatible with |
| 885 // PlzNavigate. |
| 886 if (content::IsBrowserSideNavigationEnabled()) |
| 887 return; |
| 888 |
| 889 // Disabling web security is necessary to test the browser enforcement; |
| 890 // without it, the loads in this test would be blocked by |
| 891 // SecurityOrigin::canDisplay() as invalid local resource loads. |
| 892 PrefService* prefs = browser()->profile()->GetPrefs(); |
| 893 prefs->SetBoolean(prefs::kWebKitWebSecurityEnabled, false); |
| 894 |
| 895 // Load a simple app that has the "webview" permission. The app will also |
| 896 // open a <webview> when it's loaded. |
| 897 ASSERT_TRUE(embedded_test_server()->Start()); |
| 898 base::FilePath dir; |
| 899 PathService::Get(chrome::DIR_TEST_DATA, &dir); |
| 900 dir = dir.AppendASCII("extensions") |
| 901 .AppendASCII("platform_apps") |
| 902 .AppendASCII("web_view") |
| 903 .AppendASCII("simple"); |
| 904 const Extension* app = LoadAndLaunchApp(dir); |
| 905 EXPECT_TRUE(app->permissions_data()->HasAPIPermission( |
| 906 extensions::APIPermission::kWebView)); |
| 907 |
| 908 auto app_windows = AppWindowRegistry::Get(browser()->profile()) |
| 909 ->GetAppWindowsForApp(app->id()); |
| 910 EXPECT_EQ(1u, app_windows.size()); |
| 911 content::WebContents* app_tab = (*app_windows.begin())->web_contents(); |
| 912 content::RenderFrameHost* app_rfh = app_tab->GetMainFrame(); |
| 913 url::Origin app_origin(app_rfh->GetLastCommittedOrigin()); |
| 914 EXPECT_EQ(url::Origin(app->url()), app_rfh->GetLastCommittedOrigin()); |
| 915 |
| 916 // Wait for the app's guest WebContents to load. |
| 917 guest_view::TestGuestViewManager* guest_manager = |
| 918 static_cast<guest_view::TestGuestViewManager*>( |
| 919 guest_view::TestGuestViewManager::FromBrowserContext( |
| 920 browser()->profile())); |
| 921 content::WebContents* guest = guest_manager->WaitForSingleGuestCreated(); |
| 922 |
| 923 // There should be two extension frames in ProcessManager: the app's main |
| 924 // page and the background page. |
| 925 ProcessManager* pm = ProcessManager::Get(profile()); |
| 926 EXPECT_EQ(2u, pm->GetAllFrames().size()); |
| 927 EXPECT_EQ(2u, pm->GetRenderFrameHostsForExtension(app->id()).size()); |
| 928 |
| 929 // Create valid blob and filesystem URLs in the app's origin. |
| 930 GURL blob_url(CreateBlobURL(app_rfh, "foo")); |
| 931 EXPECT_EQ(app_origin, url::Origin(blob_url)); |
| 932 GURL filesystem_url(CreateFileSystemURL(app_rfh, "foo")); |
| 933 EXPECT_EQ(app_origin, url::Origin(filesystem_url)); |
| 934 |
| 935 // Create a new tab, unrelated to the app, and navigate it to a web URL. |
| 936 chrome::NewTab(browser()); |
| 937 content::WebContents* web_tab = |
| 938 browser()->tab_strip_model()->GetActiveWebContents(); |
| 939 GURL web_url(embedded_test_server()->GetURL("/title1.html")); |
| 940 ui_test_utils::NavigateToURL(browser(), web_url); |
| 941 EXPECT_NE(web_tab, app_tab); |
| 942 EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess()); |
| 943 |
| 944 // The web process shouldn't have permission to request URLs in the app's |
| 945 // origin, but the guest process should. |
| 946 content::ChildProcessSecurityPolicy* policy = |
| 947 content::ChildProcessSecurityPolicy::GetInstance(); |
| 948 EXPECT_FALSE(policy->HasSpecificPermissionForOrigin( |
| 949 web_tab->GetRenderProcessHost()->GetID(), app_origin)); |
| 950 EXPECT_TRUE(policy->HasSpecificPermissionForOrigin( |
| 951 guest->GetRenderProcessHost()->GetID(), app_origin)); |
| 952 |
| 953 // Try navigating the web tab to each nested URL with the app's origin. This |
| 954 // should be blocked. |
| 955 GURL nested_urls[] = {blob_url, filesystem_url}; |
| 956 for (size_t i = 0; i < arraysize(nested_urls); i++) { |
| 957 content::TestNavigationObserver observer(web_tab); |
| 958 EXPECT_TRUE(ExecuteScript( |
| 959 web_tab, "location.href = '" + nested_urls[i].spec() + "';")); |
| 960 observer.Wait(); |
| 961 EXPECT_NE(nested_urls[i], web_tab->GetLastCommittedURL()); |
| 962 EXPECT_FALSE(app_origin.IsSameOriginWith( |
| 963 web_tab->GetMainFrame()->GetLastCommittedOrigin())); |
| 964 EXPECT_NE("foo", GetTextContent(web_tab->GetMainFrame())); |
| 965 EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess()); |
| 966 |
| 967 EXPECT_EQ(2u, pm->GetAllFrames().size()); |
| 968 EXPECT_EQ(2u, pm->GetRenderFrameHostsForExtension(app->id()).size()); |
| 969 } |
| 970 } |
| 971 |
865 // Verify that a web popup created via window.open from an extension page can | 972 // Verify that a web popup created via window.open from an extension page can |
866 // communicate with the extension page via window.opener. See | 973 // communicate with the extension page via window.opener. See |
867 // https://crbug.com/590068. | 974 // https://crbug.com/590068. |
868 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, | 975 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, |
869 WebPopupFromExtensionMainFrameHasValidOpener) { | 976 WebPopupFromExtensionMainFrameHasValidOpener) { |
870 // Create a simple extension without a background page. | 977 // Create a simple extension without a background page. |
871 const Extension* extension = CreateExtension("Extension", false); | 978 const Extension* extension = CreateExtension("Extension", false); |
872 embedded_test_server()->ServeFilesFromDirectory(extension->path()); | 979 embedded_test_server()->ServeFilesFromDirectory(extension->path()); |
873 ASSERT_TRUE(embedded_test_server()->Start()); | 980 ASSERT_TRUE(embedded_test_server()->Start()); |
874 | 981 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 EXPECT_TRUE(ExecuteScriptAndExtractBool( | 1056 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
950 popup, "window.domAutomationController.send(!!window.opener)", | 1057 popup, "window.domAutomationController.send(!!window.opener)", |
951 &is_opener_defined)); | 1058 &is_opener_defined)); |
952 EXPECT_TRUE(is_opener_defined); | 1059 EXPECT_TRUE(is_opener_defined); |
953 | 1060 |
954 // Verify that postMessage to window.opener works. | 1061 // Verify that postMessage to window.opener works. |
955 VerifyPostMessageToOpener(popup->GetMainFrame(), extension_frame); | 1062 VerifyPostMessageToOpener(popup->GetMainFrame(), extension_frame); |
956 } | 1063 } |
957 | 1064 |
958 } // namespace extensions | 1065 } // namespace extensions |
OLD | NEW |