Apply ExtensionNavigationThrottle filesystem/blob checks to all frames.
BUG=836858
Change-Id: I34333a72501129fd40b5a9aa6378c9f35f1e7fc2
Reviewed-on: https://chromium-review.googlesource.com/1028511
Reviewed-by: Devlin <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Reviewed-by: Nick Carter <[email protected]>
Commit-Queue: Charlie Reis <[email protected]>
Cr-Commit-Position: refs/heads/master@{#553867}
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc
index 78f04bf..bde2056c 100644
--- a/chrome/browser/extensions/process_manager_browsertest.cc
+++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -924,6 +924,73 @@
}
// Test that navigations to blob: and filesystem: URLs with extension origins
+// are disallowed in subframes when initiated from non-extension processes, even
+// when the main frame lies about its origin. See https://crbug.com/836858.
+IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
+ NestedURLNavigationsToExtensionBlockedInSubframe) {
+ // 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);
+
+ // Create a simple extension without a background page.
+ const Extension* extension = CreateExtension("Extension", false);
+ embedded_test_server()->ServeFilesFromDirectory(extension->path());
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ // Navigate main tab to a web page with two web iframes. There should be no
+ // extension frames yet.
+ NavigateToURL(embedded_test_server()->GetURL("/two_iframes.html"));
+ ProcessManager* pm = ProcessManager::Get(profile());
+ EXPECT_EQ(0u, pm->GetAllFrames().size());
+ EXPECT_EQ(0u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
+
+ content::WebContents* tab =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Navigate first subframe to an extension URL. This will go into a new
+ // extension process.
+ const GURL extension_url(extension->url().Resolve("empty.html"));
+ EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame1", extension_url));
+ EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
+ EXPECT_EQ(1u, pm->GetAllFrames().size());
+
+ content::RenderFrameHost* main_frame = tab->GetMainFrame();
+ content::RenderFrameHost* extension_frame = ChildFrameAt(main_frame, 0);
+
+ // Create valid blob and filesystem URLs in the extension's origin.
+ url::Origin extension_origin(extension_frame->GetLastCommittedOrigin());
+ GURL blob_url(CreateBlobURL(extension_frame, "foo"));
+ EXPECT_EQ(extension_origin, url::Origin::Create(blob_url));
+ GURL filesystem_url(CreateFileSystemURL(extension_frame, "foo"));
+ EXPECT_EQ(extension_origin, url::Origin::Create(filesystem_url));
+
+ // Suppose that the main frame's origin incorrectly claims it is an extension,
+ // even though it is not in an extension process. This used to bypass the
+ // checks in ExtensionNavigationThrottle.
+ OverrideLastCommittedOrigin(main_frame, extension_origin);
+
+ // Navigate second subframe to each nested URL from the main frame (i.e.,
+ // from non-extension process). These should be canceled.
+ GURL nested_urls[] = {blob_url, filesystem_url};
+ for (size_t i = 0; i < arraysize(nested_urls); i++) {
+ EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame2", nested_urls[i]));
+ content::RenderFrameHost* second_frame = ChildFrameAt(main_frame, 1);
+
+ EXPECT_NE(nested_urls[i], second_frame->GetLastCommittedURL());
+ EXPECT_FALSE(extension_origin.IsSameOriginWith(
+ second_frame->GetLastCommittedOrigin()));
+ EXPECT_NE("foo", GetTextContent(second_frame));
+ EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
+ EXPECT_EQ(1u, pm->GetAllFrames().size());
+
+ EXPECT_TRUE(
+ content::NavigateIframeToURL(tab, "frame2", GURL(url::kAboutBlankURL)));
+ }
+}
+
+// Test that navigations to blob: and filesystem: URLs with extension origins
// are allowed when initiated from extension processes. See
// https://crbug.com/645028 and https://crbug.com/644426.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,