blob: 7d16f1068a959313d2846aa72e32ef501ff9a6a6 [file] [log] [blame]
clamy49678312015-10-22 21:59:001// Copyright 2015 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
danakjc492bf82020-09-09 20:02:445#include "content/browser/renderer_host/navigation_request.h"
Cammie Smith Barnesa0da2cf2021-01-11 22:09:376
7#include <string>
8#include <vector>
9
Sebastien Marchandf8cbfab2019-01-25 16:02:3010#include "base/bind.h"
arthursonzogni898dcda52021-01-21 08:50:1011#include "base/i18n/number_formatting.h"
Yao Xiao6e1f7d32022-01-07 03:28:4012#include "base/test/scoped_feature_list.h"
Becky Zhou9898cb6e2019-06-05 00:35:3013#include "build/build_config.h"
clamy49678312015-10-22 21:59:0014#include "content/public/browser/navigation_throttle.h"
jam6d47c3452016-09-09 18:51:0115#include "content/public/browser/ssl_status.h"
Hans Wennborg5ffd1392019-10-16 11:00:0216#include "content/public/common/content_client.h"
Charles Harrison860f7ef2017-06-28 15:31:4117#include "content/public/common/url_constants.h"
Lucas Garron79e1a972017-10-04 22:25:0618#include "content/public/test/test_navigation_throttle.h"
Yao Xiao1099e4c2022-03-24 22:40:3719#include "content/test/fenced_frame_test_utils.h"
Camille Lamy62b826012019-02-26 09:15:4720#include "content/test/navigation_simulator_impl.h"
Charles Harrison860f7ef2017-06-28 15:31:4121#include "content/test/test_content_browser_client.h"
clamy49678312015-10-22 21:59:0022#include "content/test/test_render_frame_host.h"
scottmg276753cf2016-10-27 18:25:2223#include "content/test/test_web_contents.h"
Lucas Garronc1edb5ab2017-11-08 03:31:1324#include "net/ssl/ssl_connection_status_flags.h"
arthursonzogni898dcda52021-01-21 08:50:1025#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
Cammie Smith Barnesa0da2cf2021-01-11 22:09:3726#include "testing/gmock/include/gmock/gmock.h"
Anton Bikineevf62d1bf2021-05-15 17:56:0727#include "third_party/abseil-cpp/absl/types/optional.h"
Minggang Wanga13c796e2021-07-02 05:54:4328#include "third_party/blink/public/common/navigation/navigation_params.h"
Richard Lie6899952018-11-30 08:42:0029#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
clamy49678312015-10-22 21:59:0030
31namespace content {
32
clamy1d4e78fd2017-07-11 12:59:1933// Test version of a NavigationThrottle that will execute a callback when
34// called.
Lucas Garron79e1a972017-10-04 22:25:0635class DeletingNavigationThrottle : public NavigationThrottle {
clamy1d4e78fd2017-07-11 12:59:1936 public:
Lucas Garron79e1a972017-10-04 22:25:0637 DeletingNavigationThrottle(NavigationHandle* handle,
38 const base::RepeatingClosure& deletion_callback)
39 : NavigationThrottle(handle), deletion_callback_(deletion_callback) {}
Fergal Dalya1d569972021-03-16 03:24:5340 ~DeletingNavigationThrottle() override = default;
clamy1d4e78fd2017-07-11 12:59:1941
42 NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0643 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1944 return NavigationThrottle::PROCEED;
45 }
46
47 NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override {
Lucas Garron79e1a972017-10-04 22:25:0648 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1949 return NavigationThrottle::PROCEED;
50 }
51
Lucas Garron0cedd962017-10-17 07:23:3352 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
53 deletion_callback_.Run();
54 return NavigationThrottle::PROCEED;
55 }
56
clamy1d4e78fd2017-07-11 12:59:1957 NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
Lucas Garron79e1a972017-10-04 22:25:0658 deletion_callback_.Run();
clamy1d4e78fd2017-07-11 12:59:1959 return NavigationThrottle::PROCEED;
60 }
61
62 const char* GetNameForLogging() override {
Lucas Garron79e1a972017-10-04 22:25:0663 return "DeletingNavigationThrottle";
clamy1d4e78fd2017-07-11 12:59:1964 }
65
66 private:
Lucas Garron79e1a972017-10-04 22:25:0667 base::RepeatingClosure deletion_callback_;
clamy1d4e78fd2017-07-11 12:59:1968};
69
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4370class NavigationRequestTest : public RenderViewHostImplTestHarness {
clamy49678312015-10-22 21:59:0071 public:
Fergal Dalya1d569972021-03-16 03:24:5372 NavigationRequestTest() : callback_result_(NavigationThrottle::DEFER) {}
clamy49678312015-10-22 21:59:0073
74 void SetUp() override {
75 RenderViewHostImplTestHarness::SetUp();
clamy1d4e78fd2017-07-11 12:59:1976 CreateNavigationHandle();
scottmg276753cf2016-10-27 18:25:2277 contents()->GetMainFrame()->InitializeRenderFrameIfNeeded();
clamy49678312015-10-22 21:59:0078 }
79
80 void TearDown() override {
clamy49678312015-10-22 21:59:0081 RenderViewHostImplTestHarness::TearDown();
82 }
83
Charles Harrison4f2bf1a2017-07-18 20:21:2184 void CancelDeferredNavigation(
85 NavigationThrottle::ThrottleCheckResult result) {
Hiroki Nakagawaadcffc502021-06-16 10:47:5186 GetNavigationRequest()->CancelDeferredNavigationInternal(result);
Charles Harrison4f2bf1a2017-07-18 20:21:2187 }
88
clamy49678312015-10-22 21:59:0089 // Helper function to call WillStartRequest on |handle|. If this function
90 // returns DEFER, |callback_result_| will be set to the actual result of
91 // the throttle checks when they are finished.
92 void SimulateWillStartRequest() {
93 was_callback_called_ = false;
94 callback_result_ = NavigationThrottle::DEFER;
95
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:4496 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:4397 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:5198 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:1899 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
100 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44101
Hiroki Nakagawaadcffc502021-06-16 10:47:51102 GetNavigationRequest()->WillStartRequest();
clamy49678312015-10-22 21:59:00103 }
104
105 // Helper function to call WillRedirectRequest on |handle|. If this function
106 // returns DEFER, |callback_result_| will be set to the actual result of the
107 // throttle checks when they are finished.
clamye88533842015-11-18 12:48:57108 // TODO(clamy): this should also simulate that WillStartRequest was called if
109 // it has not been called before.
clamy49678312015-10-22 21:59:00110 void SimulateWillRedirectRequest() {
111 was_callback_called_ = false;
112 callback_result_ = NavigationThrottle::DEFER;
113
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44114 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43115 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51116 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18117 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
118 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44119
Hiroki Nakagawaadcffc502021-06-16 10:47:51120 GetNavigationRequest()->WillRedirectRequest(
Arthur Hemery3a991c092021-12-22 12:04:24121 GURL(), nullptr /* post_redirect_process */);
clamy49678312015-10-22 21:59:00122 }
123
Lucas Garron0cedd962017-10-17 07:23:33124 // Helper function to call WillFailRequest on |handle|. If this function
125 // returns DEFER, |callback_result_| will be set to the actual result of the
126 // throttle checks when they are finished.
Lucas Garronc1edb5ab2017-11-08 03:31:13127 void SimulateWillFailRequest(
128 net::Error net_error_code,
Anton Bikineevf62d1bf2021-05-15 17:56:07129 const absl::optional<net::SSLInfo> ssl_info = absl::nullopt) {
Lucas Garron0cedd962017-10-17 07:23:33130 was_callback_called_ = false;
131 callback_result_ = NavigationThrottle::DEFER;
Hiroki Nakagawaadcffc502021-06-16 10:47:51132 GetNavigationRequest()->set_net_error(net_error_code);
Lucas Garron0cedd962017-10-17 07:23:33133
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44134 // It's safe to use base::Unretained since the NavigationRequest is owned by
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43135 // the NavigationRequestTest.
Hiroki Nakagawaadcffc502021-06-16 10:47:51136 GetNavigationRequest()->set_complete_callback_for_testing(
Makoto Shimazud2aa2202019-10-09 13:57:18137 base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult,
138 base::Unretained(this)));
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44139
Hiroki Nakagawaadcffc502021-06-16 10:47:51140 GetNavigationRequest()->WillFailRequest();
Lucas Garron0cedd962017-10-17 07:23:33141 }
142
clamy49678312015-10-22 21:59:00143 // Whether the callback was called.
144 bool was_callback_called() const { return was_callback_called_; }
145
146 // Returns the callback_result.
147 NavigationThrottle::ThrottleCheckResult callback_result() const {
148 return callback_result_;
149 }
150
Hiroki Nakagawaadcffc502021-06-16 10:47:51151 NavigationRequest::NavigationState state() {
152 return GetNavigationRequest()->state();
153 }
Mohamed Abdelhalimccd149af2019-10-31 14:48:53154
Lucas Garron0cedd962017-10-17 07:23:33155 bool call_counts_match(TestNavigationThrottle* throttle,
156 int start,
157 int redirect,
158 int failure,
159 int process) {
160 return start == throttle->GetCallCount(
161 TestNavigationThrottle::WILL_START_REQUEST) &&
162 redirect == throttle->GetCallCount(
163 TestNavigationThrottle::WILL_REDIRECT_REQUEST) &&
164 failure == throttle->GetCallCount(
165 TestNavigationThrottle::WILL_FAIL_REQUEST) &&
166 process == throttle->GetCallCount(
167 TestNavigationThrottle::WILL_PROCESS_RESPONSE);
168 }
169
170 // Creates, register and returns a TestNavigationThrottle that will
171 // synchronously return |result| on checks by default.
clamy49678312015-10-22 21:59:00172 TestNavigationThrottle* CreateTestNavigationThrottle(
173 NavigationThrottle::ThrottleCheckResult result) {
174 TestNavigationThrottle* test_throttle =
Hiroki Nakagawaadcffc502021-06-16 10:47:51175 new TestNavigationThrottle(GetNavigationRequest());
Lucas Garron79e1a972017-10-04 22:25:06176 test_throttle->SetResponseForAllMethods(TestNavigationThrottle::SYNCHRONOUS,
177 result);
Hiroki Nakagawaadcffc502021-06-16 10:47:51178 GetNavigationRequest()->RegisterThrottleForTesting(
dcheng9bfa5162016-04-09 01:00:57179 std::unique_ptr<TestNavigationThrottle>(test_throttle));
clamy49678312015-10-22 21:59:00180 return test_throttle;
181 }
182
Lucas Garron0cedd962017-10-17 07:23:33183 // Creates, register and returns a TestNavigationThrottle that will
184 // synchronously return |result| on check for the given |method|, and
185 // NavigationThrottle::PROCEED otherwise.
186 TestNavigationThrottle* CreateTestNavigationThrottle(
187 TestNavigationThrottle::ThrottleMethod method,
188 NavigationThrottle::ThrottleCheckResult result) {
189 TestNavigationThrottle* test_throttle =
190 CreateTestNavigationThrottle(NavigationThrottle::PROCEED);
191 test_throttle->SetResponse(method, TestNavigationThrottle::SYNCHRONOUS,
192 result);
193 return test_throttle;
194 }
195
Mohamed Abdelhalim9ef43fc2019-04-05 13:09:43196 // TODO(zetamoo): Use NavigationSimulator instead of creating
197 // NavigationRequest and NavigationHandleImpl.
clamy1d4e78fd2017-07-11 12:59:19198 void CreateNavigationHandle() {
Minggang Wanga13c796e2021-07-02 05:54:43199 auto common_params = blink::CreateCommonNavigationParams();
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51200 common_params->initiator_origin =
Lukasz Anforowicz435bcb582019-07-12 20:50:06201 url::Origin::Create(GURL("https://initiator.example.com"));
Minggang Wanga13c796e2021-07-02 05:54:43202 auto commit_params = blink::CreateCommitNavigationParams();
arthursonzogni70ac7302020-05-28 08:49:05203 commit_params->frame_policy =
204 main_test_rfh()->frame_tree_node()->pending_frame_policy();
Hiroki Nakagawaadcffc502021-06-16 10:47:51205 auto request = NavigationRequest::CreateBrowserInitiated(
Lucas Furukawa Gadanief8290a2019-07-29 20:27:51206 main_test_rfh()->frame_tree_node(), std::move(common_params),
arthursonzogni70ac7302020-05-28 08:49:05207 std::move(commit_params), false /* browser-initiated */,
Takashi Toyoshimae87b7be2021-01-22 11:51:08208 false /* was_opener_suppressed */, nullptr /* initiator_frame_token */,
Antonio Sartori9a82f6f32020-12-14 09:22:45209 ChildProcessHost::kInvalidUniqueID /* initiator_process_id */,
John Delaney50425f82020-04-07 16:26:21210 std::string() /* extra_headers */, nullptr /* frame_entry */,
211 nullptr /* entry */, nullptr /* post_body */,
Daniel Hosseinianf0fbfb42021-09-08 02:20:47212 nullptr /* navigation_ui_data */, absl::nullopt /* impression */,
213 false /* is_pdf */);
Hiroki Nakagawaadcffc502021-06-16 10:47:51214 main_test_rfh()->frame_tree_node()->CreatedNavigationRequest(
215 std::move(request));
216 GetNavigationRequest()->StartNavigation();
clamy1d4e78fd2017-07-11 12:59:19217 }
218
Yao Xiao6e1f7d32022-01-07 03:28:40219 FrameTreeNode* AddFrame(FrameTree& frame_tree,
220 RenderFrameHostImpl* parent,
221 int process_id,
222 int new_routing_id,
223 const blink::FramePolicy& frame_policy,
224 blink::FrameOwnerElementType owner_type) {
225 return frame_tree.AddFrame(
226 parent, process_id, new_routing_id,
227 TestRenderFrameHost::CreateStubFrameRemote(),
228 TestRenderFrameHost::CreateStubBrowserInterfaceBrokerReceiver(),
229 TestRenderFrameHost::CreateStubPolicyContainerBindParams(),
230 blink::mojom::TreeScopeType::kDocument, std::string(), "uniqueName0",
231 false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
232 frame_policy, blink::mojom::FrameOwnerProperties(), false, owner_type,
233 /*is_dummy_frame_for_inner_tree=*/false);
234 }
235
clamy49678312015-10-22 21:59:00236 private:
Mohamed Abdelhalimf03d4a22019-10-01 13:34:31237 // The callback provided to NavigationRequest::WillStartRequest,
238 // NavigationRequest::WillRedirectRequest, and
239 // NavigationRequest::WillFailRequest during the tests.
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44240 bool UpdateThrottleCheckResult(
clamy49678312015-10-22 21:59:00241 NavigationThrottle::ThrottleCheckResult result) {
242 callback_result_ = result;
243 was_callback_called_ = true;
Mohamed Abdelhalim7e9e9c12019-11-26 13:48:44244 return true;
clamy49678312015-10-22 21:59:00245 }
246
Hiroki Nakagawaadcffc502021-06-16 10:47:51247 // This must be called after CreateNavigationHandle().
248 NavigationRequest* GetNavigationRequest() {
249 return main_test_rfh()->frame_tree_node()->navigation_request();
250 }
251
Fergal Dalya1d569972021-03-16 03:24:53252 bool was_callback_called_ = false;
clamy49678312015-10-22 21:59:00253 NavigationThrottle::ThrottleCheckResult callback_result_;
254};
255
carlosk489d9e22016-07-25 14:25:43256// Checks that the request_context_type is properly set.
257// Note: can be extended to cover more internal members.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43258TEST_F(NavigationRequestTest, SimpleDataChecksRedirectAndProcess) {
Camille Lamy62b826012019-02-26 09:15:47259 const GURL kUrl1 = GURL("http://chromium.org");
260 const GURL kUrl2 = GURL("http://google.com");
261 auto navigation =
262 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
263 navigation->Start();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40264 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05265 NavigationRequest::From(navigation->GetNavigationHandle())
266 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11267 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47268 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43269
Camille Lamy62b826012019-02-26 09:15:47270 navigation->set_http_connection_info(
271 net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1);
272 navigation->Redirect(kUrl2);
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40273 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05274 NavigationRequest::From(navigation->GetNavigationHandle())
275 ->request_context_type());
jkarlinbb150112016-11-02 17:55:11276 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
Camille Lamy62b826012019-02-26 09:15:47277 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43278
Camille Lamy62b826012019-02-26 09:15:47279 navigation->set_http_connection_info(
280 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
281 navigation->ReadyToCommit();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40282 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05283 NavigationRequest::From(navigation->GetNavigationHandle())
284 ->request_context_type());
bnc90be5dd782016-11-09 16:28:44285 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47286 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11287}
288
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43289TEST_F(NavigationRequestTest, SimpleDataCheckNoRedirect) {
Camille Lamy62b826012019-02-26 09:15:47290 const GURL kUrl = GURL("http://chromium.org");
291 auto navigation =
292 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
293 navigation->Start();
jkarlinbb150112016-11-02 17:55:11294 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47295 navigation->GetNavigationHandle()->GetConnectionInfo());
jkarlinbb150112016-11-02 17:55:11296
Camille Lamy62b826012019-02-26 09:15:47297 navigation->set_http_connection_info(
298 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
299 navigation->ReadyToCommit();
bnc90be5dd782016-11-09 16:28:44300 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
Camille Lamy62b826012019-02-26 09:15:47301 navigation->GetNavigationHandle()->GetConnectionInfo());
carlosk489d9e22016-07-25 14:25:43302}
303
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43304TEST_F(NavigationRequestTest, SimpleDataChecksFailure) {
Camille Lamy62b826012019-02-26 09:15:47305 const GURL kUrl = GURL("http://chromium.org");
306 auto navigation =
307 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
308 navigation->Start();
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40309 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05310 NavigationRequest::From(navigation->GetNavigationHandle())
311 ->request_context_type());
Lucas Garron0cedd962017-10-17 07:23:33312 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
Camille Lamy62b826012019-02-26 09:15:47313 navigation->GetNavigationHandle()->GetConnectionInfo());
Lucas Garron0cedd962017-10-17 07:23:33314
Camille Lamy62b826012019-02-26 09:15:47315 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Harkiran Bolariaa2c9f79a2021-07-02 09:25:40316 EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
Mohamed Abdelhalim40c35d22019-09-19 15:59:05317 NavigationRequest::From(navigation->GetNavigationHandle())
318 ->request_context_type());
Camille Lamy62b826012019-02-26 09:15:47319 EXPECT_EQ(net::ERR_CERT_DATE_INVALID,
320 navigation->GetNavigationHandle()->GetNetErrorCode());
Lucas Garron0cedd962017-10-17 07:23:33321}
322
Yao Xiao6e1f7d32022-01-07 03:28:40323TEST_F(NavigationRequestTest, FencedFrameNavigationToPendingMappedURN) {
324 // Note that we only run this test for the ShadowDOM implementation of fenced
325 // frames, due to how they add subframes in a way that is very specific to the
326 // ShadowDOM implementation, and not suitable for the MPArch implementation.
327 base::test::ScopedFeatureList scoped_feature_list;
328 scoped_feature_list.InitAndEnableFeatureWithParameters(
329 blink::features::kFencedFrames, {{"implementation_type", "shadow_dom"}});
330
331 FrameTree& frame_tree = contents()->GetPrimaryFrameTree();
332 FrameTreeNode* root = frame_tree.root();
333 int process_id = root->current_frame_host()->GetProcess()->GetID();
334
335 // Add a fenced frame.
336 constexpr auto kFencedframeOwnerType =
337 blink::FrameOwnerElementType::kFencedframe;
338 blink::FramePolicy policy;
339 policy.is_fenced = true;
340 AddFrame(frame_tree, root->current_frame_host(), process_id, 15, policy,
341 kFencedframeOwnerType);
342
343 FrameTreeNode* fenced_frame_tree_node = root->child_at(0);
344 EXPECT_TRUE(fenced_frame_tree_node->IsFencedFrameRoot());
345 EXPECT_TRUE(fenced_frame_tree_node->IsInFencedFrameTree());
346
347 FencedFrameURLMapping& fenced_frame_urls_map =
348 main_test_rfh()->GetPage().fenced_frame_urls_map();
349
350 const GURL urn_uuid = fenced_frame_urls_map.GeneratePendingMappedURN();
Dominic Farolinoe724b5332022-04-26 05:00:06351 const GURL mapped_url = GURL("https://chromium.org");
Yao Xiao6e1f7d32022-01-07 03:28:40352
353 auto navigation_simulator = NavigationSimulatorImpl::CreateRendererInitiated(
354 urn_uuid, fenced_frame_tree_node->current_frame_host());
355
356 auto response_headers =
357 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
358 response_headers->SetHeader("Supports-Loading-Mode", "fenced-frame");
359
360 navigation_simulator->SetAutoAdvance(false);
361 navigation_simulator->SetResponseHeaders(response_headers);
362 navigation_simulator->SetTransition(ui::PAGE_TRANSITION_AUTO_SUBFRAME);
363
364 navigation_simulator->Start();
365
366 EXPECT_EQ(navigation_simulator->GetNavigationHandle()->GetURL(), urn_uuid);
367
Yao Xiao1099e4c2022-03-24 22:40:37368 SimulateSharedStorageURNMappingComplete(
369 fenced_frame_urls_map, urn_uuid, mapped_url,
370 /*shared_storage_origin=*/url::Origin::Create(GURL("https://bar.com")),
371 /*budget_to_charge=*/2.0);
Yao Xiao6e1f7d32022-01-07 03:28:40372
373 // Expect that the url in the NavigationRequest is already mapped.
374 EXPECT_EQ(navigation_simulator->GetNavigationHandle()->GetURL(), mapped_url);
375
376 navigation_simulator->Wait();
377
378 navigation_simulator->SetAutoAdvance(true);
379 navigation_simulator->ReadyToCommit();
380 navigation_simulator->Commit();
381
382 EXPECT_EQ(fenced_frame_tree_node->current_url(), mapped_url);
383}
384
clamye88533842015-11-18 12:48:57385// Checks that a navigation deferred during WillStartRequest can be properly
386// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53387TEST_F(NavigationRequestTest, CancelDeferredWillStart) {
clamye88533842015-11-18 12:48:57388 TestNavigationThrottle* test_throttle =
389 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19390 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33391 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57392
393 // Simulate WillStartRequest. The request should be deferred. The callback
394 // should not have been called.
395 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19396 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
clamye88533842015-11-18 12:48:57397 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33398 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57399
400 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21401 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19402 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57403 EXPECT_TRUE(was_callback_called());
404 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33405 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57406}
407
408// Checks that a navigation deferred during WillRedirectRequest can be properly
409// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53410TEST_F(NavigationRequestTest, CancelDeferredWillRedirect) {
clamye88533842015-11-18 12:48:57411 TestNavigationThrottle* test_throttle =
412 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19413 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33414 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57415
416 // Simulate WillRedirectRequest. The request should be deferred. The callback
417 // should not have been called.
418 SimulateWillRedirectRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19419 EXPECT_EQ(NavigationRequest::WILL_REDIRECT_REQUEST, state());
clamye88533842015-11-18 12:48:57420 EXPECT_FALSE(was_callback_called());
Lucas Garron0cedd962017-10-17 07:23:33421 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
clamye88533842015-11-18 12:48:57422
423 // Cancel the request. The callback should have been called.
Charles Harrison4f2bf1a2017-07-18 20:21:21424 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19425 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57426 EXPECT_TRUE(was_callback_called());
427 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33428 EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0));
429}
430
431// Checks that a navigation deferred during WillFailRequest can be properly
432// cancelled.
Mohamed Abdelhalimba020672019-10-31 16:18:53433TEST_F(NavigationRequestTest, CancelDeferredWillFail) {
Lucas Garron0cedd962017-10-17 07:23:33434 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
435 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19436 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33437 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
438
439 // Simulate WillStartRequest.
440 SimulateWillStartRequest();
441 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
442
443 // Simulate WillFailRequest. The request should be deferred. The callback
444 // should not have been called.
445 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19446 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33447 EXPECT_FALSE(was_callback_called());
448 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
449
450 // Cancel the request. The callback should have been called.
451 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19452 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33453 EXPECT_TRUE(was_callback_called());
454 EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result());
455 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
clamye88533842015-11-18 12:48:57456}
457
458// Checks that a navigation deferred can be canceled and not ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53459TEST_F(NavigationRequestTest, CancelDeferredWillRedirectNoIgnore) {
clamye88533842015-11-18 12:48:57460 TestNavigationThrottle* test_throttle =
461 CreateTestNavigationThrottle(NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19462 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33463 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
clamye88533842015-11-18 12:48:57464
Lucas Garron0cedd962017-10-17 07:23:33465 // Simulate WillStartRequest. The request should be deferred. The callback
clamye88533842015-11-18 12:48:57466 // should not have been called.
467 SimulateWillStartRequest();
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19468 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33469 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57470
471 // Cancel the request. The callback should have been called with CANCEL, and
472 // not CANCEL_AND_IGNORE.
Charles Harrison4f2bf1a2017-07-18 20:21:21473 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19474 EXPECT_EQ(NavigationRequest::CANCELING, state());
clamye88533842015-11-18 12:48:57475 EXPECT_TRUE(was_callback_called());
476 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
Lucas Garron0cedd962017-10-17 07:23:33477 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
clamye88533842015-11-18 12:48:57478}
479
Lucas Garron0cedd962017-10-17 07:23:33480// Checks that a navigation deferred by WillFailRequest can be canceled and not
481// ignored.
Mohamed Abdelhalimba020672019-10-31 16:18:53482TEST_F(NavigationRequestTest, CancelDeferredWillFailNoIgnore) {
Lucas Garron0cedd962017-10-17 07:23:33483 TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(
484 TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19485 EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33486 EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0));
487
488 // Simulate WillStartRequest.
489 SimulateWillStartRequest();
490 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0));
491
492 // Simulate WillFailRequest. The request should be deferred. The callback
493 // should not have been called.
494 SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19495 EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state());
Lucas Garron0cedd962017-10-17 07:23:33496 EXPECT_FALSE(was_callback_called());
497 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
498
499 // Cancel the request. The callback should have been called with CANCEL, and
500 // not CANCEL_AND_IGNORE.
501 CancelDeferredNavigation(NavigationThrottle::CANCEL);
Mohamed Abdelhalimb6f9f702019-11-06 17:23:19502 EXPECT_EQ(NavigationRequest::CANCELING, state());
Lucas Garron0cedd962017-10-17 07:23:33503 EXPECT_TRUE(was_callback_called());
504 EXPECT_EQ(NavigationThrottle::CANCEL, callback_result());
505 EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0));
506}
507
Lucas Garronc1edb5ab2017-11-08 03:31:13508// Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
John Abd-El-Malekf36e05f2017-11-30 16:17:52509// stored on the handle.
Mohamed Abdelhalim1e8c5822019-08-02 11:45:43510TEST_F(NavigationRequestTest, WillFailRequestSetsSSLInfo) {
Lucas Garronc1edb5ab2017-11-08 03:31:13511 uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
512 int connection_status = 0;
513 net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
514
515 // Set some test values.
516 net::SSLInfo ssl_info;
517 ssl_info.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
518 ssl_info.connection_status = connection_status;
519
Camille Lamy62b826012019-02-26 09:15:47520 const GURL kUrl = GURL("https://chromium.org");
521 auto navigation =
522 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
Emily Starkfd6978ad12019-04-30 21:20:07523 navigation->SetSSLInfo(ssl_info);
Camille Lamy62b826012019-02-26 09:15:47524 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Lucas Garronc1edb5ab2017-11-08 03:31:13525
526 EXPECT_EQ(net::CERT_STATUS_AUTHORITY_INVALID,
Camille Lamy62b826012019-02-26 09:15:47527 navigation->GetNavigationHandle()->GetSSLInfo()->cert_status);
528 EXPECT_EQ(connection_status,
529 navigation->GetNavigationHandle()->GetSSLInfo()->connection_status);
Lucas Garronc1edb5ab2017-11-08 03:31:13530}
531
Camille Lamy62b826012019-02-26 09:15:47532namespace {
533
Alex Moshchuk1a66b1d2018-05-15 21:18:26534// Helper throttle which checks that it can access NavigationHandle's
535// RenderFrameHost in WillFailRequest() and then defers the failure.
536class GetRenderFrameHostOnFailureNavigationThrottle
537 : public NavigationThrottle {
538 public:
Fergal Dalya1d569972021-03-16 03:24:53539 explicit GetRenderFrameHostOnFailureNavigationThrottle(
540 NavigationHandle* handle)
Alex Moshchuk1a66b1d2018-05-15 21:18:26541 : NavigationThrottle(handle) {}
Peter Boström828b9022021-09-21 02:28:43542
543 GetRenderFrameHostOnFailureNavigationThrottle(
544 const GetRenderFrameHostOnFailureNavigationThrottle&) = delete;
545 GetRenderFrameHostOnFailureNavigationThrottle& operator=(
546 const GetRenderFrameHostOnFailureNavigationThrottle&) = delete;
547
Fergal Dalya1d569972021-03-16 03:24:53548 ~GetRenderFrameHostOnFailureNavigationThrottle() override = default;
Alex Moshchuk1a66b1d2018-05-15 21:18:26549
550 NavigationThrottle::ThrottleCheckResult WillFailRequest() override {
551 EXPECT_TRUE(navigation_handle()->GetRenderFrameHost());
552 return NavigationThrottle::DEFER;
553 }
554
555 const char* GetNameForLogging() override {
556 return "GetRenderFrameHostOnFailureNavigationThrottle";
557 }
Alex Moshchuk1a66b1d2018-05-15 21:18:26558};
559
Camille Lamy62b826012019-02-26 09:15:47560class ThrottleTestContentBrowserClient : public ContentBrowserClient {
561 std::vector<std::unique_ptr<NavigationThrottle>> CreateThrottlesForNavigation(
562 NavigationHandle* navigation_handle) override {
563 std::vector<std::unique_ptr<NavigationThrottle>> throttle;
564 throttle.push_back(
565 std::make_unique<GetRenderFrameHostOnFailureNavigationThrottle>(
566 navigation_handle));
567 return throttle;
568 }
569};
570
571} // namespace
572
Alex Moshchuk1a66b1d2018-05-15 21:18:26573// Verify that the NavigationHandle::GetRenderFrameHost() can be retrieved by a
574// throttle in WillFailRequest(), as well as after deferring the failure. This
575// is allowed, since at that point the final RenderFrameHost will have already
576// been chosen. See https://crbug.com/817881.
Mohamed Abdelhalimba020672019-10-31 16:18:53577TEST_F(NavigationRequestTest, WillFailRequestCanAccessRenderFrameHost) {
Camille Lamy62b826012019-02-26 09:15:47578 std::unique_ptr<ContentBrowserClient> client(
579 new ThrottleTestContentBrowserClient);
580 ContentBrowserClient* old_browser_client =
581 SetBrowserClientForTesting(client.get());
582
583 const GURL kUrl = GURL("http://chromium.org");
584 auto navigation =
585 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
586 navigation->SetAutoAdvance(false);
587 navigation->Start();
588 navigation->Fail(net::ERR_CERT_DATE_INVALID);
Mohamed Abdelhalim3b235272019-11-05 15:06:07589 EXPECT_EQ(
590 NavigationRequest::WILL_FAIL_REQUEST,
591 NavigationRequest::From(navigation->GetNavigationHandle())->state());
Camille Lamy62b826012019-02-26 09:15:47592 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
Mohamed Abdelhalim40c35d22019-09-19 15:59:05593 NavigationRequest::From(navigation->GetNavigationHandle())
danakjf26536bf2020-09-10 00:46:13594 ->GetNavigationThrottleRunnerForTesting()
Mohamed Abdelhalim40c35d22019-09-19 15:59:05595 ->CallResumeForTesting();
Camille Lamy62b826012019-02-26 09:15:47596 EXPECT_TRUE(navigation->GetNavigationHandle()->GetRenderFrameHost());
597
598 SetBrowserClientForTesting(old_browser_client);
Alex Moshchuk1a66b1d2018-05-15 21:18:26599}
600
Antonio Sartori3cfa3b62020-10-09 10:42:40601TEST_F(NavigationRequestTest, PolicyContainerInheritance) {
602 struct TestCase {
603 const char* url;
604 bool expect_inherit;
605 } cases[]{{"about:blank", true},
606 {"data:text/plain,hello", true},
607 {"file://local", false},
608 {"http://chromium.org", false}};
609
610 const GURL kUrl1 = GURL("http://chromium.org");
611 auto navigation =
612 NavigationSimulatorImpl::CreateRendererInitiated(kUrl1, main_rfh());
613 navigation->Commit();
614
615 for (auto test : cases) {
616 // We navigate child frames because the BlockedSchemeNavigationThrottle
617 // restricts navigations in the main frame.
618 auto* child_frame = static_cast<TestRenderFrameHost*>(
619 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child"));
620
621 // We set the referrer policy of the frame to "always". We then create a new
622 // navigation, set as initiator the frame itself, start the navigation, and
623 // change the referrer policy of the frame to "never". After we commit the
624 // navigation:
625 // - If navigating to a local scheme, the target frame should have inherited
626 // the referrer policy of the initiator ("always").
627 // - If navigating to a non-local scheme, the target frame should have a new
628 // policy container (hence referrer policy set to "default").
629 const GURL kUrl = GURL(test.url);
Peter Kastingeb8c3ce2021-08-20 04:39:35630 navigation =
Antonio Sartori3cfa3b62020-10-09 10:42:40631 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_frame);
Antonio Sartori5b2f8042020-10-23 18:13:26632 static_cast<blink::mojom::PolicyContainerHost*>(
Antonio Sartori9290b6b2020-11-09 10:09:33633 child_frame->policy_container_host())
Antonio Sartori5b2f8042020-10-23 18:13:26634 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kAlways);
Antonio Sartori3cfa3b62020-10-09 10:42:40635 navigation->SetInitiatorFrame(child_frame);
636 navigation->Start();
Antonio Sartori5b2f8042020-10-23 18:13:26637 static_cast<blink::mojom::PolicyContainerHost*>(
Antonio Sartori9290b6b2020-11-09 10:09:33638 child_frame->policy_container_host())
Antonio Sartori5b2f8042020-10-23 18:13:26639 ->SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
Antonio Sartori3cfa3b62020-10-09 10:42:40640 navigation->Commit();
641 EXPECT_EQ(
642 test.expect_inherit ? network::mojom::ReferrerPolicy::kAlways
643 : network::mojom::ReferrerPolicy::kDefault,
644 static_cast<RenderFrameHostImpl*>(navigation->GetFinalRenderFrameHost())
Antonio Sartori9290b6b2020-11-09 10:09:33645 ->policy_container_host()
Antonio Sartori3cfa3b62020-10-09 10:42:40646 ->referrer_policy());
647 }
648}
649
Cammie Smith Barnesa0da2cf2021-01-11 22:09:37650TEST_F(NavigationRequestTest, DnsAliasesCanBeAccessed) {
651 // Create simulated NavigationRequest for the URL, which has aliases.
652 const GURL kUrl = GURL("http://chromium.org");
653 auto navigation =
654 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
655 std::vector<std::string> dns_aliases({"alias1", "alias2"});
656 navigation->SetResponseDnsAliases(std::move(dns_aliases));
657
658 // Start the navigation.
659 navigation->Start();
660 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
661 navigation->GetNavigationHandle()->GetConnectionInfo());
662
663 // Commit the navigation.
664 navigation->set_http_connection_info(
665 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
666 navigation->ReadyToCommit();
667 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
668 navigation->GetNavigationHandle()->GetConnectionInfo());
669
670 // Verify that the aliases are accessible from the NavigationRequest.
671 EXPECT_THAT(navigation->GetNavigationHandle()->GetDnsAliases(),
672 testing::ElementsAre("alias1", "alias2"));
673}
674
675TEST_F(NavigationRequestTest, NoDnsAliases) {
676 // Create simulated NavigationRequest for the URL, which does not
677 // have aliases. (Note the empty alias list.)
678 const GURL kUrl = GURL("http://chromium.org");
679 auto navigation =
680 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, main_rfh());
681 std::vector<std::string> dns_aliases;
682 navigation->SetResponseDnsAliases(std::move(dns_aliases));
683
684 // Start the navigation.
685 navigation->Start();
686 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
687 navigation->GetNavigationHandle()->GetConnectionInfo());
688
689 // Commit the navigation.
690 navigation->set_http_connection_info(
691 net::HttpResponseInfo::CONNECTION_INFO_QUIC_35);
692 navigation->ReadyToCommit();
693 EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
694 navigation->GetNavigationHandle()->GetConnectionInfo());
695
696 // Verify that there are no aliases in the NavigationRequest.
697 EXPECT_TRUE(navigation->GetNavigationHandle()->GetDnsAliases().empty());
698}
699
Antonio Sartori3e8de6d2021-07-26 10:28:41700TEST_F(NavigationRequestTest, StorageKeyToCommit) {
701 TestRenderFrameHost* child_document = static_cast<TestRenderFrameHost*>(
702 content::RenderFrameHostTester::For(main_rfh())->AppendChild(""));
703 child_document->frame_tree_node()->set_anonymous(true);
704
705 const GURL kUrl = GURL("http://chromium.org");
706 auto navigation =
707 NavigationSimulatorImpl::CreateRendererInitiated(kUrl, child_document);
708 navigation->ReadyToCommit();
709 NavigationRequest* request =
710 NavigationRequest::From(navigation->GetNavigationHandle());
711 EXPECT_TRUE(request->commit_params().storage_key.nonce().has_value());
712 EXPECT_EQ(child_document->GetMainFrame()->GetPage().anonymous_iframes_nonce(),
713 request->commit_params().storage_key.nonce().value());
714
715 navigation->Commit();
716 child_document =
717 static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost());
718 EXPECT_TRUE(child_document->anonymous());
719 EXPECT_EQ(
720 blink::StorageKey::CreateWithNonce(
721 url::Origin::Create(kUrl),
722 child_document->GetMainFrame()->GetPage().anonymous_iframes_nonce()),
723 child_document->storage_key());
724}
725
Antonio Sartoribf27cc442021-08-25 13:08:23726TEST_F(NavigationRequestTest,
727 NavigationToAnonymousDocumentNetworkIsolationInfo) {
728 auto* child_frame = static_cast<TestRenderFrameHost*>(
729 content::RenderFrameHostTester::For(main_test_rfh())
730 ->AppendChild("child"));
731 child_frame->frame_tree_node()->set_anonymous(true);
732
733 std::unique_ptr<NavigationSimulator> navigation =
734 NavigationSimulator::CreateRendererInitiated(
735 GURL("https://example.com/navigation.html"), child_frame);
736 navigation->ReadyToCommit();
737
738 EXPECT_EQ(main_test_rfh()->GetPage().anonymous_iframes_nonce(),
739 static_cast<NavigationRequest*>(navigation->GetNavigationHandle())
740 ->isolation_info_for_subresources()
741 .network_isolation_key()
742 .GetNonce());
743 EXPECT_EQ(main_test_rfh()->GetPage().anonymous_iframes_nonce(),
744 static_cast<NavigationRequest*>(navigation->GetNavigationHandle())
745 ->GetIsolationInfo()
746 .network_isolation_key()
747 .GetNonce());
748}
749
arthursonzogni898dcda52021-01-21 08:50:10750// Test that the required CSP of every frame is computed/inherited correctly and
751// that the Sec-Required-CSP header is set.
752class CSPEmbeddedEnforcementUnitTest : public NavigationRequestTest {
753 protected:
754 TestRenderFrameHost* main_rfh() {
755 return static_cast<TestRenderFrameHost*>(NavigationRequestTest::main_rfh());
756 }
757
758 // Simulate the |csp| attribute being set in |rfh|'s frame. Then navigate it.
759 // Returns the request's Sec-Required-CSP header.
760 std::string NavigateWithRequiredCSP(TestRenderFrameHost** rfh,
761 std::string required_csp) {
762 TestRenderFrameHost* document = *rfh;
763
764 if (!required_csp.empty()) {
765 auto headers =
766 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
767 headers->SetHeader("Content-Security-Policy", required_csp);
768 std::vector<network::mojom::ContentSecurityPolicyPtr> policies;
769 network::AddContentSecurityPolicyFromHeaders(
770 *headers, GURL("https://example.com/"), &policies);
771 document->frame_tree_node()->set_csp_attribute(std::move(policies[0]));
772 }
773
774 // Chrome blocks a document navigating to a URL if more than one of its
775 // ancestors have the same URL. Use a different URL every time, to
776 // avoid blocking navigation of the grandchild frame.
777 static int nonce = 0;
778 GURL url("https://www.example.com" + base::NumberToString(nonce++));
779
780 auto navigation =
781 content::NavigationSimulator::CreateRendererInitiated(url, *rfh);
782 navigation->Start();
783 NavigationRequest* request =
784 NavigationRequest::From(navigation->GetNavigationHandle());
785 std::string sec_required_csp;
786 request->GetRequestHeaders().GetHeader("sec-required-csp",
787 &sec_required_csp);
788
789 // Complete the navigation so that the required csp is stored in the
790 // RenderFrameHost, so that when we will add children to this document they
791 // will be able to get the parent's required csp (and hence also test that
792 // the whole logic works).
793 auto response_headers =
794 base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
795 response_headers->SetHeader("Allow-CSP-From", "*");
796 navigation->SetResponseHeaders(response_headers);
797 navigation->Commit();
798
799 *rfh = static_cast<TestRenderFrameHost*>(
800 navigation->GetFinalRenderFrameHost());
801
802 return sec_required_csp;
803 }
804
805 TestRenderFrameHost* AddChild(TestRenderFrameHost* parent) {
806 return static_cast<TestRenderFrameHost*>(
807 content::RenderFrameHostTester::For(parent)->AppendChild(""));
808 }
809};
810
811TEST_F(CSPEmbeddedEnforcementUnitTest, TopLevel) {
812 TestRenderFrameHost* top_document = main_rfh();
813 std::string sec_required_csp = NavigateWithRequiredCSP(&top_document, "");
814 EXPECT_EQ("", sec_required_csp);
815 EXPECT_FALSE(top_document->required_csp());
816}
817
818TEST_F(CSPEmbeddedEnforcementUnitTest, ChildNoCSP) {
819 TestRenderFrameHost* top_document = main_rfh();
820 TestRenderFrameHost* child_document = AddChild(top_document);
821 std::string sec_required_csp = NavigateWithRequiredCSP(&child_document, "");
822 EXPECT_EQ("", sec_required_csp);
823 EXPECT_FALSE(child_document->required_csp());
824}
825
826TEST_F(CSPEmbeddedEnforcementUnitTest, ChildWithCSP) {
827 TestRenderFrameHost* top_document = main_rfh();
828 TestRenderFrameHost* child_document = AddChild(top_document);
829 std::string sec_required_csp =
830 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
831 EXPECT_EQ("script-src 'none'", sec_required_csp);
832 EXPECT_TRUE(child_document->required_csp());
833 EXPECT_EQ("script-src 'none'",
834 child_document->required_csp()->header->header_value);
835}
836
837TEST_F(CSPEmbeddedEnforcementUnitTest, ChildSiblingNoCSP) {
838 TestRenderFrameHost* top_document = main_rfh();
839 TestRenderFrameHost* child_document = AddChild(top_document);
840 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
841 TestRenderFrameHost* sibling_document = AddChild(top_document);
842 std::string sec_required_csp = NavigateWithRequiredCSP(&sibling_document, "");
843 EXPECT_FALSE(sibling_document->required_csp());
844}
845
846TEST_F(CSPEmbeddedEnforcementUnitTest, ChildSiblingCSP) {
847 TestRenderFrameHost* top_document = main_rfh();
848 TestRenderFrameHost* child_document = AddChild(top_document);
849 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
850 TestRenderFrameHost* sibling_document = AddChild(top_document);
851 std::string sec_required_csp =
852 NavigateWithRequiredCSP(&sibling_document, "script-src 'none'");
853 EXPECT_EQ("script-src 'none'", sec_required_csp);
854 EXPECT_TRUE(sibling_document->required_csp());
855 EXPECT_EQ("script-src 'none'",
856 sibling_document->required_csp()->header->header_value);
857}
858
859TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildNoCSP) {
860 TestRenderFrameHost* top_document = main_rfh();
861 TestRenderFrameHost* child_document = AddChild(top_document);
862 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
863 TestRenderFrameHost* grand_child_document = AddChild(child_document);
864 std::string sec_required_csp =
865 NavigateWithRequiredCSP(&grand_child_document, "");
866 EXPECT_EQ("script-src 'none'", sec_required_csp);
867 EXPECT_TRUE(grand_child_document->required_csp());
868 EXPECT_EQ("script-src 'none'",
869 grand_child_document->required_csp()->header->header_value);
870}
871
872TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildSameCSP) {
873 TestRenderFrameHost* top_document = main_rfh();
874 TestRenderFrameHost* child_document = AddChild(top_document);
875 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
876 TestRenderFrameHost* grand_child_document = AddChild(child_document);
877 std::string sec_required_csp =
878 NavigateWithRequiredCSP(&grand_child_document, "script-src 'none'");
879 EXPECT_EQ("script-src 'none'", sec_required_csp);
880 EXPECT_TRUE(grand_child_document->required_csp());
881 EXPECT_EQ("script-src 'none'",
882 grand_child_document->required_csp()->header->header_value);
883}
884
885TEST_F(CSPEmbeddedEnforcementUnitTest, GrandChildDifferentCSP) {
886 TestRenderFrameHost* top_document = main_rfh();
887 TestRenderFrameHost* child_document = AddChild(top_document);
888 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
889 TestRenderFrameHost* grand_child_document = AddChild(child_document);
890 std::string sec_required_csp =
891 NavigateWithRequiredCSP(&grand_child_document, "img-src 'none'");
892
893 // This seems weird, but it is the intended behaviour according to the spec.
894 // The problem is that "script-src 'none'" does not subsume "img-src 'none'",
895 // so "img-src 'none'" on the grandchild is an invalid csp attribute, and we
896 // just discard it in favour of the parent's csp attribute.
897 //
898 // This should probably be fixed in the specification:
899 // https://github.com/w3c/webappsec-cspee/pull/11
900 EXPECT_EQ("script-src 'none'", sec_required_csp);
901 EXPECT_TRUE(grand_child_document->required_csp());
902 EXPECT_EQ("script-src 'none'",
903 grand_child_document->required_csp()->header->header_value);
904}
905
906TEST_F(CSPEmbeddedEnforcementUnitTest, InvalidCSP) {
907 TestRenderFrameHost* top_document = main_rfh();
908 TestRenderFrameHost* child_document = AddChild(top_document);
909 std::string sec_required_csp =
910 NavigateWithRequiredCSP(&child_document, "report-to group");
911 EXPECT_EQ("", sec_required_csp);
912 EXPECT_FALSE(child_document->required_csp());
913}
914
915TEST_F(CSPEmbeddedEnforcementUnitTest, InvalidCspAndInheritFromParent) {
916 TestRenderFrameHost* top_document = main_rfh();
917 TestRenderFrameHost* child_document = AddChild(top_document);
918 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
919 TestRenderFrameHost* grand_child_document = AddChild(child_document);
920 std::string sec_required_csp =
Antonio Sartori4231e932021-02-04 12:01:14921 NavigateWithRequiredCSP(&grand_child_document, "report-to group");
arthursonzogni898dcda52021-01-21 08:50:10922 EXPECT_EQ("script-src 'none'", sec_required_csp);
923 EXPECT_TRUE(grand_child_document->required_csp());
924 EXPECT_EQ("script-src 'none'",
925 grand_child_document->required_csp()->header->header_value);
926}
927
928TEST_F(CSPEmbeddedEnforcementUnitTest,
929 SemiInvalidCspAndInheritSameCspFromParent) {
930 TestRenderFrameHost* top_document = main_rfh();
931 TestRenderFrameHost* child_document = AddChild(top_document);
932 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
933 TestRenderFrameHost* grand_child_document = AddChild(child_document);
934 std::string sec_required_csp = NavigateWithRequiredCSP(
Antonio Sartori4231e932021-02-04 12:01:14935 &grand_child_document, "script-src 'none'; report-to group");
arthursonzogni898dcda52021-01-21 08:50:10936 EXPECT_EQ("script-src 'none'", sec_required_csp);
937 EXPECT_TRUE(grand_child_document->required_csp());
938 EXPECT_EQ("script-src 'none'",
939 grand_child_document->required_csp()->header->header_value);
940}
941
942TEST_F(CSPEmbeddedEnforcementUnitTest,
943 SemiInvalidCspAndInheritDifferentCspFromParent) {
944 TestRenderFrameHost* top_document = main_rfh();
945 TestRenderFrameHost* child_document = AddChild(top_document);
946 NavigateWithRequiredCSP(&child_document, "script-src 'none'");
947 TestRenderFrameHost* grand_child_document = AddChild(child_document);
948 std::string sec_required_csp = NavigateWithRequiredCSP(
Antonio Sartori4231e932021-02-04 12:01:14949 &grand_child_document, "sandbox; report-to group");
arthursonzogni898dcda52021-01-21 08:50:10950 EXPECT_EQ("script-src 'none'", sec_required_csp);
951 EXPECT_TRUE(grand_child_document->required_csp());
952 EXPECT_EQ("script-src 'none'",
953 grand_child_document->required_csp()->header->header_value);
954}
955
clamy49678312015-10-22 21:59:00956} // namespace content