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

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

Issue 1957783002: Replicate Content-Security-Policy into remote frame proxies. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing CSP inheritance for srcdoc. Created 4 years, 7 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) 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
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/gmock/include/gmock/gmock.h"
59 #include "testing/gtest/include/gtest/gtest.h"
58 #include "third_party/WebKit/public/web/WebInputEvent.h" 60 #include "third_party/WebKit/public/web/WebInputEvent.h"
59 #include "third_party/WebKit/public/web/WebSandboxFlags.h" 61 #include "third_party/WebKit/public/web/WebSandboxFlags.h"
60 #include "ui/display/display_switches.h" 62 #include "ui/display/display_switches.h"
61 #include "ui/events/event.h" 63 #include "ui/events/event.h"
62 #include "ui/events/event_utils.h" 64 #include "ui/events/event_utils.h"
63 #include "ui/gfx/geometry/point.h" 65 #include "ui/gfx/geometry/point.h"
64 66
65 #if defined(USE_AURA) 67 #if defined(USE_AURA)
66 #include "content/browser/renderer_host/render_widget_host_view_aura.h" 68 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
67 #endif 69 #endif
68 70
69 #if defined(OS_MACOSX) 71 #if defined(OS_MACOSX)
70 #include "ui/base/test/scoped_preferred_scroller_style_mac.h" 72 #include "ui/base/test/scoped_preferred_scroller_style_mac.h"
71 #endif 73 #endif
72 74
73 namespace content { 75 namespace content {
74 76
77 using testing::MatchesRegex;
78
75 namespace { 79 namespace {
76 80
77 // Helper function to send a postMessage and wait for a reply message. The 81 // Helper function to send a postMessage and wait for a reply message. The
78 // |post_message_script| is executed on the |sender_ftn| frame, and the sender 82 // |post_message_script| is executed on the |sender_ftn| frame, and the sender
79 // frame is expected to post |reply_status| from the DOMAutomationController 83 // frame is expected to post |reply_status| from the DOMAutomationController
80 // when it receives a reply. 84 // when it receives a reply.
81 void PostMessageAndWaitForReply(FrameTreeNode* sender_ftn, 85 void PostMessageAndWaitForReply(FrameTreeNode* sender_ftn,
82 const std::string& post_message_script, 86 const std::string& post_message_script,
83 const std::string& reply_status) { 87 const std::string& reply_status) {
84 // Subtle: msg_queue needs to be declared before the ExecuteScript below, or 88 // Subtle: msg_queue needs to be declared before the ExecuteScript below, or
(...skipping 6087 matching lines...) Expand 10 before | Expand all | Expand 10 after
6172 // the blocked page is seen as cross-origin. However, those flags shouldn't 6176 // the blocked page is seen as cross-origin. However, those flags shouldn't
6173 // affect future navigations for a frame. Verify this for the above 6177 // affect future navigations for a frame. Verify this for the above
6174 // navigation. 6178 // navigation.
6175 EXPECT_EQ(c_url.GetOrigin().spec(), 6179 EXPECT_EQ(c_url.GetOrigin().spec(),
6176 root->child_at(0)->current_origin().Serialize() + "/"); 6180 root->child_at(0)->current_origin().Serialize() + "/");
6177 EXPECT_EQ(blink::WebSandboxFlags::None, 6181 EXPECT_EQ(blink::WebSandboxFlags::None,
6178 root->child_at(0)->effective_sandbox_flags()); 6182 root->child_at(0)->effective_sandbox_flags());
6179 } 6183 }
6180 } 6184 }
6181 6185
6186 // Test that a cross-origin frame's navigation can be blocked by CSP frame-src.
6187 // In this version of a test, CSP comes from HTTP headers.
6188 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
6189 CrossSiteIframeBlockedByParentCSPFromHeaders) {
6190 GURL main_url(
6191 embedded_test_server()->GetURL("a.com", "/frame-src-self-and-b.html"));
6192 NavigateToURL(shell(), main_url);
alexmos 2016/05/16 16:17:03 nit: EXPECT_TRUE (also below)
Łukasz Anforowicz 2016/05/16 19:44:45 Done (but only for the 3 new tests... :-/ ).
6193
6194 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
6195
6196 // Sanity-check that the test page has the expected shape for testing.
6197 EXPECT_FALSE(root->child_at(0)->HasSameOrigin(*root));
6198 EXPECT_THAT(root->child_at(0)->current_url().spec(),
6199 MatchesRegex("http://b.com.*/title2.html"));
alexmos 2016/05/16 16:17:03 Why not just check against the exact URL, embedded
Łukasz Anforowicz 2016/05/16 19:44:45 Good idea. Done.
6200
6201 // Monitor subframe's load events via main frame's title.
6202 EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
6203 "document.querySelector('iframe').onload = "
6204 " function() { document.title = 'loaded'; };"));
6205 EXPECT_TRUE(
6206 ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';"));
6207 base::string16 expected_title(base::UTF8ToUTF16("loaded"));
6208 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
6209
6210 // Try to navigate the subframe to a blocked URL.
6211 TestNavigationObserver load_observer(shell()->web_contents());
6212 GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html");
6213 EXPECT_TRUE(
6214 ExecuteScript(root->child_at(0)->current_frame_host(),
6215 "window.location.href = '" + blocked_url.spec() + "';"));
6216
6217 // The blocked frame should still fire a load event in its parent's process.
6218 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
6219
6220 // Check that the current RenderFrameHost has stopped loading.
6221 if (root->child_at(0)->current_frame_host()->is_loading()) {
6222 ADD_FAILURE() << "Blocked RenderFrameHost shouldn't be loading anything";
6223 load_observer.Wait();
6224 }
6225
6226 // The blocked frame should stay at the old location.
6227 EXPECT_THAT(root->child_at(0)->current_url().spec(),
6228 MatchesRegex("http://b.com.*/title2.html"));
6229
6230 // The blocked frame should keep the old title.
6231 std::string frame_title;
6232 EXPECT_TRUE(ExecuteScriptAndExtractString(
6233 root->child_at(0)->current_frame_host(),
6234 "domAutomationController.send(document.title)", &frame_title));
6235 EXPECT_EQ("Title Of Awesomeness", frame_title);
6236 }
6237
6238 // Test that a cross-origin frame's navigation can be blocked by CSP frame-src.
6239 // In this version of a test, CSP comes from a <meta> element added after the
6240 // page has already loaded.
6241 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
6242 CrossSiteIframeBlockedByParentCSPFromMeta) {
6243 GURL main_url(embedded_test_server()->GetURL(
6244 "a.com", "/cross_site_iframe_factory.html?a(a)"));
6245 NavigateToURL(shell(), main_url);
6246
6247 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
6248
6249 // Navigate the subframe to a location we will disallow in the future.
6250 TestNavigationObserver load_observer(shell()->web_contents());
6251 GURL still_allowed_url =
6252 embedded_test_server()->GetURL("b.com", "/title2.html");
6253 EXPECT_TRUE(ExecuteScript(
6254 root->child_at(0)->current_frame_host(),
6255 "window.location.href = '" + still_allowed_url.spec() + "';"));
6256 load_observer.Wait();
alexmos 2016/05/16 16:17:03 Is renderer-initiated navigation required here? U
Łukasz Anforowicz 2016/05/16 19:44:45 Done.
6257
6258 // Add frame-src CSP via a new <meta> element.
6259 EXPECT_TRUE(ExecuteScript(
6260 shell()->web_contents(),
6261 "var meta = document.createElement('meta');"
6262 "meta.httpEquiv = 'Content-Security-Policy';"
6263 "meta.content = 'frame-src https://a.com:*';"
6264 "document.getElementsByTagName('head')[0].appendChild(meta);"));
6265
6266 // Sanity-check that the test page has the expected shape for testing.
6267 // (the CSP should not have an effect on the already loaded frames).
6268 EXPECT_FALSE(root->child_at(0)->HasSameOrigin(*root));
6269 EXPECT_THAT(root->child_at(0)->current_url().spec(),
6270 MatchesRegex("http://b.com.*/title2.html"));
6271
6272 // Monitor subframe's load events via main frame's title.
6273 EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
6274 "document.querySelector('iframe').onload = "
6275 " function() { document.title = 'loaded'; };"));
6276 EXPECT_TRUE(
6277 ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';"));
6278 base::string16 expected_title(base::UTF8ToUTF16("loaded"));
6279 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
6280
6281 // Try to navigate the subframe to a blocked URL.
6282 TestNavigationObserver load_observer2(shell()->web_contents());
6283 GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html");
6284 EXPECT_TRUE(
6285 ExecuteScript(root->child_at(0)->current_frame_host(),
6286 "window.location.href = '" + blocked_url.spec() + "';"));
6287
6288 // The blocked frame should still fire a load event in its parent's process.
6289 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
6290
6291 // Check that the current RenderFrameHost has stopped loading.
6292 if (root->child_at(0)->current_frame_host()->is_loading()) {
6293 ADD_FAILURE() << "Blocked RenderFrameHost shouldn't be loading anything";
6294 load_observer2.Wait();
6295 }
6296
6297 // The blocked frame should stay at the old location.
6298 EXPECT_THAT(root->child_at(0)->current_url().spec(),
6299 MatchesRegex("http://b.com.*/title2.html"));
6300
6301 // The blocked frame should keep the old title.
6302 std::string frame_title;
6303 EXPECT_TRUE(ExecuteScriptAndExtractString(
6304 root->child_at(0)->current_frame_host(),
6305 "domAutomationController.send(document.title)", &frame_title));
6306 EXPECT_EQ("Title Of Awesomeness", frame_title);
6307 }
6308
6309 // Test that a cross-origin frame's navigation can be blocked by CSP frame-src.
6310 // In this version of a test, CSP is inherited by srcdoc iframe from a parent
6311 // that declared CSP via HTTP headers. Cross-origin frame navigating to a
6312 // blocked location is a child of the srcdoc iframe.
6313 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
6314 CrossSiteIframeBlockedByCSPInheritedBySrcDocParent) {
6315 GURL main_url(
6316 embedded_test_server()->GetURL("a.com", "/frame-src-self-and-b.html"));
6317 NavigateToURL(shell(), main_url);
6318
6319 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
6320 FrameTreeNode* srcdoc_frame = root->child_at(1);
6321 EXPECT_TRUE(srcdoc_frame != nullptr);
6322 FrameTreeNode* navigating_frame = srcdoc_frame->child_at(0);
6323 EXPECT_TRUE(navigating_frame != nullptr);
6324
6325 // Sanity-check that the test page has the expected shape for testing.
6326 // (the CSP should not have an effect on the already loaded frames).
6327 EXPECT_TRUE(srcdoc_frame->HasSameOrigin(*root));
6328 EXPECT_FALSE(srcdoc_frame->HasSameOrigin(*navigating_frame));
6329 EXPECT_THAT(navigating_frame->current_url().spec(),
6330 MatchesRegex("http://b.com.*/title2.html"));
6331
6332 // Monitor navigating_frame's load events via srcdoc_frame posting
6333 // a message to the parent frame.
6334 EXPECT_TRUE(
6335 ExecuteScript(root->current_frame_host(),
6336 "window.addEventListener('message', function(event) {"
6337 " document.title = event.data;"
6338 "});"));
6339 EXPECT_TRUE(ExecuteScript(
6340 srcdoc_frame->current_frame_host(),
6341 "document.querySelector('iframe').onload = "
6342 " function() { window.top.postMessage('loaded', '*'); };"));
6343 EXPECT_TRUE(
6344 ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';"));
6345 base::string16 expected_title(base::UTF8ToUTF16("loaded"));
6346 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
6347
6348 // Try to navigate the subframe to a blocked URL.
6349 TestNavigationObserver load_observer2(shell()->web_contents());
6350 GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html");
6351 EXPECT_TRUE(
6352 ExecuteScript(navigating_frame->current_frame_host(),
6353 "window.location.href = '" + blocked_url.spec() + "';"));
6354
6355 // The blocked frame should still fire a load event in its parent's process.
6356 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
6357
6358 // Check that the current RenderFrameHost has stopped loading.
6359 if (navigating_frame->current_frame_host()->is_loading()) {
6360 ADD_FAILURE() << "Blocked RenderFrameHost shouldn't be loading anything";
6361 load_observer2.Wait();
6362 }
6363
6364 // The blocked frame should stay at the old location.
6365 EXPECT_THAT(navigating_frame->current_url().spec(),
6366 MatchesRegex("http://b.com.*/title2.html"));
6367
6368 // The blocked frame should keep the old title.
6369 std::string frame_title;
6370 EXPECT_TRUE(ExecuteScriptAndExtractString(
6371 navigating_frame->current_frame_host(),
6372 "domAutomationController.send(document.title)", &frame_title));
6373 EXPECT_EQ("Title Of Awesomeness", frame_title);
6374 }
6375
6182 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScreenCoordinates) { 6376 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScreenCoordinates) {
6183 GURL main_url(embedded_test_server()->GetURL( 6377 GURL main_url(embedded_test_server()->GetURL(
6184 "a.com", "/cross_site_iframe_factory.html?a(b)")); 6378 "a.com", "/cross_site_iframe_factory.html?a(b)"));
6185 NavigateToURL(shell(), main_url); 6379 NavigateToURL(shell(), main_url);
6186 6380
6187 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); 6381 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
6188 FrameTreeNode* child = root->child_at(0); 6382 FrameTreeNode* child = root->child_at(0);
6189 6383
6190 const char* properties[] = {"screenX", "screenY", "outerWidth", 6384 const char* properties[] = {"screenX", "screenY", "outerWidth",
6191 "outerHeight"}; 6385 "outerHeight"};
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
6559 6753
6560 EXPECT_EQ( 6754 EXPECT_EQ(
6561 " Site A ------------ proxies for B\n" 6755 " Site A ------------ proxies for B\n"
6562 " +--Site B ------- proxies for A\n" 6756 " +--Site B ------- proxies for A\n"
6563 "Where A = http://a.com/\n" 6757 "Where A = http://a.com/\n"
6564 " B = http://b.com/", 6758 " B = http://b.com/",
6565 DepictFrameTree(root)); 6759 DepictFrameTree(root));
6566 } 6760 }
6567 6761
6568 } // namespace content 6762 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698