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/path_service.h" |
13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
14 #include "base/test/histogram_tester.h" | |
14 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
15 #include "chrome/browser/extensions/browser_action_test_util.h" | 16 #include "chrome/browser/extensions/browser_action_test_util.h" |
16 #include "chrome/browser/extensions/extension_browsertest.h" | 17 #include "chrome/browser/extensions/extension_browsertest.h" |
17 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
18 #include "chrome/browser/extensions/test_extension_dir.h" | 19 #include "chrome/browser/extensions/test_extension_dir.h" |
19 #include "chrome/browser/ui/browser_commands.h" | 20 #include "chrome/browser/ui/browser_commands.h" |
20 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
21 #include "chrome/common/chrome_paths.h" | 22 #include "chrome/common/chrome_paths.h" |
22 #include "chrome/common/extensions/extension_process_policy.h" | 23 #include "chrome/common/extensions/extension_process_policy.h" |
23 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 IsIsolateExtensionsEnabled() | 247 IsIsolateExtensionsEnabled() |
247 ? if_enabled | 248 ? if_enabled |
248 : if_disabled; | 249 : if_disabled; |
249 } | 250 } |
250 | 251 |
251 content::WebContents* OpenPopup(content::RenderFrameHost* opener, | 252 content::WebContents* OpenPopup(content::RenderFrameHost* opener, |
252 const GURL& url) { | 253 const GURL& url) { |
253 content::WindowedNotificationObserver popup_observer( | 254 content::WindowedNotificationObserver popup_observer( |
254 chrome::NOTIFICATION_TAB_ADDED, | 255 chrome::NOTIFICATION_TAB_ADDED, |
255 content::NotificationService::AllSources()); | 256 content::NotificationService::AllSources()); |
256 EXPECT_TRUE(ExecuteScript(opener, "window.open('" + url.spec() + "')")); | 257 EXPECT_TRUE(ExecuteScript( |
258 opener, "window.popup = window.open('" + url.spec() + "')")); | |
257 popup_observer.Wait(); | 259 popup_observer.Wait(); |
258 content::WebContents* popup = | 260 content::WebContents* popup = |
259 browser()->tab_strip_model()->GetActiveWebContents(); | 261 browser()->tab_strip_model()->GetActiveWebContents(); |
260 WaitForLoadStop(popup); | 262 WaitForLoadStop(popup); |
261 EXPECT_EQ(url, popup->GetMainFrame()->GetLastCommittedURL()); | 263 EXPECT_EQ(url, popup->GetMainFrame()->GetLastCommittedURL()); |
262 return popup; | 264 return popup; |
263 } | 265 } |
264 | 266 |
265 private: | 267 private: |
266 guest_view::TestGuestViewManagerFactory factory_; | 268 guest_view::TestGuestViewManagerFactory factory_; |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
727 EXPECT_TRUE(policy->CanRequestURL( | 729 EXPECT_TRUE(policy->CanRequestURL( |
728 main_frame->GetProcess()->GetID(), | 730 main_frame->GetProcess()->GetID(), |
729 GURL("filesystem:chrome-extension://some-extension-id/some-path"))); | 731 GURL("filesystem:chrome-extension://some-extension-id/some-path"))); |
730 EXPECT_TRUE(policy->CanRequestURL( | 732 EXPECT_TRUE(policy->CanRequestURL( |
731 extension_frame->GetProcess()->GetID(), | 733 extension_frame->GetProcess()->GetID(), |
732 GURL("chrome-extension://some-extension-id/resource.html"))); | 734 GURL("chrome-extension://some-extension-id/resource.html"))); |
733 EXPECT_TRUE(policy->CanRequestURL( | 735 EXPECT_TRUE(policy->CanRequestURL( |
734 main_frame->GetProcess()->GetID(), | 736 main_frame->GetProcess()->GetID(), |
735 GURL("chrome-extension://some-extension-id/resource.html"))); | 737 GURL("chrome-extension://some-extension-id/resource.html"))); |
736 | 738 |
737 if (extensions::IsIsolateExtensionsEnabled()) { | 739 if (IsIsolateExtensionsEnabled()) { |
738 EXPECT_TRUE(policy->CanCommitURL( | 740 EXPECT_TRUE(policy->CanCommitURL( |
739 extension_frame->GetProcess()->GetID(), | 741 extension_frame->GetProcess()->GetID(), |
740 GURL("blob:chrome-extension://some-extension-id/some-guid"))); | 742 GURL("blob:chrome-extension://some-extension-id/some-guid"))); |
741 EXPECT_FALSE(policy->CanCommitURL( | 743 EXPECT_FALSE(policy->CanCommitURL( |
742 main_frame->GetProcess()->GetID(), | 744 main_frame->GetProcess()->GetID(), |
743 GURL("blob:chrome-extension://some-extension-id/some-guid"))); | 745 GURL("blob:chrome-extension://some-extension-id/some-guid"))); |
744 EXPECT_TRUE(policy->CanCommitURL( | 746 EXPECT_TRUE(policy->CanCommitURL( |
745 extension_frame->GetProcess()->GetID(), | 747 extension_frame->GetProcess()->GetID(), |
746 GURL("chrome-extension://some-extension-id/resource.html"))); | 748 GURL("chrome-extension://some-extension-id/resource.html"))); |
747 EXPECT_FALSE(policy->CanCommitURL( | 749 EXPECT_FALSE(policy->CanCommitURL( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 EXPECT_FALSE(extension_origin.IsSameOriginWith( | 789 EXPECT_FALSE(extension_origin.IsSameOriginWith( |
788 popup->GetMainFrame()->GetLastCommittedOrigin())); | 790 popup->GetMainFrame()->GetLastCommittedOrigin())); |
789 EXPECT_NE("foo", GetTextContent(popup->GetMainFrame())); | 791 EXPECT_NE("foo", GetTextContent(popup->GetMainFrame())); |
790 | 792 |
791 EXPECT_EQ(IfExtensionsIsolated(1, 0), | 793 EXPECT_EQ(IfExtensionsIsolated(1, 0), |
792 pm->GetRenderFrameHostsForExtension(extension->id()).size()); | 794 pm->GetRenderFrameHostsForExtension(extension->id()).size()); |
793 EXPECT_EQ(IfExtensionsIsolated(1, 0), pm->GetAllFrames().size()); | 795 EXPECT_EQ(IfExtensionsIsolated(1, 0), pm->GetAllFrames().size()); |
794 } | 796 } |
795 | 797 |
796 // Navigate second subframe to each nested URL from the main frame (i.e., | 798 // Navigate second subframe to each nested URL from the main frame (i.e., |
797 // from non-extension process). | 799 // from non-extension process). This should be blocked in |
800 // --isolate-extensions, but allowed without --isolate-extensions due to | |
801 // unblessed extension frames. | |
798 // | 802 // |
799 // TODO(alexmos): Currently, this is still allowed due to unblessed extension | 803 // TODO(alexmos): This is also temporarily allowed under PlzNavigate, because |
800 // contexts, but in the future such subframe navigations from non-extension | 804 // currently this particular blocking happens in |
801 // processes should be blocked when unblessed contexts go away with | 805 // ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL, which isn't |
802 // --isolate-extensions. | 806 // triggered below under PlzNavigate (since there'll be no transfer). Once |
807 // the blob/filesystem URL checks in ExtensionNavigationThrottle are updated | |
808 // to apply to all frames and not just main frames, the PlzNavigate exception | |
809 // below can be removed. | |
Charlie Reis
2016/11/01 18:12:19
Maybe file a PlzNavigate bug for this? I don't wa
alexmos
2016/11/01 22:04:22
Done - filed https://crbug.com/661324 and mentione
| |
803 for (size_t i = 0; i < arraysize(nested_urls); i++) { | 810 for (size_t i = 0; i < arraysize(nested_urls); i++) { |
804 EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame2", nested_urls[i])); | 811 EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame2", nested_urls[i])); |
805 content::RenderFrameHost* second_frame = ChildFrameAt(main_frame, 1); | 812 content::RenderFrameHost* second_frame = ChildFrameAt(main_frame, 1); |
806 EXPECT_EQ(nested_urls[i], second_frame->GetLastCommittedURL()); | 813 if (IsIsolateExtensionsEnabled() && |
807 EXPECT_EQ(extension_origin, second_frame->GetLastCommittedOrigin()); | 814 !content::IsBrowserSideNavigationEnabled()) { |
808 EXPECT_EQ("foo", GetTextContent(second_frame)); | 815 EXPECT_NE(nested_urls[i], second_frame->GetLastCommittedURL()); |
809 EXPECT_EQ(IfExtensionsIsolated(2, 0), | 816 EXPECT_FALSE(extension_origin.IsSameOriginWith( |
810 pm->GetRenderFrameHostsForExtension(extension->id()).size()); | 817 second_frame->GetLastCommittedOrigin())); |
811 EXPECT_EQ(IfExtensionsIsolated(2, 0), pm->GetAllFrames().size()); | 818 EXPECT_NE("foo", GetTextContent(second_frame)); |
819 EXPECT_EQ(IfExtensionsIsolated(1, 0), | |
820 pm->GetRenderFrameHostsForExtension(extension->id()).size()); | |
821 EXPECT_EQ(IfExtensionsIsolated(1, 0), pm->GetAllFrames().size()); | |
822 } else { | |
823 EXPECT_EQ(nested_urls[i], second_frame->GetLastCommittedURL()); | |
824 EXPECT_EQ(extension_origin, second_frame->GetLastCommittedOrigin()); | |
825 EXPECT_EQ("foo", GetTextContent(second_frame)); | |
826 EXPECT_EQ(IfExtensionsIsolated(2, 0), | |
827 pm->GetRenderFrameHostsForExtension(extension->id()).size()); | |
828 EXPECT_EQ(IfExtensionsIsolated(2, 0), pm->GetAllFrames().size()); | |
829 } | |
830 EXPECT_TRUE( | |
831 content::NavigateIframeToURL(tab, "frame2", GURL(url::kAboutBlankURL))); | |
812 } | 832 } |
813 } | 833 } |
814 | 834 |
815 // Test that navigations to blob: and filesystem: URLs with extension origins | 835 // Test that navigations to blob: and filesystem: URLs with extension origins |
816 // are allowed when initiated from extension processes. See | 836 // are allowed when initiated from extension processes. See |
817 // https://crbug.com/645028 and https://crbug.com/644426. | 837 // https://crbug.com/645028 and https://crbug.com/644426. |
818 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, | 838 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, |
819 NestedURLNavigationsToExtensionAllowed) { | 839 NestedURLNavigationsToExtensionAllowed) { |
820 // Create a simple extension without a background page. | 840 // Create a simple extension without a background page. |
821 const Extension* extension = CreateExtension("Extension", false); | 841 const Extension* extension = CreateExtension("Extension", false); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
969 EXPECT_FALSE(app_origin.IsSameOriginWith( | 989 EXPECT_FALSE(app_origin.IsSameOriginWith( |
970 web_tab->GetMainFrame()->GetLastCommittedOrigin())); | 990 web_tab->GetMainFrame()->GetLastCommittedOrigin())); |
971 EXPECT_NE("foo", GetTextContent(web_tab->GetMainFrame())); | 991 EXPECT_NE("foo", GetTextContent(web_tab->GetMainFrame())); |
972 EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess()); | 992 EXPECT_NE(web_tab->GetMainFrame()->GetProcess(), app_rfh->GetProcess()); |
973 | 993 |
974 EXPECT_EQ(2u, pm->GetAllFrames().size()); | 994 EXPECT_EQ(2u, pm->GetAllFrames().size()); |
975 EXPECT_EQ(2u, pm->GetRenderFrameHostsForExtension(app->id()).size()); | 995 EXPECT_EQ(2u, pm->GetRenderFrameHostsForExtension(app->id()).size()); |
976 } | 996 } |
977 } | 997 } |
978 | 998 |
999 // Test that a web frame can't navigate a proxy for an extension frame to a | |
1000 // blob/filesystem extension URL. See https://crbug.com/656752. | |
1001 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, | |
1002 NestedURLNavigationsViaProxyBlocked) { | |
1003 base::HistogramTester uma; | |
1004 // Create a simple extension without a background page. | |
1005 const Extension* extension = CreateExtension("Extension", false); | |
1006 embedded_test_server()->ServeFilesFromDirectory(extension->path()); | |
1007 ASSERT_TRUE(embedded_test_server()->Start()); | |
1008 | |
1009 // Navigate main tab to an empty web page. There should be no extension | |
1010 // frames yet. | |
1011 NavigateToURL(embedded_test_server()->GetURL("/empty.html")); | |
1012 ProcessManager* pm = ProcessManager::Get(profile()); | |
1013 EXPECT_EQ(0u, pm->GetAllFrames().size()); | |
1014 EXPECT_EQ(0u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); | |
1015 | |
1016 content::WebContents* tab = | |
1017 browser()->tab_strip_model()->GetActiveWebContents(); | |
1018 content::RenderFrameHost* main_frame = tab->GetMainFrame(); | |
1019 | |
1020 // Open a new about:blank popup from main frame. This should stay in the web | |
1021 // process. | |
1022 content::WebContents* popup = | |
1023 OpenPopup(main_frame, GURL(url::kAboutBlankURL)); | |
1024 EXPECT_NE(popup, tab); | |
1025 ASSERT_EQ(2, browser()->tab_strip_model()->count()); | |
1026 EXPECT_EQ(0u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); | |
1027 EXPECT_EQ(0u, pm->GetAllFrames().size()); | |
1028 | |
1029 // Navigate popup to an extension page. | |
1030 const GURL extension_url(extension->url().Resolve("empty.html")); | |
1031 content::TestNavigationObserver observer(popup); | |
1032 EXPECT_TRUE( | |
1033 ExecuteScript(popup, "location.href = '" + extension_url.spec() + "';")); | |
1034 observer.Wait(); | |
1035 EXPECT_EQ(1u, pm->GetAllFrames().size()); | |
1036 EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); | |
1037 content::RenderFrameHost* extension_frame = popup->GetMainFrame(); | |
1038 | |
1039 // Create valid blob and filesystem URLs in the extension's origin. | |
1040 url::Origin extension_origin(extension_frame->GetLastCommittedOrigin()); | |
1041 GURL blob_url(CreateBlobURL(extension_frame, "foo")); | |
1042 EXPECT_EQ(extension_origin, url::Origin(blob_url)); | |
1043 GURL filesystem_url(CreateFileSystemURL(extension_frame, "foo")); | |
1044 EXPECT_EQ(extension_origin, url::Origin(filesystem_url)); | |
1045 | |
1046 // Have the web page navigate the popup to each nested URL with extension | |
1047 // origin via the window reference it obtained earlier from window.open. | |
1048 GURL nested_urls[] = {blob_url, filesystem_url}; | |
1049 for (size_t i = 0; i < arraysize(nested_urls); i++) { | |
1050 EXPECT_TRUE(ExecuteScript( | |
1051 tab, "window.popup.location.href = '" + nested_urls[i].spec() + "';")); | |
1052 WaitForLoadStop(popup); | |
1053 | |
1054 // This is a top-level navigation that should be blocked since it | |
1055 // originates from a non-extension process. Ensure that the popup stays at | |
1056 // the original page and doesn't navigate to the nested URL. | |
1057 EXPECT_NE(nested_urls[i], popup->GetLastCommittedURL()); | |
1058 EXPECT_NE("foo", GetTextContent(popup->GetMainFrame())); | |
1059 | |
1060 EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size()); | |
1061 EXPECT_EQ(1u, pm->GetAllFrames().size()); | |
1062 } | |
1063 | |
1064 // Verify that the blocking was recorded correctly in UMA. | |
1065 uma.ExpectTotalCount("Extensions.ShouldAllowOpenURL.Failure", 2); | |
1066 uma.ExpectBucketCount("Extensions.ShouldAllowOpenURL.Failure", | |
1067 0 /* FAILURE_FILE_SYSTEM_URL */, 1); | |
1068 uma.ExpectBucketCount("Extensions.ShouldAllowOpenURL.Failure", | |
1069 1 /* FAILURE_BLOB_URL */, 1); | |
1070 } | |
1071 | |
979 // Verify that a web popup created via window.open from an extension page can | 1072 // Verify that a web popup created via window.open from an extension page can |
980 // communicate with the extension page via window.opener. See | 1073 // communicate with the extension page via window.opener. See |
981 // https://crbug.com/590068. | 1074 // https://crbug.com/590068. |
982 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, | 1075 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, |
983 WebPopupFromExtensionMainFrameHasValidOpener) { | 1076 WebPopupFromExtensionMainFrameHasValidOpener) { |
984 // Create a simple extension without a background page. | 1077 // Create a simple extension without a background page. |
985 const Extension* extension = CreateExtension("Extension", false); | 1078 const Extension* extension = CreateExtension("Extension", false); |
986 embedded_test_server()->ServeFilesFromDirectory(extension->path()); | 1079 embedded_test_server()->ServeFilesFromDirectory(extension->path()); |
987 ASSERT_TRUE(embedded_test_server()->Start()); | 1080 ASSERT_TRUE(embedded_test_server()->Start()); |
988 | 1081 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1063 EXPECT_TRUE(ExecuteScriptAndExtractBool( | 1156 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
1064 popup, "window.domAutomationController.send(!!window.opener)", | 1157 popup, "window.domAutomationController.send(!!window.opener)", |
1065 &is_opener_defined)); | 1158 &is_opener_defined)); |
1066 EXPECT_TRUE(is_opener_defined); | 1159 EXPECT_TRUE(is_opener_defined); |
1067 | 1160 |
1068 // Verify that postMessage to window.opener works. | 1161 // Verify that postMessage to window.opener works. |
1069 VerifyPostMessageToOpener(popup->GetMainFrame(), extension_frame); | 1162 VerifyPostMessageToOpener(popup->GetMainFrame(), extension_frame); |
1070 } | 1163 } |
1071 | 1164 |
1072 } // namespace extensions | 1165 } // namespace extensions |
OLD | NEW |