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

Unified Diff: content/browser/frame_host/form_submission_throttle_browsertest.cc

Issue 2689653003: PlzNavigate: Enforce 'form-action' CSP on the browser-side. (Closed)
Patch Set: Add TODO. Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/frame_host/form_submission_throttle_browsertest.cc
diff --git a/content/browser/frame_host/form_submission_throttle_browsertest.cc b/content/browser/frame_host/form_submission_throttle_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..88ec91dc03a352a54cb47af25928a4af3101da7f
--- /dev/null
+++ b/content/browser/frame_host/form_submission_throttle_browsertest.cc
@@ -0,0 +1,146 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
nasko 2017/03/16 21:49:47 No "(c)" and 2017
alexmos 2017/03/16 23:05:35 nit: update year
arthursonzogni 2017/03/17 14:58:25 Done.
arthursonzogni 2017/03/17 14:58:25 Done.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "content/browser/frame_host/form_submission_throttle.h"
+
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/url_constants.h"
+#include "url/url_util.h"
+
+namespace content {
+
+class FormSubmissionBrowserTest : public ContentBrowserTest {
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
+ CheckContentSecurityPolicyFormAction) {
+ // The FormSubmissionThrottle aren't used without PlzNavigate.
alexmos 2017/03/16 23:05:35 nit: s/aren't/isn't/ (here and below)
arthursonzogni 2017/03/17 14:58:25 Done.
+ if (!IsBrowserSideNavigationEnabled())
+ return;
+
+ const struct {
+ GURL main_page_url;
+ GURL form_page_url;
+ NavigationThrottle::ThrottleCheckResult start_expectation;
+ NavigationThrottle::ThrottleCheckResult redirect_expectation;
+ } kTestCases[] = {
+ // Form submissions are allowed by default when there is not CSP.
alexmos 2017/03/16 23:05:35 nit: s/not/no/
arthursonzogni 2017/03/17 14:58:25 Done.
+ {
+ embedded_test_server()->GetURL(
+ "/form_submission_throttle/no_csp.html"),
+ embedded_test_server()->GetURL("/simple_page.html"),
+ NavigationThrottle::PROCEED, // start expectation.
+ NavigationThrottle::PROCEED // redirect expectation.
+ },
+
+ // No form submission is allowed when the calling RenderFrameHost's CSP
+ // is "form-action 'none'".
+ {
+ embedded_test_server()->GetURL(
+ "/form_submission_throttle/form_action_none.html"),
+ embedded_test_server()->GetURL("/simple_page.html"),
+ NavigationThrottle::CANCEL, // start expectation.
+ NavigationThrottle::CANCEL // redirect expectation.
+ },
+
+ // The path of the source-expression is only enforced when there is no
+ // redirection. By using this behavior, this test can checks a case where
alexmos 2017/03/16 23:05:36 nit: s/checks/check/
arthursonzogni 2017/03/17 14:58:25 Done.
+ // the request is canceled in WillStartRequest() but not in
+ // WillRedirectRequest().
+ // See https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects for
+ // details.
+ {
+ embedded_test_server()->GetURL(
+ "/form_submission_throttle/form_action_with_path.html"),
+ embedded_test_server()->GetURL("/not_the_file.html"),
+ NavigationThrottle::CANCEL, // start expectation.
+ NavigationThrottle::PROCEED // redirect expectation.
+ },
+ };
+
+ for (const auto& test : kTestCases) {
+ SCOPED_TRACE(testing::Message()
+ << std::endl
+ << "main_page_url = " << test.main_page_url << std::endl
+ << "form_page_url = " << test.form_page_url << std::endl);
+
+ // Load the main page.
+ EXPECT_TRUE(NavigateToURL(shell(), test.main_page_url));
+
+ // Build a new form submission navigation.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ std::unique_ptr<NavigationHandle> handle = NavigationHandleImpl::Create(
nasko 2017/03/16 21:49:47 This approach feels more like an unit test than a
alexmos 2017/03/16 23:05:35 I had the same comment, and Arthur pointed out tha
arthursonzogni 2017/03/17 14:58:25 Yes, I wanted to do an unit test initially, but si
+ test.form_page_url, // url
+ std::vector<GURL>(), // redirect chain
+ root, // frame_tree_node
+ true, // is_renderer_initiated
+ false, // is_same_page
+ base::TimeTicks::Now(), // navigation_start
+ 0, // pending_nav_entry_id
+ false, // started_from_context_menu
+ false, // should_bypass_main_world_csp
+ true); // is_form_submission
+
+ // Test the expectations with a FormSubmissionThrottle.
+ std::unique_ptr<NavigationThrottle> throttle =
+ FormSubmissionThrottle::MaybeCreateThrottleFor(handle.get());
+ ASSERT_TRUE(throttle);
+ EXPECT_EQ(test.start_expectation, throttle->WillStartRequest());
+ EXPECT_EQ(test.redirect_expectation, throttle->WillRedirectRequest());
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(FormSubmissionBrowserTest,
+ CheckContentSecurityPolicyFormActionBypassCSP) {
+ // The FormSubmissionThrottle aren't used without PlzNavigate.
+ if (!IsBrowserSideNavigationEnabled())
+ return;
+
+ GURL main_url = embedded_test_server()->GetURL(
+ "/form_submission_throttle/form_action_none.html");
+ GURL form_url = embedded_test_server()->GetURL("/simple_page.html");
+
+ // Load the main page.
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ // Build a new form submission navigation.
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ std::unique_ptr<NavigationHandle> handle =
+ NavigationHandleImpl::Create(form_url, // url
+ std::vector<GURL>(), // redirect chain
+ root, // frame_tree_node
+ true, // is_renderer_initiated
+ false, // is_same_page
+ base::TimeTicks::Now(), // navigation_start
+ 0, // pending_nav_entry_id
+ false, // started_from_context_menu
+ true, // should_bypass_main_world_csp
+ true); // is_form_submission
+
+ // Test that the navigation is allowed because "should_by_pass_main_world_csp"
+ // is true, even if it is a form submission and the policy is
+ // "form-action 'none'".
+ std::unique_ptr<NavigationThrottle> throttle =
+ FormSubmissionThrottle::MaybeCreateThrottleFor(handle.get());
+ ASSERT_TRUE(throttle);
+ EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest());
+ EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillRedirectRequest());
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698