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

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 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 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/common/extensions/extension_process_policy.h"
13 #include "chrome/test/base/in_process_browser_test.h" 14 #include "chrome/test/base/in_process_browser_test.h"
14 #include "chrome/test/base/ui_test_utils.h" 15 #include "chrome/test/base/ui_test_utils.h"
16 #include "content/common/fileapi/file_system_messages.h"
jam 2016/10/05 01:34:45 please don't add dependencies to content internals
15 #include "content/common/fileapi/webblob_messages.h" 17 #include "content/common/fileapi/webblob_messages.h"
16 #include "content/public/browser/notification_observer.h" 18 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_types.h" 20 #include "content/public/browser/notification_types.h"
19 #include "content/public/browser/render_frame_host.h" 21 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/render_process_host.h" 22 #include "content/public/browser/render_process_host.h"
21 #include "content/public/browser/resource_request_details.h" 23 #include "content/public/browser/resource_request_details.h"
22 #include "content/public/browser/web_contents_observer.h" 24 #include "content/public/browser/web_contents_observer.h"
23 #include "content/public/common/content_switches.h" 25 #include "content/public/common/content_switches.h"
24 #include "content/public/test/browser_test_utils.h" 26 #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; 64 content::DOMMessageQueue msg_queue;
63 65
64 ui_test_utils::NavigateToURL(browser(), foo); 66 ui_test_utils::NavigateToURL(browser(), foo);
65 67
66 std::string status; 68 std::string status;
67 std::string expected_status("0"); 69 std::string expected_status("0");
68 EXPECT_TRUE(msg_queue.WaitForMessage(&status)); 70 EXPECT_TRUE(msg_queue.WaitForMessage(&status));
69 EXPECT_STREQ(status.c_str(), expected_status.c_str()); 71 EXPECT_STREQ(status.c_str(), expected_status.c_str());
70 } 72 }
71 73
74 // A normal renderer process should not be able to create a
75 // blob:chrome-extension:// resource.
72 IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest, 76 IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
73 CreateBlobInExtensionOrigin) { 77 CreateBlobInExtensionOrigin) {
74 ui_test_utils::NavigateToURL( 78 ui_test_utils::NavigateToURL(
75 browser(), 79 browser(),
76 embedded_test_server()->GetURL("a.root-servers.net", "/title1.html")); 80 embedded_test_server()->GetURL("a.root-servers.net", "/title1.html"));
77 81
78 content::RenderFrameHost* rfh = 82 content::RenderFrameHost* rfh =
79 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); 83 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
80 84
81 // All these are attacker controlled values. The UUID is arbitrary. 85 // All these are attacker controlled values. The UUID is arbitrary.
(...skipping 24 matching lines...) Expand all
106 // in |rfh->GetProcess()|. 110 // in |rfh->GetProcess()|.
107 content::RenderProcessHostWatcher crash_observer( 111 content::RenderProcessHostWatcher crash_observer(
108 rfh->GetProcess(), 112 rfh->GetProcess(),
109 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); 113 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
110 IPC::IpcSecurityTestUtil::PwnMessageReceived( 114 IPC::IpcSecurityTestUtil::PwnMessageReceived(
111 rfh->GetProcess()->GetChannel(), 115 rfh->GetProcess()->GetChannel(),
112 BlobHostMsg_RegisterPublicURL( 116 BlobHostMsg_RegisterPublicURL(
113 GURL("blob:" + target_origin + "/" + blob_path), blob_id)); 117 GURL("blob:" + target_origin + "/" + blob_path), blob_id));
114 crash_observer.Wait(); // If the process is killed, this test passes. 118 crash_observer.Wait(); // If the process is killed, this test passes.
115 } 119 }
120
121 // A normal renderer process should not be able to create a
122 // filesystem:chrome-extension:// resource.
123 IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
124 CreateFilesystemURLInExtensionOrigin) {
125 GURL page_url =
126 embedded_test_server()->GetURL("a.root-servers.net", "/title1.html");
127 ui_test_utils::NavigateToURL(browser(), page_url);
128
129 content::RenderFrameHost* rfh =
130 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
131
132 // JS code that the attacker would like to run in an extension process.
133 std::string payload = "<html><body>pwned.<script></script>";
134 std::string payload_type = "text/html";
135
136 // Target the bookmark manager extension.
137 std::string target_origin =
138 "chrome-extension://eemcgdkfndhakfknompkggombfjjjeno";
139 GURL target_url =
140 GURL("filesystem:" + target_origin + "/temporary/exploit.html");
141
142 {
143 content::RenderProcessHostWatcher crash_observer(
144 rfh->GetProcess(),
145 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
146
147 IPC::IpcSecurityTestUtil::PwnMessageReceived(
148 rfh->GetProcess()->GetChannel(),
149 FileSystemHostMsg_Create(55, target_url, false, false, false));
150
151 // Wait for the child process to die as a side effect of the unexpected
152 // FileSystemMsg_DidSucceed or FileSystemMsg_DidFail.
153 crash_observer.Wait();
154 }
155
156 // Reload the page.
157 ui_test_utils::NavigateToURL(browser(), page_url);
158 {
159 content::RenderProcessHostWatcher crash_observer(
160 rfh->GetProcess(),
161 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
162
163 // Set up a blob ID and populate it with the attacker-controlled payload.
164 // These two messages are allowed, because this data is not in any origin;
165 // the UUID is arbitrary.
166 std::string blob_id = "2ce53a26-0409-45a3-86e5-f8fb9f5566d8";
167 IPC::IpcSecurityTestUtil::PwnMessageReceived(
168 rfh->GetProcess()->GetChannel(),
169 BlobStorageMsg_RegisterBlobUUID(blob_id, payload_type, "",
170 std::set<std::string>()));
171 std::vector<storage::DataElement> data_elements(1);
172 data_elements[0].SetToBytes(payload.c_str(), payload.size());
173 IPC::IpcSecurityTestUtil::PwnMessageReceived(
174 rfh->GetProcess()->GetChannel(),
175 BlobStorageMsg_StartBuildingBlob(blob_id, data_elements));
176
177 // Write the blob into the file. If successful, this places an
178 // attacker-controlled value in a resource on the extension origin.
179 IPC::IpcSecurityTestUtil::PwnMessageReceived(
180 rfh->GetProcess()->GetChannel(),
181 FileSystemHostMsg_Write(56, target_url, blob_id, 0));
182
183 // Wait for the child process to die as a side effect of the unexpected
184 // FileSystemMsg_DidWrite (if the exploit step succeeded) or
185 // FileSystemMsg_DidFail (if we soft-failed the operation), or a renderer
186 // kill (if we enforced the origin permission with a kill).
187 crash_observer.Wait();
188 }
189
190 // Now navigate to |target_url|. It should not contain |payload|.
191 ui_test_utils::NavigateToURL(browser(), target_url);
192 rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
193 EXPECT_EQ(GURL(target_origin), rfh->GetSiteInstance()->GetSiteURL());
194 std::string body;
195 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
196 rfh, "window.domAutomationController.send(document.body.innerText);",
197 &body));
198 if (extensions::IsIsolateExtensionsEnabled()) {
199 EXPECT_EQ(
200 "\nYour file was not found\n\n"
201 "It may have been moved or deleted.\n"
202 "ERR_FILE_NOT_FOUND\n",
203 body);
204 } else {
205 // Without --isolate-extensions, the above steps must succeed, since
206 // unblessed extension frames are allowed in ordinary renderer processes.
207 EXPECT_EQ("pwned.", body);
208 }
209 }
OLDNEW
« 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