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

Unified Diff: chrome/browser/chrome_security_exploit_browsertest.cc

Issue 2387173005: Lock down creation of "filesystem:chrome-extension://" URLs (Closed)
Patch Set: Add a histogram. 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/chrome_security_exploit_browsertest.cc
diff --git a/chrome/browser/chrome_security_exploit_browsertest.cc b/chrome/browser/chrome_security_exploit_browsertest.cc
index c95bb562d6bbe45c7bbdbe6b1d24f62d1ba76987..bd5a4fa8de1e79807caf69d1a301d8a7d7d0dd6e 100644
--- a/chrome/browser/chrome_security_exploit_browsertest.cc
+++ b/chrome/browser/chrome_security_exploit_browsertest.cc
@@ -10,8 +10,10 @@
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/extensions/extension_process_policy.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "content/common/fileapi/file_system_messages.h"
jam 2016/10/05 01:34:45 please don't add dependencies to content internals
#include "content/common/fileapi/webblob_messages.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_service.h"
@@ -69,6 +71,8 @@ IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
EXPECT_STREQ(status.c_str(), expected_status.c_str());
}
+// A normal renderer process should not be able to create a
+// blob:chrome-extension:// resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
CreateBlobInExtensionOrigin) {
ui_test_utils::NavigateToURL(
@@ -113,3 +117,93 @@ IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
GURL("blob:" + target_origin + "/" + blob_path), blob_id));
crash_observer.Wait(); // If the process is killed, this test passes.
}
+
+// A normal renderer process should not be able to create a
+// filesystem:chrome-extension:// resource.
+IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
+ CreateFilesystemURLInExtensionOrigin) {
+ GURL page_url =
+ embedded_test_server()->GetURL("a.root-servers.net", "/title1.html");
+ ui_test_utils::NavigateToURL(browser(), page_url);
+
+ content::RenderFrameHost* rfh =
+ browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+
+ // JS code that the attacker would like to run in an extension process.
+ std::string payload = "<html><body>pwned.<script></script>";
+ std::string payload_type = "text/html";
+
+ // Target the bookmark manager extension.
+ std::string target_origin =
+ "chrome-extension://eemcgdkfndhakfknompkggombfjjjeno";
+ GURL target_url =
+ GURL("filesystem:" + target_origin + "/temporary/exploit.html");
+
+ {
+ content::RenderProcessHostWatcher crash_observer(
+ rfh->GetProcess(),
+ content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ rfh->GetProcess()->GetChannel(),
+ FileSystemHostMsg_Create(55, target_url, false, false, false));
+
+ // Wait for the child process to die as a side effect of the unexpected
+ // FileSystemMsg_DidSucceed or FileSystemMsg_DidFail.
+ crash_observer.Wait();
+ }
+
+ // Reload the page.
+ ui_test_utils::NavigateToURL(browser(), page_url);
+ {
+ content::RenderProcessHostWatcher crash_observer(
+ rfh->GetProcess(),
+ content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+
+ // Set up a blob ID and populate it with the attacker-controlled payload.
+ // These two messages are allowed, because this data is not in any origin;
+ // the UUID is arbitrary.
+ std::string blob_id = "2ce53a26-0409-45a3-86e5-f8fb9f5566d8";
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ rfh->GetProcess()->GetChannel(),
+ BlobStorageMsg_RegisterBlobUUID(blob_id, payload_type, "",
+ std::set<std::string>()));
+ std::vector<storage::DataElement> data_elements(1);
+ data_elements[0].SetToBytes(payload.c_str(), payload.size());
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ rfh->GetProcess()->GetChannel(),
+ BlobStorageMsg_StartBuildingBlob(blob_id, data_elements));
+
+ // Write the blob into the file. If successful, this places an
+ // attacker-controlled value in a resource on the extension origin.
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ rfh->GetProcess()->GetChannel(),
+ FileSystemHostMsg_Write(56, target_url, blob_id, 0));
+
+ // Wait for the child process to die as a side effect of the unexpected
+ // FileSystemMsg_DidWrite (if the exploit step succeeded) or
+ // FileSystemMsg_DidFail (if we soft-failed the operation), or a renderer
+ // kill (if we enforced the origin permission with a kill).
+ crash_observer.Wait();
+ }
+
+ // Now navigate to |target_url|. It should not contain |payload|.
+ ui_test_utils::NavigateToURL(browser(), target_url);
+ rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
+ EXPECT_EQ(GURL(target_origin), rfh->GetSiteInstance()->GetSiteURL());
+ std::string body;
+ EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+ rfh, "window.domAutomationController.send(document.body.innerText);",
+ &body));
+ if (extensions::IsIsolateExtensionsEnabled()) {
+ EXPECT_EQ(
+ "\nYour file was not found\n\n"
+ "It may have been moved or deleted.\n"
+ "ERR_FILE_NOT_FOUND\n",
+ body);
+ } else {
+ // Without --isolate-extensions, the above steps must succeed, since
+ // unblessed extension frames are allowed in ordinary renderer processes.
+ EXPECT_EQ("pwned.", body);
+ }
+}
« no previous file with comments | « no previous file | content/browser/child_process_security_policy_impl.cc » ('j') | tools/metrics/histograms/histograms.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698