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

Side by Side Diff: content/browser/security_exploit_browsertest.cc

Issue 1608573002: RDH: Block a compromised renderer from reusing request ids (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a test Created 4 years, 10 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 <stdint.h> 5 #include <stdint.h>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/containers/hash_tables.h" 8 #include "base/containers/hash_tables.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "content/browser/dom_storage/dom_storage_context_wrapper.h" 12 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
13 #include "content/browser/dom_storage/session_storage_namespace_impl.h" 13 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
14 #include "content/browser/frame_host/navigator.h" 14 #include "content/browser/frame_host/navigator.h"
15 #include "content/browser/frame_host/render_frame_host_impl.h" 15 #include "content/browser/frame_host/render_frame_host_impl.h"
16 #include "content/browser/renderer_host/render_view_host_factory.h" 16 #include "content/browser/renderer_host/render_view_host_factory.h"
17 #include "content/browser/renderer_host/render_view_host_impl.h" 17 #include "content/browser/renderer_host/render_view_host_impl.h"
18 #include "content/browser/web_contents/web_contents_impl.h" 18 #include "content/browser/web_contents/web_contents_impl.h"
19 #include "content/common/frame_messages.h" 19 #include "content/common/frame_messages.h"
20 #include "content/common/resource_messages.h" 20 #include "content/common/resource_messages.h"
21 #include "content/common/view_messages.h" 21 #include "content/common/view_messages.h"
22 #include "content/public/browser/browser_context.h" 22 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/content_browser_client.h" 23 #include "content/public/browser/content_browser_client.h"
24 #include "content/public/browser/interstitial_page.h" 24 #include "content/public/browser/interstitial_page.h"
25 #include "content/public/browser/interstitial_page_delegate.h" 25 #include "content/public/browser/interstitial_page_delegate.h"
26 #include "content/public/browser/resource_dispatcher_host.h"
26 #include "content/public/browser/storage_partition.h" 27 #include "content/public/browser/storage_partition.h"
27 #include "content/public/common/appcache_info.h" 28 #include "content/public/common/appcache_info.h"
28 #include "content/public/common/browser_side_navigation_policy.h" 29 #include "content/public/common/browser_side_navigation_policy.h"
29 #include "content/public/common/content_switches.h" 30 #include "content/public/common/content_switches.h"
30 #include "content/public/common/file_chooser_params.h" 31 #include "content/public/common/file_chooser_params.h"
31 #include "content/public/test/browser_test_utils.h" 32 #include "content/public/test/browser_test_utils.h"
32 #include "content/public/test/content_browser_test.h" 33 #include "content/public/test/content_browser_test.h"
33 #include "content/public/test/content_browser_test_utils.h" 34 #include "content/public/test/content_browser_test_utils.h"
34 #include "content/public/test/test_utils.h" 35 #include "content/public/test/test_utils.h"
35 #include "content/shell/browser/shell.h" 36 #include "content/shell/browser/shell.h"
36 #include "content/test/test_content_browser_client.h" 37 #include "content/test/test_content_browser_client.h"
37 #include "ipc/ipc_security_test_util.h" 38 #include "ipc/ipc_security_test_util.h"
38 #include "net/dns/mock_host_resolver.h" 39 #include "net/dns/mock_host_resolver.h"
39 #include "net/test/embedded_test_server/embedded_test_server.h" 40 #include "net/test/embedded_test_server/embedded_test_server.h"
41 #include "net/test/url_request/url_request_slow_download_job.h"
40 42
41 using IPC::IpcSecurityTestUtil; 43 using IPC::IpcSecurityTestUtil;
42 44
43 namespace content { 45 namespace content {
44 46
45 namespace { 47 namespace {
46 48
47 // This is a helper function for the tests which attempt to create a 49 // This is a helper function for the tests which attempt to create a
48 // duplicate RenderViewHost or RenderWidgetHost. It tries to create two objects 50 // duplicate RenderViewHost or RenderWidgetHost. It tries to create two objects
49 // with the same process and routing ids, which causes a collision. 51 // with the same process and routing ids, which causes a collision.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 else 93 else
92 next_rfh = wc->GetRenderManagerForTesting()->pending_frame_host(); 94 next_rfh = wc->GetRenderManagerForTesting()->pending_frame_host();
93 95
94 EXPECT_TRUE(next_rfh); 96 EXPECT_TRUE(next_rfh);
95 EXPECT_NE(shell->web_contents()->GetRenderProcessHost()->GetID(), 97 EXPECT_NE(shell->web_contents()->GetRenderProcessHost()->GetID(),
96 next_rfh->GetProcess()->GetID()); 98 next_rfh->GetProcess()->GetID());
97 99
98 return next_rfh->render_view_host(); 100 return next_rfh->render_view_host();
99 } 101 }
100 102
101 ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { 103 ResourceHostMsg_Request CreateDefaultRequest() {
mmenke 2016/01/28 16:20:08 Optional: Suggest making this take in a url, and
gzobqq 2016/01/28 20:21:17 Done.
102 ResourceHostMsg_Request request; 104 ResourceHostMsg_Request request;
103 request.method = "GET"; 105 request.method = "GET";
104 request.url = GURL("http://bar.com/simple_page.html"); 106 request.url = GURL("http://bar.com/simple_page.html");
105 request.first_party_for_cookies = GURL(origin);
106 request.referrer_policy = blink::WebReferrerPolicyDefault; 107 request.referrer_policy = blink::WebReferrerPolicyDefault;
107 request.headers = base::StringPrintf("Origin: %s\r\n", origin);
108 request.load_flags = 0; 108 request.load_flags = 0;
109 request.origin_pid = 0; 109 request.origin_pid = 0;
110 request.resource_type = RESOURCE_TYPE_XHR; 110 request.resource_type = RESOURCE_TYPE_XHR;
111 request.request_context = 0; 111 request.request_context = 0;
112 request.appcache_host_id = kAppCacheNoHostId; 112 request.appcache_host_id = kAppCacheNoHostId;
113 request.download_to_file = false; 113 request.download_to_file = false;
114 request.should_reset_appcache = false; 114 request.should_reset_appcache = false;
115 request.is_main_frame = true; 115 request.is_main_frame = true;
116 request.parent_is_main_frame = false; 116 request.parent_is_main_frame = false;
117 request.parent_render_frame_id = -1; 117 request.parent_render_frame_id = -1;
118 request.transition_type = ui::PAGE_TRANSITION_LINK; 118 request.transition_type = ui::PAGE_TRANSITION_LINK;
119 request.allow_download = true; 119 request.allow_download = true;
120 return request; 120 return request;
121 } 121 }
122 122
123 ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) {
124 ResourceHostMsg_Request request = CreateDefaultRequest();
125 request.first_party_for_cookies = GURL(origin);
126 request.headers = base::StringPrintf("Origin: %s\r\n", origin);
127 return request;
128 }
129
130 ResourceHostMsg_Request CreateXHRRequestForURL(const char *url) {
131 ResourceHostMsg_Request request = CreateDefaultRequest();
132 request.url = GURL(url);
133 return request;
134 }
135
136 void TryCreateDuplicateRequestIds(Shell *shell, bool block_loaders) {
137 NavigateToURL(shell, GURL("http://foo.com/simple_page.html"));
138 RenderFrameHost* web_rfh = shell->web_contents()->GetMainFrame();
139
140 if (block_loaders) {
141 // Test the case where loaders are placed into blocked_loaders_map_.
142 int child_id = web_rfh->GetProcess()->GetID();
143 ResourceDispatcherHost::Get()->BlockRequestsForRoute(
144 child_id, web_rfh->GetRoutingID());
mmenke 2016/01/28 16:20:08 This needs to be run on the IO thread, and we're c
gzobqq 2016/01/28 20:21:16 Good catch, done.
145 }
146
147 // URLRequestSlowDownloadJob waits for another request to kFinishDownloadUrl
148 // to finish all pending requests. We never send it, so the following URL
149 // blocks indefinitely, which is good because the request stays alive and we
mmenke 2016/01/28 16:20:08 nit (x2): Avoid "we" in comments, due to ambiguit
gzobqq 2016/01/28 20:21:17 Done.
150 // can try to reuse the request id without a race.
151 const char* blocking_url = net::URLRequestSlowDownloadJob::kUnknownSizeUrl;
152 ResourceHostMsg_Request request(CreateXHRRequestForURL(blocking_url));
153
154 RenderProcessHostWatcher web_process_killed(
155 web_rfh->GetProcess(),
156 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
157 // Use request id 1 twice.
158 IPC::IpcSecurityTestUtil::PwnMessageReceived(
159 web_rfh->GetProcess()->GetChannel(),
160 ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, request));
161 IPC::IpcSecurityTestUtil::PwnMessageReceived(
162 web_rfh->GetProcess()->GetChannel(),
163 ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, request));
164 web_process_killed.Wait();
165 }
166
123 } // namespace 167 } // namespace
124 168
125 169
126 // The goal of these tests will be to "simulate" exploited renderer processes, 170 // The goal of these tests will be to "simulate" exploited renderer processes,
127 // which can send arbitrary IPC messages and confuse browser process internal 171 // which can send arbitrary IPC messages and confuse browser process internal
128 // state, leading to security bugs. We are trying to verify that the browser 172 // state, leading to security bugs. We are trying to verify that the browser
129 // doesn't perform any dangerous operations in such cases. 173 // doesn't perform any dangerous operations in such cases.
130 class SecurityExploitBrowserTest : public ContentBrowserTest { 174 class SecurityExploitBrowserTest : public ContentBrowserTest {
131 public: 175 public:
132 SecurityExploitBrowserTest() {} 176 SecurityExploitBrowserTest() {}
133 177
134 void SetUpCommandLine(base::CommandLine* command_line) override { 178 void SetUpCommandLine(base::CommandLine* command_line) override {
135 ASSERT_TRUE(embedded_test_server()->Start()); 179 ASSERT_TRUE(embedded_test_server()->Start());
136 180
137 // Add a host resolver rule to map all outgoing requests to the test server. 181 // Add a host resolver rule to map all outgoing requests to the test server.
138 // This allows us to use "real" hostnames in URLs, which we can use to 182 // This allows us to use "real" hostnames in URLs, which we can use to
139 // create arbitrary SiteInstances. 183 // create arbitrary SiteInstances.
140 command_line->AppendSwitchASCII( 184 command_line->AppendSwitchASCII(
141 switches::kHostResolverRules, 185 switches::kHostResolverRules,
142 "MAP * " + 186 "MAP * " +
143 net::HostPortPair::FromURL(embedded_test_server()->base_url()) 187 net::HostPortPair::FromURL(embedded_test_server()->base_url())
144 .ToString() + 188 .ToString() +
145 ",EXCLUDE localhost"); 189 ",EXCLUDE localhost");
146 } 190 }
147 191
192 void SetUpOnMainThread() override {
193 BrowserThread::PostTask(
194 BrowserThread::IO, FROM_HERE,
195 base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler));
196 }
197
148 protected: 198 protected:
149 // Tests that a given file path sent in a ViewHostMsg_RunFileChooser will 199 // Tests that a given file path sent in a ViewHostMsg_RunFileChooser will
150 // cause renderer to be killed. 200 // cause renderer to be killed.
151 void TestFileChooserWithPath(const base::FilePath& path); 201 void TestFileChooserWithPath(const base::FilePath& path);
152 }; 202 };
153 203
154 void SecurityExploitBrowserTest::TestFileChooserWithPath( 204 void SecurityExploitBrowserTest::TestFileChooserWithPath(
155 const base::FilePath& path) { 205 const base::FilePath& path) {
156 GURL foo("http://foo.com/simple_page.html"); 206 GURL foo("http://foo.com/simple_page.html");
157 NavigateToURL(shell(), foo); 207 NavigateToURL(shell(), foo);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 NavigateToURL(shell(), web_url); 427 NavigateToURL(shell(), web_url);
378 RenderFrameHost* web_rfh = shell()->web_contents()->GetMainFrame(); 428 RenderFrameHost* web_rfh = shell()->web_contents()->GetMainFrame();
379 429
380 // Web processes cannot make XHRs with chrome:// Origin headers. 430 // Web processes cannot make XHRs with chrome:// Origin headers.
381 { 431 {
382 RenderProcessHostWatcher web_process_killed( 432 RenderProcessHostWatcher web_process_killed(
383 web_rfh->GetProcess(), 433 web_rfh->GetProcess(),
384 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); 434 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
385 IPC::IpcSecurityTestUtil::PwnMessageReceived( 435 IPC::IpcSecurityTestUtil::PwnMessageReceived(
386 web_rfh->GetProcess()->GetChannel(), 436 web_rfh->GetProcess()->GetChannel(),
387 ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, 437 ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1,
mmenke 2016/01/28 16:20:08 These tests make me nervous now - we're depending
gzobqq 2016/01/28 20:21:17 Done.
388 chrome_origin_msg)); 438 chrome_origin_msg));
389 web_process_killed.Wait(); 439 web_process_killed.Wait();
390 } 440 }
391 441
392 // Web processes cannot make XHRs with URLs that the content embedder expects 442 // Web processes cannot make XHRs with URLs that the content embedder expects
393 // to have process isolation. Ideally this would test chrome-extension:// 443 // to have process isolation. Ideally this would test chrome-extension://
394 // URLs for Chrome Apps, but those can't be tested inside content/ and the 444 // URLs for Chrome Apps, but those can't be tested inside content/ and the
395 // ResourceHostMsg_Request IPC can't be created in a test outside content/. 445 // ResourceHostMsg_Request IPC can't be created in a test outside content/.
396 NavigateToURL(shell(), web_url); 446 NavigateToURL(shell(), web_url);
397 { 447 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 web_rfh->GetProcess(), 480 web_rfh->GetProcess(),
431 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); 481 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
432 IPC::IpcSecurityTestUtil::PwnMessageReceived( 482 IPC::IpcSecurityTestUtil::PwnMessageReceived(
433 web_rfh->GetProcess()->GetChannel(), 483 web_rfh->GetProcess()->GetChannel(),
434 ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, 484 ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1,
435 invalid_scheme_origin_msg)); 485 invalid_scheme_origin_msg));
436 web_process_killed.Wait(); 486 web_process_killed.Wait();
437 } 487 }
438 } 488 }
439 489
490 // Renderer process should not be able to create multiple requests with the same
491 // id.
492 IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) {
493 // Existing loader in pending_loaders_.
494 TryCreateDuplicateRequestIds(shell(), false);
495 // Existing loader in blocked_loaders_map_.
496 TryCreateDuplicateRequestIds(shell(), true);
497 }
498
440 } // namespace content 499 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_impl.cc ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698