1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/frame_host/frame_tree_node.h"
6 #include "content/browser/frame_host/navigation_request.h"
7 #include "content/public/browser/navigation_throttle.h"
8 #include "content/test/navigation_simulator_impl.h"
9 #include "content/test/test_render_frame_host.h"
10 #include "content/test/test_render_view_host.h"
11
12 namespace content {
13
14 class FormSubmissionTest : public RenderViewHostImplTestHarness {
15 public:
PreventFormSubmission()16 void PreventFormSubmission() {
17 auto source_none = network::mojom::CSPSourceList::New(
18 std::vector<network::mojom::CSPSourcePtr>(), false, false, false);
19 auto policy = network::mojom::ContentSecurityPolicy::New();
20 policy->header = network::mojom::ContentSecurityPolicyHeader::New();
21 policy->directives[network::mojom::CSPDirectiveName::FormAction] =
22 std::move(source_none);
23 main_test_rfh()->AddContentSecurityPolicy(std::move(policy));
24 }
25 };
26
27 // Tests that form submissions are allowed by default when there is no CSP.
TEST_F(FormSubmissionTest,ContentSecurityPolicyFormActionNoCSP)28 TEST_F(FormSubmissionTest, ContentSecurityPolicyFormActionNoCSP) {
29 const GURL kUrl("https://chromium.org");
30 const GURL kFormUrl("https://foo.com");
31 const GURL kRedirectUrl("https://bar.com");
32
33 // Load a page.
34 NavigateAndCommit(kUrl);
35
36 // Try to submit a form.
37 auto form_submission =
38 NavigationSimulatorImpl::CreateRendererInitiated(kFormUrl, main_rfh());
39 form_submission->SetIsFormSubmission(true);
40 form_submission->set_should_check_main_world_csp(
41 network::mojom::CSPDisposition::CHECK);
42 form_submission->Start();
43 EXPECT_EQ(NavigationThrottle::PROCEED,
44 form_submission->GetLastThrottleCheckResult());
45 form_submission->Redirect(kRedirectUrl);
46 EXPECT_EQ(NavigationThrottle::PROCEED,
47 form_submission->GetLastThrottleCheckResult());
48 }
49
50 // Tests that no form submission is allowed when the calling RenderFrameHost's
51 // CSP is "form-action 'none'".
TEST_F(FormSubmissionTest,ContentSecurityPolicyFormActionNone)52 TEST_F(FormSubmissionTest, ContentSecurityPolicyFormActionNone) {
53 const GURL kUrl("https://chromium.org");
54 const GURL kFormUrl("https://foo.com");
55 const GURL kRedirectUrl("https://bar.com");
56
57 // Load a page.
58 NavigateAndCommit(kUrl);
59 PreventFormSubmission();
60
61 // Try to submit a form.
62 auto form_submission =
63 NavigationSimulatorImpl::CreateRendererInitiated(kFormUrl, main_rfh());
64 form_submission->SetIsFormSubmission(true);
65 form_submission->set_should_check_main_world_csp(
66 network::mojom::CSPDisposition::CHECK);
67
68 // Browser side checks have been disabled on the initial load. Only the
69 // renderer side checks occurs. Related issue: https://crbug.com/798698.
70 form_submission->Start();
71 EXPECT_EQ(NavigationThrottle::PROCEED,
72 form_submission->GetLastThrottleCheckResult());
73
74 form_submission->Redirect(kRedirectUrl);
75 EXPECT_EQ(NavigationThrottle::CANCEL,
76 form_submission->GetLastThrottleCheckResult());
77 }
78
79 // Tests that the navigation is allowed because "should_by_pass_main_world_csp"
80 // is true, even if it is a form submission and the policy is
81 // "form-action 'none'".
TEST_F(FormSubmissionTest,ContentSecurityPolicyFormActionBypassCSP)82 TEST_F(FormSubmissionTest, ContentSecurityPolicyFormActionBypassCSP) {
83 const GURL kUrl("https://chromium.org");
84 const GURL kFormUrl("https://foo.com");
85 const GURL kRedirectUrl("https://bar.com");
86
87 // Load a page.
88 NavigateAndCommit(kUrl);
89 PreventFormSubmission();
90
91 // Try to submit a form.
92 auto form_submission =
93 NavigationSimulatorImpl::CreateRendererInitiated(kFormUrl, main_rfh());
94 form_submission->SetIsFormSubmission(true);
95 form_submission->set_should_check_main_world_csp(
96 network::mojom::CSPDisposition::DO_NOT_CHECK);
97 form_submission->Start();
98 EXPECT_EQ(NavigationThrottle::PROCEED,
99 form_submission->GetLastThrottleCheckResult());
100
101 form_submission->Redirect(kRedirectUrl);
102 EXPECT_EQ(NavigationThrottle::PROCEED,
103 form_submission->GetLastThrottleCheckResult());
104 }
105
106 } // namespace content
107