OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/site_per_process_browsertest.h" | 5 #include "content/browser/site_per_process_browsertest.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "content/public/common/url_constants.h" | 48 #include "content/public/common/url_constants.h" |
49 #include "content/public/test/browser_test_utils.h" | 49 #include "content/public/test/browser_test_utils.h" |
50 #include "content/public/test/content_browser_test_utils.h" | 50 #include "content/public/test/content_browser_test_utils.h" |
51 #include "content/public/test/test_navigation_observer.h" | 51 #include "content/public/test/test_navigation_observer.h" |
52 #include "content/public/test/test_utils.h" | 52 #include "content/public/test/test_utils.h" |
53 #include "content/test/content_browser_test_utils_internal.h" | 53 #include "content/test/content_browser_test_utils_internal.h" |
54 #include "content/test/test_frame_navigation_observer.h" | 54 #include "content/test/test_frame_navigation_observer.h" |
55 #include "ipc/ipc_security_test_util.h" | 55 #include "ipc/ipc_security_test_util.h" |
56 #include "net/dns/mock_host_resolver.h" | 56 #include "net/dns/mock_host_resolver.h" |
57 #include "net/test/embedded_test_server/embedded_test_server.h" | 57 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 58 #include "testing/gtest/include/gtest/gtest.h" |
58 #include "third_party/WebKit/public/web/WebInputEvent.h" | 59 #include "third_party/WebKit/public/web/WebInputEvent.h" |
59 #include "third_party/WebKit/public/web/WebSandboxFlags.h" | 60 #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
60 #include "ui/display/display_switches.h" | 61 #include "ui/display/display_switches.h" |
61 #include "ui/events/event.h" | 62 #include "ui/events/event.h" |
62 #include "ui/events/event_utils.h" | 63 #include "ui/events/event_utils.h" |
63 #include "ui/gfx/geometry/point.h" | 64 #include "ui/gfx/geometry/point.h" |
64 | 65 |
65 #if defined(USE_AURA) | 66 #if defined(USE_AURA) |
66 #include "content/browser/renderer_host/render_widget_host_view_aura.h" | 67 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
67 #endif | 68 #endif |
(...skipping 6257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6325 // the blocked page is seen as cross-origin. However, those flags shouldn't | 6326 // the blocked page is seen as cross-origin. However, those flags shouldn't |
6326 // affect future navigations for a frame. Verify this for the above | 6327 // affect future navigations for a frame. Verify this for the above |
6327 // navigation. | 6328 // navigation. |
6328 EXPECT_EQ(c_url.GetOrigin().spec(), | 6329 EXPECT_EQ(c_url.GetOrigin().spec(), |
6329 root->child_at(0)->current_origin().Serialize() + "/"); | 6330 root->child_at(0)->current_origin().Serialize() + "/"); |
6330 EXPECT_EQ(blink::WebSandboxFlags::None, | 6331 EXPECT_EQ(blink::WebSandboxFlags::None, |
6331 root->child_at(0)->effective_sandbox_flags()); | 6332 root->child_at(0)->effective_sandbox_flags()); |
6332 } | 6333 } |
6333 } | 6334 } |
6334 | 6335 |
| 6336 // Test that a cross-origin frame's navigation can be blocked by CSP frame-src. |
| 6337 // In this version of a test, CSP comes from HTTP headers. |
| 6338 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 6339 CrossSiteIframeBlockedByParentCSPFromHeaders) { |
| 6340 GURL main_url( |
| 6341 embedded_test_server()->GetURL("a.com", "/frame-src-self-and-b.html")); |
| 6342 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 6343 |
| 6344 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 6345 |
| 6346 // Sanity-check that the test page has the expected shape for testing. |
| 6347 GURL old_subframe_url( |
| 6348 embedded_test_server()->GetURL("b.com", "/title2.html")); |
| 6349 EXPECT_FALSE(root->child_at(0)->HasSameOrigin(*root)); |
| 6350 EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url()); |
| 6351 const std::vector<ContentSecurityPolicyHeader>& root_csp = |
| 6352 root->current_replication_state().accumulated_csp_headers; |
| 6353 EXPECT_EQ(1u, root_csp.size()); |
| 6354 EXPECT_EQ("frame-src 'self' http://b.com:*", root_csp[0].header_value); |
| 6355 |
| 6356 // Monitor subframe's load events via main frame's title. |
| 6357 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), |
| 6358 "document.querySelector('iframe').onload = " |
| 6359 " function() { document.title = 'loaded'; };")); |
| 6360 EXPECT_TRUE( |
| 6361 ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';")); |
| 6362 base::string16 expected_title(base::UTF8ToUTF16("loaded")); |
| 6363 TitleWatcher title_watcher(shell()->web_contents(), expected_title); |
| 6364 |
| 6365 // Try to navigate the subframe to a blocked URL. |
| 6366 TestNavigationObserver load_observer(shell()->web_contents()); |
| 6367 GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html"); |
| 6368 EXPECT_TRUE( |
| 6369 ExecuteScript(root->child_at(0)->current_frame_host(), |
| 6370 "window.location.href = '" + blocked_url.spec() + "';")); |
| 6371 |
| 6372 // The blocked frame should still fire a load event in its parent's process. |
| 6373 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); |
| 6374 |
| 6375 // Check that the current RenderFrameHost has stopped loading. |
| 6376 if (root->child_at(0)->current_frame_host()->is_loading()) { |
| 6377 ADD_FAILURE() << "Blocked RenderFrameHost shouldn't be loading anything"; |
| 6378 load_observer.Wait(); |
| 6379 } |
| 6380 |
| 6381 // The blocked frame should stay at the old location. |
| 6382 EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url()); |
| 6383 |
| 6384 // The blocked frame should keep the old title. |
| 6385 std::string frame_title; |
| 6386 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 6387 root->child_at(0)->current_frame_host(), |
| 6388 "domAutomationController.send(document.title)", &frame_title)); |
| 6389 EXPECT_EQ("Title Of Awesomeness", frame_title); |
| 6390 |
| 6391 // Navigate to a URL without CSP. |
| 6392 EXPECT_TRUE(NavigateToURL( |
| 6393 shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); |
| 6394 |
| 6395 // Verify that the frame's CSP got correctly reset to an empty set. |
| 6396 EXPECT_EQ(0u, |
| 6397 root->current_replication_state().accumulated_csp_headers.size()); |
| 6398 } |
| 6399 |
| 6400 // Test that a cross-origin frame's navigation can be blocked by CSP frame-src. |
| 6401 // In this version of a test, CSP comes from a <meta> element added after the |
| 6402 // page has already loaded. |
| 6403 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 6404 CrossSiteIframeBlockedByParentCSPFromMeta) { |
| 6405 GURL main_url(embedded_test_server()->GetURL( |
| 6406 "a.com", "/cross_site_iframe_factory.html?a(a)")); |
| 6407 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 6408 |
| 6409 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 6410 |
| 6411 // Navigate the subframe to a location we will disallow in the future. |
| 6412 GURL old_subframe_url( |
| 6413 embedded_test_server()->GetURL("b.com", "/title2.html")); |
| 6414 NavigateFrameToURL(root->child_at(0), old_subframe_url); |
| 6415 |
| 6416 // Add frame-src CSP via a new <meta> element. |
| 6417 EXPECT_TRUE(ExecuteScript( |
| 6418 shell()->web_contents(), |
| 6419 "var meta = document.createElement('meta');" |
| 6420 "meta.httpEquiv = 'Content-Security-Policy';" |
| 6421 "meta.content = 'frame-src https://a.com:*';" |
| 6422 "document.getElementsByTagName('head')[0].appendChild(meta);")); |
| 6423 |
| 6424 // Sanity-check that the test page has the expected shape for testing. |
| 6425 // (the CSP should not have an effect on the already loaded frames). |
| 6426 EXPECT_FALSE(root->child_at(0)->HasSameOrigin(*root)); |
| 6427 EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url()); |
| 6428 const std::vector<ContentSecurityPolicyHeader>& root_csp = |
| 6429 root->current_replication_state().accumulated_csp_headers; |
| 6430 EXPECT_EQ(1u, root_csp.size()); |
| 6431 EXPECT_EQ("frame-src https://a.com:*", root_csp[0].header_value); |
| 6432 |
| 6433 // Monitor subframe's load events via main frame's title. |
| 6434 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), |
| 6435 "document.querySelector('iframe').onload = " |
| 6436 " function() { document.title = 'loaded'; };")); |
| 6437 EXPECT_TRUE( |
| 6438 ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';")); |
| 6439 base::string16 expected_title(base::UTF8ToUTF16("loaded")); |
| 6440 TitleWatcher title_watcher(shell()->web_contents(), expected_title); |
| 6441 |
| 6442 // Try to navigate the subframe to a blocked URL. |
| 6443 TestNavigationObserver load_observer2(shell()->web_contents()); |
| 6444 GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html"); |
| 6445 EXPECT_TRUE( |
| 6446 ExecuteScript(root->child_at(0)->current_frame_host(), |
| 6447 "window.location.href = '" + blocked_url.spec() + "';")); |
| 6448 |
| 6449 // The blocked frame should still fire a load event in its parent's process. |
| 6450 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); |
| 6451 |
| 6452 // Check that the current RenderFrameHost has stopped loading. |
| 6453 if (root->child_at(0)->current_frame_host()->is_loading()) { |
| 6454 ADD_FAILURE() << "Blocked RenderFrameHost shouldn't be loading anything"; |
| 6455 load_observer2.Wait(); |
| 6456 } |
| 6457 |
| 6458 // The blocked frame should stay at the old location. |
| 6459 EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url()); |
| 6460 |
| 6461 // The blocked frame should keep the old title. |
| 6462 std::string frame_title; |
| 6463 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 6464 root->child_at(0)->current_frame_host(), |
| 6465 "domAutomationController.send(document.title)", &frame_title)); |
| 6466 EXPECT_EQ("Title Of Awesomeness", frame_title); |
| 6467 } |
| 6468 |
| 6469 // Test that a cross-origin frame's navigation can be blocked by CSP frame-src. |
| 6470 // In this version of a test, CSP is inherited by srcdoc iframe from a parent |
| 6471 // that declared CSP via HTTP headers. Cross-origin frame navigating to a |
| 6472 // blocked location is a child of the srcdoc iframe. |
| 6473 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 6474 CrossSiteIframeBlockedByCSPInheritedBySrcDocParent) { |
| 6475 GURL main_url( |
| 6476 embedded_test_server()->GetURL("a.com", "/frame-src-self-and-b.html")); |
| 6477 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 6478 |
| 6479 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 6480 FrameTreeNode* srcdoc_frame = root->child_at(1); |
| 6481 EXPECT_TRUE(srcdoc_frame != nullptr); |
| 6482 FrameTreeNode* navigating_frame = srcdoc_frame->child_at(0); |
| 6483 EXPECT_TRUE(navigating_frame != nullptr); |
| 6484 |
| 6485 // Sanity-check that the test page has the expected shape for testing. |
| 6486 // (the CSP should not have an effect on the already loaded frames). |
| 6487 GURL old_subframe_url( |
| 6488 embedded_test_server()->GetURL("b.com", "/title2.html")); |
| 6489 EXPECT_TRUE(srcdoc_frame->HasSameOrigin(*root)); |
| 6490 EXPECT_FALSE(srcdoc_frame->HasSameOrigin(*navigating_frame)); |
| 6491 EXPECT_EQ(old_subframe_url, navigating_frame->current_url()); |
| 6492 const std::vector<ContentSecurityPolicyHeader>& srcdoc_csp = |
| 6493 srcdoc_frame->current_replication_state().accumulated_csp_headers; |
| 6494 EXPECT_EQ(1u, srcdoc_csp.size()); |
| 6495 EXPECT_EQ("frame-src 'self' http://b.com:*", srcdoc_csp[0].header_value); |
| 6496 |
| 6497 // Monitor navigating_frame's load events via srcdoc_frame posting |
| 6498 // a message to the parent frame. |
| 6499 EXPECT_TRUE( |
| 6500 ExecuteScript(root->current_frame_host(), |
| 6501 "window.addEventListener('message', function(event) {" |
| 6502 " document.title = event.data;" |
| 6503 "});")); |
| 6504 EXPECT_TRUE(ExecuteScript( |
| 6505 srcdoc_frame->current_frame_host(), |
| 6506 "document.querySelector('iframe').onload = " |
| 6507 " function() { window.top.postMessage('loaded', '*'); };")); |
| 6508 EXPECT_TRUE( |
| 6509 ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';")); |
| 6510 base::string16 expected_title(base::UTF8ToUTF16("loaded")); |
| 6511 TitleWatcher title_watcher(shell()->web_contents(), expected_title); |
| 6512 |
| 6513 // Try to navigate the subframe to a blocked URL. |
| 6514 TestNavigationObserver load_observer2(shell()->web_contents()); |
| 6515 GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html"); |
| 6516 EXPECT_TRUE( |
| 6517 ExecuteScript(navigating_frame->current_frame_host(), |
| 6518 "window.location.href = '" + blocked_url.spec() + "';")); |
| 6519 |
| 6520 // The blocked frame should still fire a load event in its parent's process. |
| 6521 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); |
| 6522 |
| 6523 // Check that the current RenderFrameHost has stopped loading. |
| 6524 if (navigating_frame->current_frame_host()->is_loading()) { |
| 6525 ADD_FAILURE() << "Blocked RenderFrameHost shouldn't be loading anything"; |
| 6526 load_observer2.Wait(); |
| 6527 } |
| 6528 |
| 6529 // The blocked frame should stay at the old location. |
| 6530 EXPECT_EQ(old_subframe_url, navigating_frame->current_url()); |
| 6531 |
| 6532 // The blocked frame should keep the old title. |
| 6533 std::string frame_title; |
| 6534 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 6535 navigating_frame->current_frame_host(), |
| 6536 "domAutomationController.send(document.title)", &frame_title)); |
| 6537 EXPECT_EQ("Title Of Awesomeness", frame_title); |
| 6538 |
| 6539 // Navigate the subframe to a URL without CSP. |
| 6540 NavigateFrameToURL(srcdoc_frame, |
| 6541 embedded_test_server()->GetURL("a.com", "/title1.html")); |
| 6542 |
| 6543 // Verify that the frame's CSP got correctly reset to an empty set. |
| 6544 EXPECT_EQ( |
| 6545 0u, |
| 6546 srcdoc_frame->current_replication_state().accumulated_csp_headers.size()); |
| 6547 } |
| 6548 |
6335 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScreenCoordinates) { | 6549 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScreenCoordinates) { |
6336 GURL main_url(embedded_test_server()->GetURL( | 6550 GURL main_url(embedded_test_server()->GetURL( |
6337 "a.com", "/cross_site_iframe_factory.html?a(b)")); | 6551 "a.com", "/cross_site_iframe_factory.html?a(b)")); |
6338 NavigateToURL(shell(), main_url); | 6552 NavigateToURL(shell(), main_url); |
6339 | 6553 |
6340 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); | 6554 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
6341 FrameTreeNode* child = root->child_at(0); | 6555 FrameTreeNode* child = root->child_at(0); |
6342 | 6556 |
6343 const char* properties[] = {"screenX", "screenY", "outerWidth", | 6557 const char* properties[] = {"screenX", "screenY", "outerWidth", |
6344 "outerHeight"}; | 6558 "outerHeight"}; |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6712 | 6926 |
6713 EXPECT_EQ( | 6927 EXPECT_EQ( |
6714 " Site A ------------ proxies for B\n" | 6928 " Site A ------------ proxies for B\n" |
6715 " +--Site B ------- proxies for A\n" | 6929 " +--Site B ------- proxies for A\n" |
6716 "Where A = http://a.com/\n" | 6930 "Where A = http://a.com/\n" |
6717 " B = http://b.com/", | 6931 " B = http://b.com/", |
6718 DepictFrameTree(root)); | 6932 DepictFrameTree(root)); |
6719 } | 6933 } |
6720 | 6934 |
6721 } // namespace content | 6935 } // namespace content |
OLD | NEW |