Index: content/browser/security_exploit_browsertest.cc |
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc |
index 2a1be07b9a9a34189f0747fcc329d36c1bd19ec9..68430ad3af7deebdfc00beefeb459d6157cad184 100644 |
--- a/content/browser/security_exploit_browsertest.cc |
+++ b/content/browser/security_exploit_browsertest.cc |
@@ -4,14 +4,18 @@ |
#include "base/command_line.h" |
#include "base/containers/hash_tables.h" |
+#include "base/strings/utf_string_conversions.h" |
#include "content/browser/dom_storage/dom_storage_context_wrapper.h" |
#include "content/browser/dom_storage/session_storage_namespace_impl.h" |
#include "content/browser/frame_host/navigator.h" |
#include "content/browser/renderer_host/render_view_host_factory.h" |
#include "content/browser/renderer_host/render_view_host_impl.h" |
#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/common/frame_messages.h" |
#include "content/common/view_messages.h" |
#include "content/public/browser/browser_context.h" |
+#include "content/public/browser/interstitial_page.h" |
+#include "content/public/browser/interstitial_page_delegate.h" |
#include "content/public/browser/storage_partition.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/test/browser_test_utils.h" |
@@ -19,6 +23,11 @@ |
#include "content/public/test/content_browser_test_utils.h" |
#include "content/public/test/test_utils.h" |
#include "content/shell/browser/shell.h" |
+#include "ipc/ipc_security_test_util.h" |
+#include "net/dns/mock_host_resolver.h" |
+#include "net/test/embedded_test_server/embedded_test_server.h" |
+ |
+using IPC::IpcSecurityTestUtil; |
namespace content { |
@@ -35,10 +44,11 @@ namespace { |
// the attempt is the return value. |
RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell, |
int* target_routing_id) { |
- GURL foo("http://foo.com/files/simple_page.html"); |
+ GURL foo("http://foo.com/simple_page.html"); |
// Start off with initial navigation, so we get the first process allocated. |
NavigateToURL(shell, foo); |
+ EXPECT_EQ(base::ASCIIToUTF16("OK"), shell->web_contents()->GetTitle()); |
Charlie Reis
2014/11/14 00:13:27
I think we can put EXPECT_TRUE on the NavigateToUR
|
// Open another window, so we generate some more routing ids. |
ShellAddedObserver shell2_observer; |
@@ -55,7 +65,7 @@ RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell, |
shell->web_contents()->GetRenderViewHost()->GetRoutingID()); |
// Now, simulate a link click coming from the renderer. |
- GURL extension_url("https://bar.com/files/simple_page.html"); |
+ GURL extension_url("https://bar.com/simple_page.html"); |
WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell->web_contents()); |
wc->GetFrameTree()->root()->navigator()->RequestOpenURL( |
wc->GetFrameTree()->root()->current_frame_host(), extension_url, |
@@ -84,25 +94,37 @@ RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell, |
class SecurityExploitBrowserTest : public ContentBrowserTest { |
public: |
SecurityExploitBrowserTest() {} |
+ |
void SetUpCommandLine(CommandLine* command_line) override { |
- ASSERT_TRUE(test_server()->Start()); |
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
// Add a host resolver rule to map all outgoing requests to the test server. |
// This allows us to use "real" hostnames in URLs, which we can use to |
// create arbitrary SiteInstances. |
command_line->AppendSwitchASCII( |
switches::kHostResolverRules, |
- "MAP * " + test_server()->host_port_pair().ToString() + |
+ "MAP * " + |
+ net::HostPortPair::FromURL(embedded_test_server()->base_url()) |
+ .ToString() + |
",EXCLUDE localhost"); |
} |
}; |
+// Fails because the process kill on Android does not succeed. |
+// http://crbug.com/433068 |
+#if defined(OS_ANDROID) |
+#define MAYBE_SetWebUIProperty DISABLED_SetWebUIProperty |
+#else |
+#define MAYBE_SetWebUIProperty SetWebUIProperty |
+#endif |
+ |
// Ensure that we kill the renderer process if we try to give it WebUI |
// properties and it doesn't have enabled WebUI bindings. |
-IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, SetWebUIProperty) { |
- GURL foo("http://foo.com/files/simple_page.html"); |
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MAYBE_SetWebUIProperty) { |
+ GURL foo("http://foo.com/simple_page.html"); |
NavigateToURL(shell(), foo); |
+ EXPECT_EQ(base::ASCIIToUTF16("OK"), shell()->web_contents()->GetTitle()); |
EXPECT_EQ(0, |
shell()->web_contents()->GetRenderViewHost()->GetEnabledBindings()); |
@@ -166,4 +188,97 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, |
// If the above operation doesn't crash, the test has succeeded! |
} |
+class SecurityExploitTestInterstitialPage : public InterstitialPageDelegate { |
+ public: |
+ explicit SecurityExploitTestInterstitialPage(WebContents* contents) { |
+ InterstitialPage* interstitial = InterstitialPage::Create( |
+ contents, true, contents->GetLastCommittedURL(), this); |
+ interstitial->Show(); |
+ } |
+ |
+ // InterstitialPageDelegate implementation. |
+ void CommandReceived(const std::string& command) override { |
+ last_command_ = command; |
+ } |
+ |
+ std::string GetHTMLContents() override { |
+ return "<html><head><script>" |
+ "window.domAutomationController.setAutomationId(1);" |
+ "window.domAutomationController.send(\"okay\");" |
+ "</script></head>" |
+ "<body>this page is an interstitial</body></html>"; |
+ } |
+ |
+ std::string last_command() { return last_command_; } |
+ |
+ private: |
+ std::string last_command_; |
+ DISALLOW_COPY_AND_ASSIGN(SecurityExploitTestInterstitialPage); |
+}; |
+ |
+// Fails due to InterstitialPage's reliance on PostNonNestableTask |
+// http://crbug.com/432737 |
+#if defined(OS_ANDROID) |
+#define MAYBE_InterstitialCommandFromUnderlyingContent \ |
+ DISABLED_InterstitialCommandFromUnderlyingContent |
+#else |
+#define MAYBE_InterstitialCommandFromUnderlyingContent \ |
+ InterstitialCommandFromUnderlyingContent |
+#endif |
+ |
+// The interstitial should not be controllable by the underlying content. |
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, |
+ MAYBE_InterstitialCommandFromUnderlyingContent) { |
+ // Start off with initial navigation, to allocate the process. |
+ GURL foo("http://foo.com/simple_page.html"); |
+ NavigateToURL(shell(), foo); |
+ EXPECT_EQ(base::ASCIIToUTF16("OK"), shell()->web_contents()->GetTitle()); |
+ |
+ DOMMessageQueue message_queue; |
+ |
+ // Install and show an interstitial page. |
+ SecurityExploitTestInterstitialPage* interstitial = |
+ new SecurityExploitTestInterstitialPage(shell()->web_contents()); |
+ |
+ ASSERT_EQ("", interstitial->last_command()); |
+ content::WaitForInterstitialAttach(shell()->web_contents()); |
+ |
+ InterstitialPage* interstitial_page = |
+ shell()->web_contents()->GetInterstitialPage(); |
+ ASSERT_TRUE(interstitial_page != NULL); |
+ ASSERT_TRUE(shell()->web_contents()->ShowingInterstitialPage()); |
+ ASSERT_TRUE(interstitial_page->GetDelegateForTesting() == interstitial); |
Charlie Reis
2014/11/14 00:13:27
nit: ASSERT_EQ
|
+ |
+ // The interstitial page ought to be able to send a message. |
+ std::string message; |
+ ASSERT_TRUE(message_queue.WaitForMessage(&message)); |
+ ASSERT_EQ("\"okay\"", message); |
+ ASSERT_EQ("\"okay\"", interstitial->last_command()); |
+ |
+ // Send an automation message from the underlying content and wait for it to |
+ // be dispatched on this thread. This message should not be received by the |
+ // interstitial. |
+ content::RenderFrameHost* compromised_renderer = |
+ shell()->web_contents()->GetMainFrame(); |
+ FrameHostMsg_DomOperationResponse evil(compromised_renderer->GetRoutingID(), |
+ "evil", MSG_ROUTING_NONE); |
+ IpcSecurityTestUtil::PwnMessageReceived( |
+ compromised_renderer->GetProcess()->GetChannel(), evil); |
+ |
+ ASSERT_TRUE(message_queue.WaitForMessage(&message)); |
+ ASSERT_EQ("evil", message) |
+ << "Automation message should be received by WebContents."; |
+ ASSERT_EQ("\"okay\"", interstitial->last_command()) |
+ << "Interstitial should not be affected."; |
+ |
+ // Send a second message from the interstitial page, and make sure that the |
+ // "evil" message doesn't arrive in the intervening period. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ interstitial_page->GetRenderViewHostForTesting(), |
+ "window.domAutomationController.send(\"okay2\");")); |
+ ASSERT_TRUE(message_queue.WaitForMessage(&message)); |
+ ASSERT_EQ("\"okay2\"", message); |
+ ASSERT_EQ("\"okay2\"", interstitial->last_command()); |
+} |
+ |
} // namespace content |