blob: 5b9977dfb20152fb781fe038e6961448fb8e8e86 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2020 The Chromium Authors
Antonio Sartori88ca1792020-10-09 06:26:452// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Antonio Sartori9290b6b2020-11-09 10:09:335#include "content/browser/renderer_host/policy_container_host.h"
Antonio Sartori88ca1792020-10-09 06:26:456
Peter Kasting1557e5f2025-01-28 01:14:087#include <algorithm>
8
Daniel Cheng8db1f0e2024-02-21 21:14:419#include "base/memory/scoped_refptr.h"
Nate Chapin63db0d12022-01-20 22:03:3010#include "content/browser/renderer_host/frame_navigation_entry.h"
11#include "content/browser/renderer_host/frame_tree_node.h"
Jonathan Hao9ebd2462023-07-27 16:06:0712#include "content/browser/renderer_host/private_network_access_util.h"
Nate Chapin63db0d12022-01-20 22:03:3013#include "content/browser/renderer_host/render_frame_host_impl.h"
Antonio Sartoridb967c52021-01-20 09:54:3014#include "content/public/browser/browser_thread.h"
Antonio Sartorid7af7d82025-04-22 09:24:1915#include "services/network/public/cpp/cross_origin_opener_policy.h"
16#include "services/network/public/cpp/document_isolation_policy.h"
Jonathan Haof6cd7692022-08-26 09:18:2117#include "services/network/public/cpp/is_potentially_trustworthy.h"
Antonio Sartori5d09b30f2021-03-02 09:27:1618#include "services/network/public/mojom/content_security_policy.mojom.h"
Yoav Weiss93d38b502025-05-06 15:55:5119#include "services/network/public/mojom/integrity_policy.mojom.h"
20
21namespace {
22template <typename T>
23std::string ConvertToString(const std::vector<T>& array) {
24 std::ostringstream oss;
25 size_t array_size = array.size();
26 for (size_t i = 0; i < array_size; ++i) {
27 oss << array[i];
28 if (i == array_size - 1) {
29 oss << ", ";
30 }
31 }
32 return oss.str();
33}
34} // namespace
Antonio Sartoridb967c52021-01-20 09:54:3035
Antonio Sartori88ca1792020-10-09 06:26:4536namespace content {
37
Titouan Rigoudy2f995bc2021-02-19 19:39:4138std::ostream& operator<<(std::ostream& out,
39 const PolicyContainerPolicies& policies) {
Antonio Sartori5d09b30f2021-03-02 09:27:1640 out << "{ referrer_policy: " << policies.referrer_policy
41 << ", ip_address_space: " << policies.ip_address_space
42 << ", is_web_secure_context: " << policies.is_web_secure_context
43 << ", content_security_policies: ";
44
Pâris MEULEMAN541156ae2021-04-29 07:52:0245 if (policies.content_security_policies.empty()) {
46 out << "[]";
47 } else {
48 out << "[ ";
49 auto it = policies.content_security_policies.begin();
50 for (; it + 1 != policies.content_security_policies.end(); ++it) {
51 out << (*it)->header->header_value << ", ";
52 }
53 out << (*it)->header->header_value << " ]";
Antonio Sartori5d09b30f2021-03-02 09:27:1654 }
Pâris MEULEMAN541156ae2021-04-29 07:52:0255
56 out << ", cross_origin_opener_policy: "
Camille Lamy10109fb2025-05-06 12:52:4457 << "{ value: " << policies.cross_origin_opener_policy.value
Pâris MEULEMAN541156ae2021-04-29 07:52:0258 << ", reporting_endpoint: "
59 << policies.cross_origin_opener_policy.reporting_endpoint.value_or(
60 "<null>")
61 << ", report_only_value: "
62 << policies.cross_origin_opener_policy.report_only_value
63 << ", report_only_reporting_endpoint: "
64 << policies.cross_origin_opener_policy.report_only_reporting_endpoint
65 .value_or("<null>")
Camille Lamyb988f142021-08-20 15:47:2866 << ", soap_by_default_value: "
67 << policies.cross_origin_opener_policy.soap_by_default_value << " }";
Pâris MEULEMAN541156ae2021-04-29 07:52:0268
Pâris Meuleman00d62b22022-01-14 13:43:4269 out << ", cross_origin_embedder_policy: "
70 << "{ value: " << policies.cross_origin_embedder_policy.value
71 << ", reporting_endpoint: "
72 << policies.cross_origin_embedder_policy.reporting_endpoint.value_or(
73 "<null>")
74 << ", report_only_value: "
75 << policies.cross_origin_embedder_policy.report_only_value
76 << ", report_only_reporting_endpoint: "
77 << policies.cross_origin_embedder_policy.report_only_reporting_endpoint
78 .value_or("<null>")
79 << " }";
80
Camille Lamyab870072024-04-16 15:18:1081 out << ", document_isolation_policy: " << "{ value: "
82 << policies.document_isolation_policy.value << ", reporting_endpoint: "
83 << policies.document_isolation_policy.reporting_endpoint.value_or(
84 "<null>")
85 << ", report_only_value: "
86 << policies.document_isolation_policy.report_only_value
87 << ", report_only_reporting_endpoint: "
88 << policies.document_isolation_policy.report_only_reporting_endpoint
89 .value_or("<null>")
90 << " }";
91
Yoav Weiss93d38b502025-05-06 15:55:5192 out << ", integrity_policy: " << "{ blocked-destinations: "
93 << ConvertToString<::network::mojom::IntegrityPolicy_Destination>(
94 policies.integrity_policy.blocked_destinations)
95 << ", sources: "
96 << ConvertToString<::network::mojom::IntegrityPolicy_Source>(
97 policies.integrity_policy.sources)
98 << ", endpoints: "
99 << ConvertToString<std::string>(policies.integrity_policy.endpoints)
100 << " }";
101
Pâris Meuleman687f7002022-02-16 11:11:34102 out << ", sandbox_flags: " << policies.sandbox_flags;
Arthur Sonzogni64457592022-11-22 11:08:59103 out << ", is_credentialless: " << policies.is_credentialless;
Liam Bradye6de25e2022-10-11 17:02:30104 out << ", can_navigate_top_without_user_gesture: "
105 << policies.can_navigate_top_without_user_gesture;
Camille Lamy1ce9a2062025-02-05 16:02:20106 out << ", cross_origin_isolationi_enabled_by_dip: "
107 << policies.cross_origin_isolation_enabled_by_dip;
Pâris Meuleman687f7002022-02-16 11:11:34108
Pâris MEULEMAN541156ae2021-04-29 07:52:02109 return out << " }";
Titouan Rigoudy2f995bc2021-02-19 19:39:41110}
111
Antonio Sartori5d09b30f2021-03-02 09:27:16112PolicyContainerPolicies::PolicyContainerPolicies() = default;
113
114PolicyContainerPolicies::PolicyContainerPolicies(
115 network::mojom::ReferrerPolicy referrer_policy,
116 network::mojom::IPAddressSpace ip_address_space,
117 bool is_web_secure_context,
118 std::vector<network::mojom::ContentSecurityPolicyPtr>
Pâris MEULEMAN541156ae2021-04-29 07:52:02119 content_security_policies,
Pâris Meuleman00d62b22022-01-14 13:43:42120 const network::CrossOriginOpenerPolicy& cross_origin_opener_policy,
Pâris Meuleman687f7002022-02-16 11:11:34121 const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
Camille Lamyab870072024-04-16 15:18:10122 const network::DocumentIsolationPolicy& document_isolation_policy,
Yoav Weiss93d38b502025-05-06 15:55:51123 network::IntegrityPolicy integrity_policy,
124 network::IntegrityPolicy integrity_policy_report_only,
Arthur Sonzognie41678a2022-06-16 15:51:19125 network::mojom::WebSandboxFlags sandbox_flags,
Arthur Sonzogni64457592022-11-22 11:08:59126 bool is_credentialless,
Jonathan Hao81558f62023-07-11 12:15:22127 bool can_navigate_top_without_user_gesture,
Camille Lamy1ce9a2062025-02-05 16:02:20128 bool cross_origin_isolation_enabled_by_dip)
Antonio Sartori5d09b30f2021-03-02 09:27:16129 : referrer_policy(referrer_policy),
130 ip_address_space(ip_address_space),
131 is_web_secure_context(is_web_secure_context),
Pâris MEULEMAN541156ae2021-04-29 07:52:02132 content_security_policies(std::move(content_security_policies)),
Pâris Meuleman00d62b22022-01-14 13:43:42133 cross_origin_opener_policy(cross_origin_opener_policy),
Pâris Meuleman687f7002022-02-16 11:11:34134 cross_origin_embedder_policy(cross_origin_embedder_policy),
Camille Lamyab870072024-04-16 15:18:10135 document_isolation_policy(document_isolation_policy),
Yoav Weiss93d38b502025-05-06 15:55:51136 integrity_policy(std::move(integrity_policy)),
137 integrity_policy_report_only(std::move(integrity_policy_report_only)),
Arthur Sonzognie41678a2022-06-16 15:51:19138 sandbox_flags(sandbox_flags),
Arthur Sonzogni64457592022-11-22 11:08:59139 is_credentialless(is_credentialless),
Liam Bradye6de25e2022-10-11 17:02:30140 can_navigate_top_without_user_gesture(
Jonathan Hao81558f62023-07-11 12:15:22141 can_navigate_top_without_user_gesture),
Camille Lamy1ce9a2062025-02-05 16:02:20142 cross_origin_isolation_enabled_by_dip(
143 cross_origin_isolation_enabled_by_dip) {}
Antonio Sartori5d09b30f2021-03-02 09:27:16144
Jonathan Haof6cd7692022-08-26 09:18:21145PolicyContainerPolicies::PolicyContainerPolicies(
Patrick Meenandd8e28222025-02-06 15:41:40146 const blink::mojom::PolicyContainerPolicies& policies,
147 bool is_web_secure_context)
Antonio Sartorid7af7d82025-04-22 09:24:19148 : PolicyContainerPolicies(policies.referrer_policy,
149 policies.ip_address_space,
150 is_web_secure_context,
151 mojo::Clone(policies.content_security_policies),
152 network::CrossOriginOpenerPolicy(),
153 policies.cross_origin_embedder_policy,
154 network::DocumentIsolationPolicy(),
Yoav Weiss93d38b502025-05-06 15:55:51155 std::move(policies.integrity_policy),
156 std::move(policies.integrity_policy_report_only),
Antonio Sartorid7af7d82025-04-22 09:24:19157 policies.sandbox_flags,
158 policies.is_credentialless,
159 policies.can_navigate_top_without_user_gesture,
Antonio Sartorid7af7d82025-04-22 09:24:19160 policies.cross_origin_isolation_enabled_by_dip) {}
Jonathan Haof6cd7692022-08-26 09:18:21161
162PolicyContainerPolicies::PolicyContainerPolicies(
163 const GURL& url,
164 network::mojom::URLResponseHead* response_head,
165 ContentBrowserClient* client)
166 : PolicyContainerPolicies(
167 network::mojom::ReferrerPolicy::kDefault,
168 CalculateIPAddressSpace(url, response_head, client),
169 network::IsUrlPotentiallyTrustworthy(url),
170 mojo::Clone(response_head->parsed_headers->content_security_policy),
171 response_head->parsed_headers->cross_origin_opener_policy,
172 response_head->parsed_headers->cross_origin_embedder_policy,
Camille Lamyab870072024-04-16 15:18:10173 response_head->parsed_headers->document_isolation_policy,
Yoav Weiss93d38b502025-05-06 15:55:51174 response_head->parsed_headers->integrity_policy,
175 response_head->parsed_headers->integrity_policy_report_only,
Jonathan Haof6cd7692022-08-26 09:18:21176 network::mojom::WebSandboxFlags::kNone,
Arthur Sonzogni64457592022-11-22 11:08:59177 /*is_credentialless=*/false,
Jonathan Hao81558f62023-07-11 12:15:22178 /*can_navigate_top_without_user_gesture=*/true,
Camille Lamy1ce9a2062025-02-05 16:02:20179 /*cross_origin_isolation_enabled_by_dip=*/false) {
Jonathan Haof6cd7692022-08-26 09:18:21180 for (auto& content_security_policy :
181 response_head->parsed_headers->content_security_policy) {
182 sandbox_flags |= content_security_policy->sandbox;
183 }
184}
185
Titouan Rigoudy72f892d2022-05-02 18:21:23186PolicyContainerPolicies::PolicyContainerPolicies(PolicyContainerPolicies&&) =
187 default;
188
189PolicyContainerPolicies& PolicyContainerPolicies::operator=(
190 PolicyContainerPolicies&&) = default;
191
Antonio Sartori5d09b30f2021-03-02 09:27:16192PolicyContainerPolicies::~PolicyContainerPolicies() = default;
193
Titouan Rigoudy72f892d2022-05-02 18:21:23194PolicyContainerPolicies PolicyContainerPolicies::Clone() const {
195 return PolicyContainerPolicies(
Antonio Sartori5d09b30f2021-03-02 09:27:16196 referrer_policy, ip_address_space, is_web_secure_context,
Pâris Meuleman00d62b22022-01-14 13:43:42197 mojo::Clone(content_security_policies), cross_origin_opener_policy,
Camille Lamyab870072024-04-16 15:18:10198 cross_origin_embedder_policy, mojo::Clone(document_isolation_policy),
Yoav Weiss93d38b502025-05-06 15:55:51199 integrity_policy, integrity_policy_report_only, sandbox_flags,
200 is_credentialless, can_navigate_top_without_user_gesture,
Camille Lamy10109fb2025-05-06 12:52:44201 cross_origin_isolation_enabled_by_dip);
Antonio Sartori5d09b30f2021-03-02 09:27:16202}
203
Titouan Rigoudy72f892d2022-05-02 18:21:23204std::unique_ptr<PolicyContainerPolicies> PolicyContainerPolicies::ClonePtr()
205 const {
206 return std::make_unique<PolicyContainerPolicies>(Clone());
207}
208
arthursonzogniadb80882021-03-11 10:43:30209void PolicyContainerPolicies::AddContentSecurityPolicies(
210 std::vector<network::mojom::ContentSecurityPolicyPtr> policies) {
211 content_security_policies.insert(content_security_policies.end(),
212 std::make_move_iterator(policies.begin()),
213 std::make_move_iterator(policies.end()));
214}
215
Jonathan Haof6cd7692022-08-26 09:18:21216blink::mojom::PolicyContainerPoliciesPtr
217PolicyContainerPolicies::ToMojoPolicyContainerPolicies() const {
218 return blink::mojom::PolicyContainerPolicies::New(
Yoav Weiss93d38b502025-05-06 15:55:51219 cross_origin_embedder_policy, integrity_policy,
220 integrity_policy_report_only, referrer_policy,
Arthur Sonzogni64457592022-11-22 11:08:59221 mojo::Clone(content_security_policies), is_credentialless, sandbox_flags,
Jonathan Hao81558f62023-07-11 12:15:22222 ip_address_space, can_navigate_top_without_user_gesture,
Camille Lamy10109fb2025-05-06 12:52:44223 cross_origin_isolation_enabled_by_dip);
Jonathan Haof6cd7692022-08-26 09:18:21224}
225
Titouan Rigoudy72f892d2022-05-02 18:21:23226PolicyContainerHost::PolicyContainerHost() = default;
Titouan Rigoudy6ec70402021-02-02 15:42:19227
Titouan Rigoudy72f892d2022-05-02 18:21:23228PolicyContainerHost::PolicyContainerHost(PolicyContainerPolicies policies)
229 : policies_(std::move(policies)) {}
Antonio Sartoridb967c52021-01-20 09:54:30230
Sharon Yang417a5df2024-04-23 17:57:15231PolicyContainerHost::~PolicyContainerHost() = default;
Antonio Sartoridb967c52021-01-20 09:54:30232
233void PolicyContainerHost::AssociateWithFrameToken(
Nate Chapin63db0d12022-01-20 22:03:30234 const blink::LocalFrameToken& frame_token,
235 int process_id) {
Antonio Sartoridb967c52021-01-20 09:54:30236 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Antonio Sartoridb967c52021-01-20 09:54:30237 frame_token_ = frame_token;
Nate Chapin63db0d12022-01-20 22:03:30238 process_id_ = process_id;
Antonio Sartoridb967c52021-01-20 09:54:30239}
Antonio Sartori88ca1792020-10-09 06:26:45240
Antonio Sartori9290b6b2020-11-09 10:09:33241void PolicyContainerHost::SetReferrerPolicy(
Antonio Sartori88ca1792020-10-09 06:26:45242 network::mojom::ReferrerPolicy referrer_policy) {
Titouan Rigoudy72f892d2022-05-02 18:21:23243 policies_.referrer_policy = referrer_policy;
Nate Chapin63db0d12022-01-20 22:03:30244 if (frame_token_) {
245 if (RenderFrameHostImpl* rfh = RenderFrameHostImpl::FromFrameToken(
246 process_id_, frame_token_.value())) {
247 rfh->DidChangeReferrerPolicy(referrer_policy);
248 }
249 }
Antonio Sartori88ca1792020-10-09 06:26:45250}
251
Antonio Sartori9c850b662021-03-02 15:13:02252void PolicyContainerHost::AddContentSecurityPolicies(
253 std::vector<network::mojom::ContentSecurityPolicyPtr>
254 content_security_policies) {
Titouan Rigoudy72f892d2022-05-02 18:21:23255 policies_.AddContentSecurityPolicies(std::move(content_security_policies));
Antonio Sartori9c850b662021-03-02 15:13:02256}
257
Antonio Sartori9290b6b2020-11-09 10:09:33258blink::mojom::PolicyContainerPtr
259PolicyContainerHost::CreatePolicyContainerForBlink() {
Antonio Sartori5b2f8042020-10-23 18:13:26260 // This function might be called several times, for example if we need to
261 // recreate the RenderFrame after the renderer process died. We gracefully
262 // handle this by resetting the receiver and creating a new one. It would be
263 // good to find a way to check that the previous remote has been deleted or is
264 // not needed anymore. Unfortunately, this cannot be done with a disconnect
265 // handler, since the mojo disconnect notification is not guaranteed to be
266 // received before we try to create a new remote.
267 policy_container_host_receiver_.reset();
Antonio Sartori9859aca2021-01-29 14:32:51268 mojo::PendingAssociatedRemote<blink::mojom::PolicyContainerHost> remote;
269 Bind(blink::mojom::PolicyContainerBindParams::New(
270 remote.InitWithNewEndpointAndPassReceiver()));
271
Antonio Sartori9290b6b2020-11-09 10:09:33272 return blink::mojom::PolicyContainer::New(
Jonathan Haof6cd7692022-08-26 09:18:21273 policies_.ToMojoPolicyContainerPolicies(), std::move(remote));
Antonio Sartori5b2f8042020-10-23 18:13:26274}
275
Antonio Sartoridb967c52021-01-20 09:54:30276scoped_refptr<PolicyContainerHost> PolicyContainerHost::Clone() const {
Titouan Rigoudy72f892d2022-05-02 18:21:23277 return base::MakeRefCounted<PolicyContainerHost>(policies_.Clone());
Antonio Sartori88ca1792020-10-09 06:26:45278}
279
Antonio Sartori9290b6b2020-11-09 10:09:33280void PolicyContainerHost::Bind(
Antonio Sartoridb967c52021-01-20 09:54:30281 blink::mojom::PolicyContainerBindParamsPtr bind_params) {
Antonio Sartoridb967c52021-01-20 09:54:30282 policy_container_host_receiver_.Bind(std::move(bind_params->receiver));
Antonio Sartori9859aca2021-01-29 14:32:51283
284 // Keep the PolicyContainerHost alive, as long as its PolicyContainer (owning
285 // the mojo remote) in the renderer process alive.
286 scoped_refptr<PolicyContainerHost> copy = this;
Antonio Sartoridb967c52021-01-20 09:54:30287 policy_container_host_receiver_.set_disconnect_handler(base::BindOnce(
Daniel Chengb7b2f5b2021-09-25 21:37:19288 [](scoped_refptr<PolicyContainerHost>) {}, std::move(copy)));
Antonio Sartoridb967c52021-01-20 09:54:30289}
290
Antonio Sartori88ca1792020-10-09 06:26:45291} // namespace content