 Chromium Code Reviews
 Chromium Code Reviews Issue 1608573002:
  RDH: Block a compromised renderer from reusing request ids  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1608573002:
  RDH: Block a compromised renderer from reusing request ids  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: content/browser/security_exploit_browsertest.cc | 
| diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc | 
| index c515609c576f74cf8fbc60f1a6e8de11c3a19e90..4f07358b4e75f84f9de4aafaea55138e9a27ebde 100644 | 
| --- a/content/browser/security_exploit_browsertest.cc | 
| +++ b/content/browser/security_exploit_browsertest.cc | 
| @@ -23,6 +23,7 @@ | 
| #include "content/public/browser/content_browser_client.h" | 
| #include "content/public/browser/interstitial_page.h" | 
| #include "content/public/browser/interstitial_page_delegate.h" | 
| +#include "content/public/browser/resource_dispatcher_host.h" | 
| #include "content/public/browser/storage_partition.h" | 
| #include "content/public/common/appcache_info.h" | 
| #include "content/public/common/browser_side_navigation_policy.h" | 
| @@ -37,6 +38,7 @@ | 
| #include "ipc/ipc_security_test_util.h" | 
| #include "net/dns/mock_host_resolver.h" | 
| #include "net/test/embedded_test_server/embedded_test_server.h" | 
| +#include "net/test/url_request/url_request_slow_download_job.h" | 
| using IPC::IpcSecurityTestUtil; | 
| @@ -98,13 +100,11 @@ RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell, | 
| return next_rfh->render_view_host(); | 
| } | 
| -ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { | 
| +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.
 | 
| ResourceHostMsg_Request request; | 
| request.method = "GET"; | 
| request.url = GURL("http://bar.com/simple_page.html"); | 
| - request.first_party_for_cookies = GURL(origin); | 
| request.referrer_policy = blink::WebReferrerPolicyDefault; | 
| - request.headers = base::StringPrintf("Origin: %s\r\n", origin); | 
| request.load_flags = 0; | 
| request.origin_pid = 0; | 
| request.resource_type = RESOURCE_TYPE_XHR; | 
| @@ -120,6 +120,50 @@ ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { | 
| return request; | 
| } | 
| +ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { | 
| + ResourceHostMsg_Request request = CreateDefaultRequest(); | 
| + request.first_party_for_cookies = GURL(origin); | 
| + request.headers = base::StringPrintf("Origin: %s\r\n", origin); | 
| + return request; | 
| +} | 
| + | 
| +ResourceHostMsg_Request CreateXHRRequestForURL(const char *url) { | 
| + ResourceHostMsg_Request request = CreateDefaultRequest(); | 
| + request.url = GURL(url); | 
| + return request; | 
| +} | 
| + | 
| +void TryCreateDuplicateRequestIds(Shell *shell, bool block_loaders) { | 
| + NavigateToURL(shell, GURL("http://foo.com/simple_page.html")); | 
| + RenderFrameHost* web_rfh = shell->web_contents()->GetMainFrame(); | 
| + | 
| + if (block_loaders) { | 
| + // Test the case where loaders are placed into blocked_loaders_map_. | 
| + int child_id = web_rfh->GetProcess()->GetID(); | 
| + ResourceDispatcherHost::Get()->BlockRequestsForRoute( | 
| + 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.
 | 
| + } | 
| + | 
| + // URLRequestSlowDownloadJob waits for another request to kFinishDownloadUrl | 
| + // to finish all pending requests. We never send it, so the following URL | 
| + // 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.
 | 
| + // can try to reuse the request id without a race. | 
| + const char* blocking_url = net::URLRequestSlowDownloadJob::kUnknownSizeUrl; | 
| + ResourceHostMsg_Request request(CreateXHRRequestForURL(blocking_url)); | 
| + | 
| + RenderProcessHostWatcher web_process_killed( | 
| + web_rfh->GetProcess(), | 
| + RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); | 
| + // Use request id 1 twice. | 
| + IPC::IpcSecurityTestUtil::PwnMessageReceived( | 
| + web_rfh->GetProcess()->GetChannel(), | 
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, request)); | 
| + IPC::IpcSecurityTestUtil::PwnMessageReceived( | 
| + web_rfh->GetProcess()->GetChannel(), | 
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, request)); | 
| + web_process_killed.Wait(); | 
| +} | 
| + | 
| } // namespace | 
| @@ -145,6 +189,12 @@ class SecurityExploitBrowserTest : public ContentBrowserTest { | 
| ",EXCLUDE localhost"); | 
| } | 
| + void SetUpOnMainThread() override { | 
| + BrowserThread::PostTask( | 
| + BrowserThread::IO, FROM_HERE, | 
| + base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler)); | 
| + } | 
| + | 
| protected: | 
| // Tests that a given file path sent in a ViewHostMsg_RunFileChooser will | 
| // cause renderer to be killed. | 
| @@ -437,4 +487,13 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) { | 
| } | 
| } | 
| +// Renderer process should not be able to create multiple requests with the same | 
| +// id. | 
| +IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) { | 
| + // Existing loader in pending_loaders_. | 
| + TryCreateDuplicateRequestIds(shell(), false); | 
| + // Existing loader in blocked_loaders_map_. | 
| + TryCreateDuplicateRequestIds(shell(), true); | 
| +} | 
| + | 
| } // namespace content |