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

Side by Side Diff: chrome/browser/chrome_security_exploit_browsertest.cc

Issue 2387173005: Lock down creation of "filesystem:chrome-extension://" URLs (Closed)
Patch Set: Add test. 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/macros.h" 6 #include "base/macros.h"
7 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/ui/browser.h" 9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_commands.h" 10 #include "chrome/browser/ui/browser_commands.h"
11 #include "chrome/browser/ui/singleton_tabs.h" 11 #include "chrome/browser/ui/singleton_tabs.h"
12 #include "chrome/browser/ui/tabs/tab_strip_model.h" 12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
13 #include "chrome/test/base/in_process_browser_test.h" 13 #include "chrome/test/base/in_process_browser_test.h"
14 #include "chrome/test/base/ui_test_utils.h" 14 #include "chrome/test/base/ui_test_utils.h"
15 #include "content/common/fileapi/file_system_messages.h"
15 #include "content/common/fileapi/webblob_messages.h" 16 #include "content/common/fileapi/webblob_messages.h"
16 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_types.h" 19 #include "content/public/browser/notification_types.h"
19 #include "content/public/browser/render_frame_host.h" 20 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/render_process_host.h" 21 #include "content/public/browser/render_process_host.h"
21 #include "content/public/browser/resource_request_details.h" 22 #include "content/public/browser/resource_request_details.h"
22 #include "content/public/browser/web_contents_observer.h" 23 #include "content/public/browser/web_contents_observer.h"
23 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
24 #include "content/public/test/browser_test_utils.h" 25 #include "content/public/test/browser_test_utils.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 content::DOMMessageQueue msg_queue; 63 content::DOMMessageQueue msg_queue;
63 64
64 ui_test_utils::NavigateToURL(browser(), foo); 65 ui_test_utils::NavigateToURL(browser(), foo);
65 66
66 std::string status; 67 std::string status;
67 std::string expected_status("0"); 68 std::string expected_status("0");
68 EXPECT_TRUE(msg_queue.WaitForMessage(&status)); 69 EXPECT_TRUE(msg_queue.WaitForMessage(&status));
69 EXPECT_STREQ(status.c_str(), expected_status.c_str()); 70 EXPECT_STREQ(status.c_str(), expected_status.c_str());
70 } 71 }
71 72
73 // A normal renderer process should not be able to create a
74 // blob:chrome-extension:// resource.
72 IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest, 75 IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
73 CreateBlobInExtensionOrigin) { 76 CreateBlobInExtensionOrigin) {
74 ui_test_utils::NavigateToURL( 77 ui_test_utils::NavigateToURL(
75 browser(), 78 browser(),
76 embedded_test_server()->GetURL("a.root-servers.net", "/title1.html")); 79 embedded_test_server()->GetURL("a.root-servers.net", "/title1.html"));
77 80
78 content::RenderFrameHost* rfh = 81 content::RenderFrameHost* rfh =
79 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); 82 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
80 83
81 // All these are attacker controlled values. The UUID is arbitrary. 84 // All these are attacker controlled values. The UUID is arbitrary.
(...skipping 24 matching lines...) Expand all
106 // in |rfh->GetProcess()|. 109 // in |rfh->GetProcess()|.
107 content::RenderProcessHostWatcher crash_observer( 110 content::RenderProcessHostWatcher crash_observer(
108 rfh->GetProcess(), 111 rfh->GetProcess(),
109 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); 112 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
110 IPC::IpcSecurityTestUtil::PwnMessageReceived( 113 IPC::IpcSecurityTestUtil::PwnMessageReceived(
111 rfh->GetProcess()->GetChannel(), 114 rfh->GetProcess()->GetChannel(),
112 BlobHostMsg_RegisterPublicURL( 115 BlobHostMsg_RegisterPublicURL(
113 GURL("blob:" + target_origin + "/" + blob_path), blob_id)); 116 GURL("blob:" + target_origin + "/" + blob_path), blob_id));
114 crash_observer.Wait(); // If the process is killed, this test passes. 117 crash_observer.Wait(); // If the process is killed, this test passes.
115 } 118 }
119
120 // A normal renderer process should not be able to create a
121 // filesystem:chrome-extension:// resource.
122 IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
123 CreateFilesystemURLInExtensionOrigin) {
124 GURL page_url =
125 embedded_test_server()->GetURL("a.root-servers.net", "/title1.html");
126 ui_test_utils::NavigateToURL(browser(), page_url);
127
128 content::RenderFrameHost* rfh =
129 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
130
131 // All these are attacker controlled values. The UUID is arbitrary.
132 std::string blob_id = "2ce53a26-0409-45a3-86e5-f8fb9f5566d8";
133 std::string blob_type = "text/html";
134 std::string blob_contents =
135 "<html><body>pwned.<script>chrome.extensions</script>";
136 std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";
Charlie Reis 2016/10/04 22:19:04 Some cleanup possible here.
ncarter (slow) 2016/10/04 23:09:36 Done.
137
138 // Target the bookmark manager extension.
139 std::string target_origin =
140 "chrome-extension://eemcgdkfndhakfknompkggombfjjjeno";
141 GURL target_url =
142 GURL("filesystem:" + target_origin + "/temporary/exploit.html");
143
144 std::vector<storage::DataElement> data_elements(1);
145 data_elements[0].SetToBytes(blob_contents.c_str(), blob_contents.size());
Charlie Reis 2016/10/04 22:19:04 Move below.
ncarter (slow) 2016/10/04 23:09:36 Done.
146
147 {
148 content::RenderProcessHostWatcher crash_observer(
149 rfh->GetProcess(),
150 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
151
152 IPC::IpcSecurityTestUtil::PwnMessageReceived(
153 rfh->GetProcess()->GetChannel(),
154 FileSystemHostMsg_Create(55, target_url, false, false, false));
155
156 // Wait for the child process to die as a side effect of the unexpected
157 // FileSystemMsg_DidSucceed or FileSystemMsg_DidFail.
158 crash_observer.Wait();
159 }
160
161 // Reload the page.
162 ui_test_utils::NavigateToURL(browser(), page_url);
163 {
164 content::RenderProcessHostWatcher crash_observer(
165 rfh->GetProcess(),
166 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
167
168 // Set up a blob ID and populate it with attacker-controlled value. These
169 // two messages are allowed, because this data is not in any origin.
170 IPC::IpcSecurityTestUtil::PwnMessageReceived(
171 rfh->GetProcess()->GetChannel(),
172 BlobStorageMsg_RegisterBlobUUID(blob_id, blob_type, "",
173 std::set<std::string>()));
174 IPC::IpcSecurityTestUtil::PwnMessageReceived(
175 rfh->GetProcess()->GetChannel(),
176 BlobStorageMsg_StartBuildingBlob(blob_id, data_elements));
177
178 // Write the blob into the file. If successful, this places an
179 // attacker-controlled value in a resource on the extension origin.
180 IPC::IpcSecurityTestUtil::PwnMessageReceived(
181 rfh->GetProcess()->GetChannel(),
182 FileSystemHostMsg_Write(56, target_url, blob_id, 0));
183
184 // Wait for the child process to die as a side effect of the unexpected
185 // FileSystemMsg_DidWrite (if the exploit step succeeded) or
186 // FileSystemMsg_DidFail (if we soft-failed the operation), or a renderer
187 // kill (if we enforced the origin permission with a kill).
188 crash_observer.Wait();
189 }
190
191 // Make sure that the above IPCs did not succeed, and |target_url| gets a 404
192 // response.
193 ui_test_utils::NavigateToURL(browser(), target_url);
194 rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
195 EXPECT_EQ(GURL(target_origin), rfh->GetSiteInstance()->GetSiteURL());
196 std::string body;
197 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
198 rfh, "window.domAutomationController.send(document.body.innerText);",
199 &body));
200 EXPECT_EQ(
Charlie Reis 2016/10/04 22:19:04 Gate this (or the test) on --isolate-extensions mo
ncarter (slow) 2016/10/04 23:09:36 Done.
201 "\nYour file was not found\n\n"
202 "It may have been moved or deleted.\n"
203 "ERR_FILE_NOT_FOUND\n",
204 body);
205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698