blob: dace9c8a248aaa7a2e9584004fafda55fc36bff8 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]df8e899b2011-02-22 22:58:222// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]b9535422012-02-09 01:47:595#ifndef CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_
6#define CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_
[email protected]df8e899b2011-02-22 22:58:227
[email protected]df8e899b2011-02-22 22:58:228#include <map>
avi6f9a1d412016-08-16 16:07:319#include <memory>
[email protected]df8e899b2011-02-22 22:58:2210#include <set>
11#include <string>
Md Hasibul Hasana963a9342024-04-03 10:15:1412#include <string_view>
lukasza43c38f122016-06-17 20:07:3813#include <vector>
[email protected]df8e899b2011-02-22 22:58:2214
Alex Moshchuk4e19b362018-09-10 21:14:3615#include "base/containers/flat_map.h"
Lukasz Anforowicz0672f8a2017-11-30 01:07:0616#include "base/containers/flat_set.h"
[email protected]df8e899b2011-02-22 22:58:2217#include "base/gtest_prod_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5218#include "base/memory/raw_ptr.h"
lukasza4ec2e7572017-05-26 23:18:1019#include "base/memory/ref_counted.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/singleton.h"
[email protected]df8e899b2011-02-22 22:58:2221#include "base/synchronization/lock.h"
Lukasz Anforowicz5e71bd42018-09-17 19:28:5722#include "base/thread_annotations.h"
Takashi Toyoshimab89ec842021-07-12 10:39:4923#include "base/time/time.h"
Aaron Colwell1325f842019-10-07 20:37:5824#include "content/browser/can_commit_status.h"
Andrew Stone6ed99b22019-06-07 06:14:3925#include "content/browser/isolated_origin_util.h"
Alex Moshchuk8e5c1952019-01-15 03:39:5026#include "content/browser/isolation_context.h"
W. James MacLean7f76c2202021-11-15 16:27:4927#include "content/browser/origin_agent_cluster_isolation_state.h"
Lei Zhang7ab313752021-11-17 01:26:0028#include "content/common/content_export.h"
[email protected]b9535422012-02-09 01:47:5929#include "content/public/browser/child_process_security_policy.h"
Avi Drissman78865bbb2024-08-22 20:57:1930#include "content/public/common/bindings_policy.h"
DongJun Kimd6930ea2019-10-24 08:49:2531#include "storage/common/file_system/file_system_types.h"
alexmos3b9ad102017-05-26 23:41:0832#include "url/origin.h"
[email protected]df8e899b2011-02-22 22:58:2233
[email protected]df8e899b2011-02-22 22:58:2234class GURL;
35
[email protected]a3ef4832013-02-02 05:12:3336namespace base {
37class FilePath;
Sharon Yanga005ca12021-11-16 20:09:4238} // namespace base
[email protected]a3ef4832013-02-02 05:12:3339
John Abd-El-Malekb49606cf2018-01-12 17:23:3440namespace network {
41class ResourceRequestBody;
Sharon Yanga005ca12021-11-16 20:09:4242} // namespace network
John Abd-El-Malekb49606cf2018-01-12 17:23:3443
[email protected]cd501a72014-08-22 19:58:3144namespace storage {
lukasza4ec2e7572017-05-26 23:18:1045class FileSystemContext;
[email protected]ce5cbed82013-07-01 11:52:3146class FileSystemURL;
Andrew Stone6ed99b22019-06-07 06:14:3947} // namespace storage
[email protected]ce5cbed82013-07-01 11:52:3148
[email protected]46488322012-10-30 03:22:2049namespace content {
50
Aaron Colwellea6921f2019-01-29 16:50:3951class BrowserContext;
Alex Moshchuk8e5c1952019-01-15 03:39:5052class IsolationContext;
Sharon Yanga005ca12021-11-16 20:09:4253class ProcessLock;
Alex Moshchuk99b795422019-03-07 00:27:3254class ResourceContext;
David Sandersc6fd8262022-02-22 19:20:3355struct UrlInfo;
Alex Moshchuk8865a062021-03-12 21:33:4456
[email protected]b9535422012-02-09 01:47:5957class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
Nico Weber43ddd7a32017-08-15 19:19:2758 : public ChildProcessSecurityPolicy {
[email protected]df8e899b2011-02-22 22:58:2259 public:
Aaron Colwell4fcbe4152020-01-16 07:10:5960 // Handle used to access the security state for a specific process.
61 //
62 // Objects that require the security state to be preserved beyond the
63 // lifetime of the RenderProcessHostImpl should hold an instance of this
64 // object and use it to answer security policy questions. (e.g. Mojo services
65 // created by RPHI that can receive calls after RPHI destruction). This
66 // object should only be called on the UI and IO threads.
67 //
68 // Note: Some security methods, like CanAccessDataForOrigin(), require
69 // information from the BrowserContext to make its decisions. These methods
70 // will fall back to failsafe values if called after BrowserContext
71 // destruction. Callers should be prepared to gracefully handle this or
72 // ensure that they don't make any calls after BrowserContext destruction.
73 class CONTENT_EXPORT Handle {
74 public:
75 Handle();
76 Handle(Handle&&);
77 Handle(const Handle&) = delete;
78 ~Handle();
79
80 Handle& operator=(const Handle&) = delete;
81 Handle& operator=(Handle&&);
82
Alex Moshchukc1701542020-02-06 19:29:3283 // Create a new instance of Handle, holding another reference to the same
84 // process ID as the current one.
85 Handle Duplicate();
86
Aaron Colwell4fcbe4152020-01-16 07:10:5987 // Returns true if this object has a valid process ID.
88 // Returns false if this object was created with the default constructor,
89 // the contents of this object was transferred to another Handle via
90 // std::move(), or ChildProcessSecurityPolicyImpl::CreateHandle()
91 // created this object after the process has already been destructed.
92 bool is_valid() const;
93
Aaron Colwell4fcbe4152020-01-16 07:10:5994 // Before servicing a child process's request to upload a file to the web,
95 // the browser should call this method to determine whether the process has
96 // the capability to upload the requested file.
97 bool CanReadFile(const base::FilePath& file);
98
99 // Explicit read permissions check for FileSystemURL specified files.
100 bool CanReadFileSystemFile(const storage::FileSystemURL& url);
101
102 // Returns true if the process is permitted to read and modify the data for
Alex Moshchuk174e1722023-11-30 02:17:20103 // the given `origin`. For more details, see
104 // ChildProcessSecurityPolicy::CanAccessDataForOrigin().
Aaron Colwell4fcbe4152020-01-16 07:10:59105 bool CanAccessDataForOrigin(const url::Origin& origin);
106
Ari Chivukulaccb16aeb2021-10-01 01:47:12107 // Returns the original `child_id` used to create the handle.
108 int child_id() { return child_id_; }
109
Aaron Colwell4fcbe4152020-01-16 07:10:59110 private:
111 friend class ChildProcessSecurityPolicyImpl;
Aaron Colwelldd9dce32020-06-04 21:03:52112 // |child_id| - The ID of the process that this Handle is being created
113 // for, or ChildProcessHost::kInvalidUniqueID if an invalid handle is being
114 // created.
115 // |duplicating_handle| - True if the handle is being created by a
116 // Duplicate() call. Otherwise false. This is used to trigger special
117 // behavior for handle duplication that is not allowed for Handles created
118 // by other means.
119 Handle(int child_id, bool duplicating_handle);
Aaron Colwell4fcbe4152020-01-16 07:10:59120
121 // The ID of the child process that this handle is associated with or
122 // ChildProcessHost::kInvalidUniqueID if the handle is no longer valid.
123 int child_id_;
124 };
125
Peter Boström9b036532021-10-28 23:37:28126 ChildProcessSecurityPolicyImpl(const ChildProcessSecurityPolicyImpl&) =
127 delete;
128 ChildProcessSecurityPolicyImpl& operator=(
129 const ChildProcessSecurityPolicyImpl&) = delete;
130
[email protected]df8e899b2011-02-22 22:58:22131 // Object can only be created through GetInstance() so the constructor is
132 // private.
dchengc2282aa2014-10-21 12:07:58133 ~ChildProcessSecurityPolicyImpl() override;
[email protected]df8e899b2011-02-22 22:58:22134
[email protected]b9535422012-02-09 01:47:59135 static ChildProcessSecurityPolicyImpl* GetInstance();
[email protected]df8e899b2011-02-22 22:58:22136
[email protected]b9535422012-02-09 01:47:59137 // ChildProcessSecurityPolicy implementation.
dchengc2282aa2014-10-21 12:07:58138 void RegisterWebSafeScheme(const std::string& scheme) override;
nick2a8ba8c2016-10-03 18:51:39139 void RegisterWebSafeIsolatedScheme(
140 const std::string& scheme,
141 bool always_allow_in_origin_headers) override;
dchengc2282aa2014-10-21 12:07:58142 bool IsWebSafeScheme(const std::string& scheme) override;
143 void GrantReadFile(int child_id, const base::FilePath& file) override;
144 void GrantCreateReadWriteFile(int child_id,
145 const base::FilePath& file) override;
146 void GrantCopyInto(int child_id, const base::FilePath& dir) override;
147 void GrantDeleteFrom(int child_id, const base::FilePath& dir) override;
148 void GrantReadFileSystem(int child_id,
149 const std::string& filesystem_id) override;
150 void GrantWriteFileSystem(int child_id,
151 const std::string& filesystem_id) override;
152 void GrantCreateFileForFileSystem(int child_id,
153 const std::string& filesystem_id) override;
154 void GrantCreateReadWriteFileSystem(
[email protected]aa7cfbf2012-06-01 08:48:09155 int child_id,
mohan.reddy7fc3ac72014-10-09 05:24:13156 const std::string& filesystem_id) override;
dchengc2282aa2014-10-21 12:07:58157 void GrantCopyIntoFileSystem(int child_id,
158 const std::string& filesystem_id) override;
159 void GrantDeleteFromFileSystem(int child_id,
mohan.reddy7fc3ac72014-10-09 05:24:13160 const std::string& filesystem_id) override;
Daniel Cheng4ebba552018-07-06 21:43:16161 void GrantCommitOrigin(int child_id, const url::Origin& origin) override;
162 void GrantRequestOrigin(int child_id, const url::Origin& origin) override;
163 void GrantRequestScheme(int child_id, const std::string& scheme) override;
nick2a8ba8c2016-10-03 18:51:39164 bool CanRequestURL(int child_id, const GURL& url) override;
dchengc2282aa2014-10-21 12:07:58165 bool CanReadFile(int child_id, const base::FilePath& file) override;
166 bool CanCreateReadWriteFile(int child_id,
167 const base::FilePath& file) override;
168 bool CanReadFileSystem(int child_id,
169 const std::string& filesystem_id) override;
170 bool CanReadWriteFileSystem(int child_id,
171 const std::string& filesystem_id) override;
172 bool CanCopyIntoFileSystem(int child_id,
173 const std::string& filesystem_id) override;
174 bool CanDeleteFromFileSystem(int child_id,
175 const std::string& filesystem_id) override;
176 bool HasWebUIBindings(int child_id) override;
Michael Wilsona24fe882023-06-01 01:02:50177 void GrantSendMidiMessage(int child_id) override;
mlamouri97de25e42014-11-25 10:50:23178 void GrantSendMidiSysExMessage(int child_id) override;
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:47179 bool CanAccessDataForOrigin(int child_id, const url::Origin& origin) override;
Alex Moshchuk99c22682024-03-28 22:43:46180 bool HostsOrigin(int child_id, const url::Origin& origin) override;
Alex Moshchukef8c2562021-03-12 06:37:45181 void AddFutureIsolatedOrigins(
Md Hasibul Hasana963a9342024-04-03 10:15:14182 std::string_view origins_list,
Alex Moshchukef8c2562021-03-12 06:37:45183 IsolatedOriginSource source,
184 BrowserContext* browser_context = nullptr) override;
185 void AddFutureIsolatedOrigins(
186 const std::vector<url::Origin>& origins,
187 IsolatedOriginSource source,
188 BrowserContext* browser_context = nullptr) override;
Lukasz Anforowicz65c61162019-03-27 20:33:58189 bool IsGloballyIsolatedOriginForTesting(const url::Origin& origin) override;
Alex Moshchukc4679422019-06-11 17:04:48190 std::vector<url::Origin> GetIsolatedOrigins(
Arthur Sonzognic686e8f2024-01-11 08:36:37191 std::optional<IsolatedOriginSource> source = std::nullopt,
Alex Moshchukc4679422019-06-11 17:04:48192 BrowserContext* browser_context = nullptr) override;
rajendrant015529c2020-12-18 04:21:52193 bool IsIsolatedSiteFromSource(const url::Origin& origin,
194 IsolatedOriginSource source) override;
Alex Moshchuk51e1428b2020-04-22 18:00:54195 void ClearIsolatedOriginsForTesting() override;
Alex Moshchuk25754cd42018-12-05 22:43:08196
Alex Moshchuk99c22682024-03-28 22:43:46197 // Centralized internal implementation of site isolation enforcements,
198 // including CanAccessDataForOrigin and HostsOrigin. It supports the following
199 // types of access checks, in order of increasing strictness:
200 enum class AccessType {
201 // Whether the process can commit a navigation to an origin, allowing a
202 // document with that origin to be hosted in this process. This is
203 // specifically about whether a particular new origin may be introduced
204 // into a given process.
205 kCanCommitNewOrigin,
206 // Whether the process has previously committed a document or instantiated a
207 // worker with the particular origin. This can be used to verify whether a
208 // particular origin can be used as an initiator or source origin, e.g. in
209 // postMessage or other IPCs sent from this process. Unlike
210 // kCanCommitNewOrigin, this check assumes that the origin must already
211 // exist in the process. Because a document/worker destruction may race with
212 // processing legitimate IPCs on behalf of `origin`, this check also allows
213 // the case where an origin has been hosted by the process in the past, but
214 // not necessarily now.
215 kHostsOrigin,
216 // Whether the process can access data belonging to an origin already
217 // committed in the process, such as passwords, localStorage, or cookies.
218 // Similarly to kHostsOrigin, this check assumes that the origin must
219 // already
220 // exist in the process, but it is more strict for certain kinds of
221 // processes that aren't supposed to access any data. For example, sandboxed
222 // frame processes (which contain only opaque origins) or PDF processes
223 // cannot access data for any origin.
224 kCanAccessDataForCommittedOrigin,
225 };
226 bool CanAccessOrigin(int child_id,
227 const url::Origin& origin,
228 AccessType access_type);
229
Arthur Hemery821fa5d2021-08-30 13:32:42230 // Determines if the combination of origin, url and web_exposed_isolation_info
231 // bundled in `url_info` are safe to commit to the process associated with
232 // `child_id`.
Aaron Colwell1325f842019-10-07 20:37:58233 //
Arthur Hemery821fa5d2021-08-30 13:32:42234 // Returns CAN_COMMIT_ORIGIN_AND_URL if it is safe to commit `url_info` origin
235 // and `url_info`'s url combination to the process associated with `child_id`.
236 // Returns CANNOT_COMMIT_URL if `url_info` url is not safe to commit.
237 // Returns CANNOT_COMMIT_ORIGIN if `url_info` origin is not safe to commit.
Aaron Colwelld759e542019-10-09 17:45:06238 CanCommitStatus CanCommitOriginAndUrl(
239 int child_id,
240 const IsolationContext& isolation_context,
Arthur Hemery821fa5d2021-08-30 13:32:42241 const UrlInfo& url_info);
Aaron Colwell1325f842019-10-07 20:37:58242
Alex Moshchukb51984772024-03-29 00:57:31243 // Whether the process is allowed to commit a document from the given URL.
244 // This is more restrictive than CanRequestURL, since CanRequestURL allows
245 // requests that might lead to cross-process navigations or external protocol
246 // handlers. Used primarily as a helper for CanCommitOriginAndUrl and thus not
247 // exposed publicly.
248 bool CanCommitURL(int child_id, const GURL& url);
249
Alex Moshchuk8e5c1952019-01-15 03:39:50250 // This function will check whether |origin| requires process isolation
251 // within |isolation_context|, and if so, it will return true and put the
252 // most specific matching isolated origin into |result|.
Alex Moshchuk25754cd42018-12-05 22:43:08253 //
254 // Such origins may be registered with the --isolate-origins command-line
255 // flag, via features::IsolateOrigins, via an IsolateOrigins enterprise
256 // policy, or by a content/ embedder using
257 // ContentBrowserClient::GetOriginsRequiringDedicatedProcess().
258 //
259 // If |origin| does not require process isolation, this function will return
260 // false, and |result| will be a unique origin. This means that neither
261 // |origin|, nor any origins for which |origin| is a subdomain, have been
262 // registered as isolated origins.
263 //
264 // For example, if both https://isolated.com/ and
265 // https://bar.foo.isolated.com/ are registered as isolated origins, then the
266 // values returned in |result| are:
267 // https://isolated.com/ --> https://isolated.com/
268 // https://foo.isolated.com/ --> https://isolated.com/
269 // https://bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
270 // https://baz.bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
271 // https://unisolated.com/ --> (unique origin)
Alex Moshchuk8e5c1952019-01-15 03:39:50272 //
273 // |isolation_context| is used to determine which origins are isolated in
274 // this context. For example, isolated origins that are dynamically added
275 // will only affect future BrowsingInstances.
W. James MacLean92e39c82021-02-25 23:27:34276 bool GetMatchingProcessIsolatedOrigin(
277 const IsolationContext& isolation_context,
278 const url::Origin& origin,
W. James MacLean7f76c2202021-11-15 16:27:49279 bool requests_origin_keyed_process,
W. James MacLean92e39c82021-02-25 23:27:34280 url::Origin* result);
[email protected]df8e899b2011-02-22 22:58:22281
Peter KHa027bf62025-07-29 15:22:52282 // Removes any state associated with `browsing_instance_id`.
283 void RemoveAllStateForBrowsingInstance(
W. James MacLean89307252020-11-11 00:16:44284 const BrowsingInstanceId& browsing_instance_id);
W. James MacLean64ddbcc2020-01-24 22:34:22285
W. James MacLeanc07dc41b2022-07-25 18:52:16286 // Registers |origin| isolation state in the BrowsingInstance associated
Alex Moshchuk331fa5f2021-03-10 06:16:59287 // with |isolation_context|.
288 //
Camille Lamy5ce9b962025-08-08 12:10:45289 // |oac_isolation_state| is the Origin-Agent-Cluster to register for the
290 // origin. It contains values describing both the logical isolation (i.e.
291 // agent cluster separation in the renderer process) and the process isolation
292 // that can be triggered by the Origin-Agent-Cluster header, the
293 // kOriginKeyedProcessesByDefault feature and the
294 // kOriginAgentClusterDefaultEnabled feature.
Alex Moshchuk331fa5f2021-03-10 06:16:59295 //
296 // If |origin| has already been registered as isolated for the same
Camille Lamy5ce9b962025-08-08 12:10:45297 // BrowsingInstance, then nothing will be changed by this call.
298 void AddOriginAgentClusterStateForBrowsingInstance(
W. James MacLean64ddbcc2020-01-24 22:34:22299 const IsolationContext& isolation_context,
Alex Moshchuk331fa5f2021-03-10 06:16:59300 const url::Origin& origin,
Camille Lamy5ce9b962025-08-08 12:10:45301 const OriginAgentClusterIsolationState& oac_isolation_state);
W. James MacLeanc07dc41b2022-07-25 18:52:16302
303 // Adds `origin` to the IsolatedOrigins list for only the BrowsingInstance of
304 // `isolation_context`, without isolating all subdomains. For use when the
305 // isolation is triggered by COOP headers.
306 void AddCoopIsolatedOriginForBrowsingInstance(
307 const IsolationContext& isolation_context,
308 const url::Origin& origin,
Alex Moshchuk331fa5f2021-03-10 06:16:59309 IsolatedOriginSource source);
W. James MacLean64ddbcc2020-01-24 22:34:22310
W. James MacLean7f76c2202021-11-15 16:27:49311 // This function will check whether |origin| has opted-in to logical or
312 // process isolation (via the Origin-Agent-Cluster header), with respect to
313 // the current state of the |isolation_context|. It is different from
314 // IsIsolatedOrigin() in that it only deals with Origin-Agent-Cluster
315 // isolation status, whereas IsIsolatedOrigin() considers all possible
316 // mechanisms for requesting isolation. It will check for two things:
W. James MacLean1c40862c2020-04-27 21:05:57317 // 1) whether |origin| already is assigned to a SiteInstance in the
W. James MacLeand42fa812021-11-18 22:59:26318 // |isolation_context| by being tracked in
W. James MacLean1c40862c2020-04-27 21:05:57319 // |origin_isolation_by_browsing_instance_|, in which case we follow the
320 // same policy, or
321 // 2) if it's not currently tracked as described above, whether |origin| is
W. James MacLean7f76c2202021-11-15 16:27:49322 // currently requesting isolation via |requested_isolation_state|.
W. James MacLeand42fa812021-11-18 22:59:26323 OriginAgentClusterIsolationState DetermineOriginAgentClusterIsolation(
W. James MacLean7f76c2202021-11-15 16:27:49324 const IsolationContext& isolation_context,
325 const url::Origin& origin,
326 const OriginAgentClusterIsolationState& requested_isolation_state);
W. James MacLean64ddbcc2020-01-24 22:34:22327
W. James MacLean1c40862c2020-04-27 21:05:57328 // This function adds |origin| to the master list of origins that have
W. James MacLean46fc0b62020-11-18 16:18:45329 // ever requested opt-in isolation in the given |browser_context|, either via
W. James MacLeand7eb1562020-11-17 17:56:10330 // an OriginPolicy or opt-in header. Returns true if |origin| is not already
331 // in the list.
332 bool UpdateOriginIsolationOptInListIfNecessary(
333 BrowserContext* browser_context,
334 const url::Origin& origin);
W. James MacLean64ddbcc2020-01-24 22:34:22335
W. James MacLean92e39c82021-02-25 23:27:34336 // A version of GetMatchingProcessIsolatedOrigin that takes in both the
337 // |origin| and the |site_url| that |origin| corresponds to. |site_url| is
338 // the key by which |origin| will be looked up in |isolated_origins_| within
Alex Moshchuk8e5c1952019-01-15 03:39:50339 // |isolation_context|; this function allows it to be passed in when it is
340 // already known to avoid recomputing it internally.
W. James MacLean92e39c82021-02-25 23:27:34341 bool GetMatchingProcessIsolatedOrigin(
342 const IsolationContext& isolation_context,
343 const url::Origin& origin,
W. James MacLean7f76c2202021-11-15 16:27:49344 bool requests_origin_keyed_process,
W. James MacLean92e39c82021-02-25 23:27:34345 const GURL& site_url,
346 url::Origin* result);
Alex Moshchuk4e19b362018-09-10 21:14:36347
Peter KHa027bf62025-07-29 15:22:52348 // Stores the v8-optimization state for the passed-in `browsing_instance_id`
349 // and `process_lock_origin`.
350 void AddV8OptimizationDisabledStateForOrigin(
351 const BrowsingInstanceId& browsing_instance_id,
352 const url::Origin& process_lock_origin,
353 bool are_v8_optimizations_disabled);
354
355 // Returns whether v8-optimization should be disabled for the passed-in
356 // (`browsing_instance_id`, `process_lock_origin`) pair. Returns std::nullopt
357 // if there is no cached v8-optimization verdict.
358 std::optional<bool> LookupAreV8OptimizationsDisabled(
359 const BrowsingInstanceId& browsing_instance_id,
360 const url::Origin& process_lock_origin);
361
lukasza43c38f122016-06-17 20:07:38362 // Returns if |child_id| can read all of the |files|.
363 bool CanReadAllFiles(int child_id, const std::vector<base::FilePath>& files);
364
lukasza5e8bef0e2017-05-30 23:41:45365 // Validate that |child_id| in |file_system_context| is allowed to access
366 // data in the POST body specified by |body|. Can be called on any thread.
John Abd-El-Malekb49606cf2018-01-12 17:23:34367 bool CanReadRequestBody(
368 int child_id,
369 const storage::FileSystemContext* file_system_context,
370 const scoped_refptr<network::ResourceRequestBody>& body);
lukasza5e8bef0e2017-05-30 23:41:45371
Sharon Yang59197b2a2023-03-24 17:49:24372 // Validate that `process` is allowed to access data in the POST body
373 // specified by |body|. Has to be called on the UI thread.
John Abd-El-Malekb49606cf2018-01-12 17:23:34374 bool CanReadRequestBody(
Sharon Yang59197b2a2023-03-24 17:49:24375 RenderProcessHost* process,
John Abd-El-Malekb49606cf2018-01-12 17:23:34376 const scoped_refptr<network::ResourceRequestBody>& body);
lukasza4ec2e7572017-05-26 23:18:10377
[email protected]df8e899b2011-02-22 22:58:22378 // Pseudo schemes are treated differently than other schemes because they
379 // cannot be requested like normal URLs. There is no mechanism for revoking
380 // pseudo schemes.
381 void RegisterPseudoScheme(const std::string& scheme);
382
383 // Returns true iff |scheme| has been registered as pseudo scheme.
384 bool IsPseudoScheme(const std::string& scheme);
385
386 // Upon creation, child processes should register themselves by calling this
Aaron Colwellea6921f2019-01-29 16:50:39387 // this method exactly once. This call must be made on the UI thread.
388 void Add(int child_id, BrowserContext* browser_context);
[email protected]df8e899b2011-02-22 22:58:22389
Aaron Colwellffade2a2020-09-16 20:54:41390 // Helper method for unit tests that calls Add() and
391 // LockProcess() with an "allow_any_site" lock. This ensures that the process
392 // policy is always in a state where it is valid to call
393 // CanAccessDataForOrigin().
394 void AddForTesting(int child_id, BrowserContext* browser_context);
395
Aaron Colwell529eb6e2019-01-24 04:31:53396 // Upon destruction, child processes should unregister themselves by calling
Aaron Colwellea6921f2019-01-29 16:50:39397 // this method exactly once. This call must be made on the UI thread.
Aaron Colwelldc211742019-04-05 21:04:01398 //
399 // Note: Pre-Remove() permissions remain in effect on the IO thread until
400 // the task posted to the IO thread by this call runs and removes the entry
401 // from |pending_remove_state_|.
402 // This UI -> IO task sequence ensures that any pending tasks, on the IO
403 // thread, for this |child_id| are allowed to run before access is completely
404 // revoked.
[email protected]df8e899b2011-02-22 22:58:22405 void Remove(int child_id);
406
Daniel Cheng4ebba552018-07-06 21:43:16407 // Whenever the browser processes commands the child process to commit a URL,
[email protected]df8e899b2011-02-22 22:58:22408 // it should call this method to grant the child process the capability to
Daniel Cheng4ebba552018-07-06 21:43:16409 // commit anything from the URL's origin, along with permission to request all
410 // URLs of the same scheme.
411 void GrantCommitURL(int child_id, const GURL& url);
[email protected]df8e899b2011-02-22 22:58:22412
[email protected]dc67e1c32012-06-08 00:10:40413 // Whenever the browser process drops a file icon on a tab, it should call
414 // this method to grant the child process the capability to request this one
Joel Hockey91f58d7aa2024-10-03 22:59:21415 // file:// URL (or content:// URL in android), but not all urls of the file://
416 // scheme.
417 void GrantRequestOfSpecificFile(int child_id, const base::FilePath& file);
[email protected]dc67e1c32012-06-08 00:10:40418
[email protected]df8e899b2011-02-22 22:58:22419 // Revokes all permissions granted to the given file.
[email protected]a3ef4832013-02-02 05:12:33420 void RevokeAllPermissionsForFile(int child_id, const base::FilePath& file);
[email protected]df8e899b2011-02-22 22:58:22421
Avi Drissman78865bbb2024-08-22 20:57:19422 // Grant the child process the ability to use Web UI Bindings.
423 void GrantWebUIBindings(int child_id, BindingsPolicySet bindings);
[email protected]df8e899b2011-02-22 22:58:22424
[email protected]df8e899b2011-02-22 22:58:22425 // Grant the child process the ability to read raw cookies.
426 void GrantReadRawCookies(int child_id);
427
428 // Revoke read raw cookies permission.
429 void RevokeReadRawCookies(int child_id);
430
Charlie Reisc1f5da62024-05-17 16:13:43431 // Some APIs for Android WebView and <webview> tags allow bypassing some
Charlie Reis05556262024-04-25 21:30:49432 // security checks, such as which URLs are allowed to commit. This method
Charlie Reisc1f5da62024-05-17 16:13:43433 // grants that ability to any document with an origin used with these APIs,
434 // because the exemption is needed for about:blank frames that inherit the
435 // same origin.
436 //
437 // For safety, this is limited to opaque origins used with LoadDataWithBaseURL
438 // in unlocked processes, as well as file origins used with
439 // allow_universal_access_from_file_urls.
Charlie Reis05556262024-04-25 21:30:49440 //
441 // Note that LoadDataWithBaseURL can be used with non-opaque origins as well,
442 // but in that case the bypass is only allowed for the document and not the
443 // entire origin, to prevent other code in the origin from bypassing checks.
Charlie Reisc1f5da62024-05-17 16:13:43444 void GrantOriginCheckExemptionForWebView(int child_id,
445 const url::Origin& origin);
Charlie Reis05556262024-04-25 21:30:49446
Charlie Reisc1f5da62024-05-17 16:13:43447 // Returns whether the given opaque or file origin was granted an exemption
448 // due to Android WebView and <webview> APIs, allowing its documents to bypass
449 // certain URL and origin checks.
450 bool HasOriginCheckExemptionForWebView(int child_id,
451 const url::Origin& origin);
Charlie Reis05556262024-04-25 21:30:49452
[email protected]9f104312013-07-23 23:18:19453 // Explicit permissions checks for FileSystemURL specified files.
nickb3c1e272016-10-07 22:56:37454 bool CanReadFileSystemFile(int child_id,
455 const storage::FileSystemURL& filesystem_url);
456 bool CanWriteFileSystemFile(int child_id,
457 const storage::FileSystemURL& filesystem_url);
458 bool CanCreateFileSystemFile(int child_id,
459 const storage::FileSystemURL& filesystem_url);
460 bool CanCreateReadWriteFileSystemFile(
461 int child_id,
462 const storage::FileSystemURL& filesystem_url);
[email protected]4b9d0862013-10-15 19:49:41463 bool CanCopyIntoFileSystemFile(int child_id,
nickb3c1e272016-10-07 22:56:37464 const storage::FileSystemURL& filesystem_url);
465 bool CanDeleteFileSystemFile(int child_id,
466 const storage::FileSystemURL& filesystem_url);
Chris Bookholt6b6383e2021-12-10 21:37:54467 bool CanMoveFileSystemFile(int child_id,
468 const storage::FileSystemURL& src_url,
469 const storage::FileSystemURL& dest_url);
470 bool CanCopyFileSystemFile(int child_id,
471 const storage::FileSystemURL& src_url,
472 const storage::FileSystemURL& dest_url);
[email protected]9f104312013-07-23 23:18:19473
[email protected]df8e899b2011-02-22 22:58:22474 // Returns true if the specified child_id has been granted ReadRawCookies.
475 bool CanReadRawCookies(int child_id);
476
Lukasz Anforowicz38003582019-09-24 19:08:05477 // Notifies security state of |child_id| about the IsolationContext it will
478 // host. The main side effect is proper setting of the lowest
479 // BrowsingInstanceId associated with the security state.
480 void IncludeIsolationContext(int child_id,
481 const IsolationContext& isolation_context);
482
Alex Moshchuk8e5c1952019-01-15 03:39:50483 // Sets the process identified by |child_id| as only permitted to access data
W. James MacLeane84fa112020-07-14 17:25:54484 // for the origin specified by |site_info|'s process_lock_url(). Most callers
485 // should use RenderProcessHostImpl::SetProcessLock instead of calling this
486 // directly. |isolation_context| provides the context, such as
487 // BrowsingInstance, from which this process locked was created. This
488 // information is used when making isolation decisions for this process, such
Charlie Reis47457a62022-05-18 21:57:37489 // as determining which isolated origins pertain to it. |is_process_used|
490 // indicates whether any content has been loaded in the process already.
W. James MacLeane84fa112020-07-14 17:25:54491 void LockProcess(const IsolationContext& isolation_context,
492 int child_id,
Charlie Reis47457a62022-05-18 21:57:37493 bool is_process_used,
W. James MacLeane84fa112020-07-14 17:25:54494 const ProcessLock& process_lock);
[email protected]313b80bd2011-11-23 03:49:10495
Aaron Colwell80f85bb2020-05-19 01:55:06496 // Testing helper method that generates a lock_url from |url| and then
W. James MacLeane84fa112020-07-14 17:25:54497 // calls LockProcess() with that lock URL.
Aaron Colwell80f85bb2020-05-19 01:55:06498 void LockProcessForTesting(const IsolationContext& isolation_context,
499 int child_id,
500 const GURL& url);
501
W. James MacLeane84fa112020-07-14 17:25:54502 // Retrieves the current ProcessLock of process |child_id|. Returns an empty
503 // lock if the process does not exist or if it is not locked.
504 ProcessLock GetProcessLock(int child_id);
Alex Moshchuk75cffa92017-10-11 20:24:02505
[email protected]ce5cbed82013-07-01 11:52:31506 // Register FileSystem type and permission policy which should be used
507 // for the type. The |policy| must be a bitwise-or'd value of
[email protected]cd501a72014-08-22 19:58:31508 // storage::FilePermissionPolicy.
509 void RegisterFileSystemPermissionPolicy(storage::FileSystemType type,
510 int policy);
[email protected]ce5cbed82013-07-01 11:52:31511
Michael Wilsona24fe882023-06-01 01:02:50512 // Returns true if sending MIDI messages is allowed.
513 bool CanSendMidiMessage(int child_id);
514
515 // Returns true if sending system exclusive (SysEx) MIDI messages is allowed.
[email protected]6e068ea2014-02-04 07:05:47516 bool CanSendMidiSysExMessage(int child_id);
[email protected]4ca7cf0f2013-08-28 14:19:03517
Aaron Colwell4fcbe4152020-01-16 07:10:59518 // Remove all isolated origins associated with |browser_context| and clear any
519 // pointers that may reference |browser_context|. This is
Aaron Colwell67f93006c2019-04-01 22:45:28520 // typically used when |browser_context| is being destroyed and assumes that
521 // no processes are running or will run for that profile; this makes the
522 // isolated origin removal safe. Note that |browser_context| cannot be null;
523 // i.e., isolated origins that apply globally to all profiles cannot
524 // currently be removed, since that is not safe to do at runtime.
Aaron Colwell4fcbe4152020-01-16 07:10:59525 void RemoveStateForBrowserContext(const BrowserContext& browser_context);
alexmos3b9ad102017-05-26 23:41:08526
Alex Moshchuk8e5c1952019-01-15 03:39:50527 // Check whether |origin| requires origin-wide process isolation within
528 // |isolation_context|.
alexmos4bc26322017-07-01 00:57:14529 //
530 // Subdomains of an isolated origin are considered part of that isolated
531 // origin. Thus, if https://isolated.foo.com/ had been added as an isolated
532 // origin, this will return true for https://isolated.foo.com/,
533 // https://bar.isolated.foo.com/, or https://baz.bar.isolated.foo.com/; and
534 // it will return false for https://foo.com/ or https://unisolated.foo.com/.
Alex Moshchuk8e5c1952019-01-15 03:39:50535 //
536 // |isolation_context| is used to determine which origins are isolated in
537 // this context. For example, isolated origins that are dynamically added
W. James MacLean46cf26212020-10-01 16:43:37538 // will only affect future BrowsingInstances. |origin_requests_isolation| may
539 // be true during navigation requests, and allows us to correctly determine
540 // isolation status for an origin that may not have had its isolation status
541 // recorded in the BrowsingInstance yet.
Alex Moshchuk8e5c1952019-01-15 03:39:50542 bool IsIsolatedOrigin(const IsolationContext& isolation_context,
W. James MacLean46cf26212020-10-01 16:43:37543 const url::Origin& origin,
544 bool origin_requests_isolation);
alexmos3b9ad102017-05-26 23:41:08545
alexmos4bc26322017-07-01 00:57:14546 // Removes a previously added isolated origin, currently only used in tests.
547 //
548 // TODO(alexmos): Exposing this more generally will require extra care, such
549 // as ensuring that there are no active SiteInstances in that origin.
550 void RemoveIsolatedOriginForTesting(const url::Origin& origin);
551
arthursonzogni98e5a232017-07-13 15:18:16552 // Returns false for redirects that must be blocked no matter which renderer
553 // process initiated the request (if any).
554 // Note: Checking CanRedirectToURL is not enough. CanRequestURL(child_id, url)
555 // represents a stricter subset. It must also be used for
556 // renderer-initiated navigations.
557 bool CanRedirectToURL(const GURL& url);
558
Aaron Colwell01466ed2019-10-24 01:17:52559 // Sets "killed_process_origin_lock" crash key with lock info for the
560 // process associated with |child_id|.
561 void LogKilledProcessOriginLock(int child_id);
562
Aaron Colwell4fcbe4152020-01-16 07:10:59563 // Creates a Handle object for a specific child process ID.
564 //
565 // This handle can be used to extend the lifetime of policy state beyond
566 // the Remove() call for |child_id|. This should be used by objects that can
567 // outlive the RenderProcessHostImpl object associated with |child_id| and
568 // need to be able to make policy decisions after RPHI destruction. (e.g.
569 // Mojo services created by RPHI)
570 //
571 // Returns a valid Handle for any |child_id| that is present in
572 // |security_state_|. Otherwise it returns a Handle that returns false for
573 // all policy checks.
574 Handle CreateHandle(int child_id);
575
W. James MacLeanc07dc41b2022-07-25 18:52:16576 // Returns true if we have seen an explicit Origin-Agent-Cluster header
577 // (either opt-in or opt-out) for this |origin| in the given |browser_context|
578 // before in any BrowsingInstance.
579 bool HasOriginEverRequestedOriginAgentClusterValue(
580 BrowserContext* browser_context,
581 const url::Origin& origin);
W. James MacLean1c40862c2020-04-27 21:05:57582
W. James MacLeanc07dc41b2022-07-25 18:52:16583 // Adds |origin| to the opt-in-out list as having the default isolation state
584 // for the BrowsingInstance specified by |isolation_context|, if we need to
585 // track it and it's not already in the list.
586 // |is_global_walk_or_frame_removal| should be set to true during the global
587 // walk that is triggered when |origin| first requests opt-in isolation, so
588 // that the function can skip safety checks that will be unnecessary during
589 // the global walk. It is also set to true if this function is called when
590 // removing a FrameNavigationEntry, since that entry won't be available to any
591 // subsequent global walks.
592 void AddDefaultIsolatedOriginIfNeeded(
593 const IsolationContext& isolation_context,
594 const url::Origin& origin,
595 bool is_global_walk_or_frame_removal);
W. James MacLean1c40862c2020-04-27 21:05:57596
Alex Moshchuk989aa22c2024-11-06 02:09:07597 // Add `origin` to the list of committed origins for the process identified by
598 // `child_id`. An attempt to add the same origin more than once is safely
599 // ignored. Note that there is currently no way to revoke an origin once it
600 // has been committed, even if all associated documents and workers go away.
601 // This might need to be revisited in the future if the list of committed
602 // origins grows too large.
603 void AddCommittedOrigin(int child_id, const url::Origin& origin);
604
W. James MacLean89307252020-11-11 00:16:44605 // Allows tests to modify the delay in cleaning up BrowsingInstanceIds. If the
606 // delay is set to zero, cleanup happens immediately.
607 void SetBrowsingInstanceCleanupDelayForTesting(int64_t delay_in_seconds) {
Peter Kastinge5a38ed2021-10-02 03:06:35608 browsing_instance_cleanup_delay_ = base::Seconds(delay_in_seconds);
W. James MacLean89307252020-11-11 00:16:44609 }
610
W. James MacLean24d534b2021-11-22 18:51:35611 // Allows tests to query the number of BrowsingInstanceIds associated with a
612 // child process.
613 size_t BrowsingInstanceIdCountForTesting(int child_id);
614
Alex Moshchuk71ca2902023-04-07 18:08:37615 void ClearRegisteredSchemeForTesting(const std::string& scheme);
616
Alex Moshchuk989aa22c2024-11-06 02:09:07617 // Checks if the provided `url` matches any committed origin in the process
618 // `child_id`. Currently only exposed for testing, since normally this check
619 // happens within CanAccessMaybeOpaqueOrigin().
620 bool MatchesCommittedOriginForTesting(int child_id,
621 const GURL& url,
622 bool url_is_for_precursor_origin);
623
W. James MacLean2a84fbf2023-05-12 18:13:43624 // Exposes LookupOriginIsolationState() for tests.
625 OriginAgentClusterIsolationState* LookupOriginIsolationStateForTesting(
626 const BrowsingInstanceId& browsing_instance_id,
627 const url::Origin& origin);
628
[email protected]df8e899b2011-02-22 22:58:22629 private:
630 friend class ChildProcessSecurityPolicyInProcessBrowserTest;
[email protected]bfcf1e92013-07-11 04:37:25631 friend class ChildProcessSecurityPolicyTest;
Aaron Colwell4fcbe4152020-01-16 07:10:59632 friend class ChildProcessSecurityPolicyImpl::Handle;
[email protected]df8e899b2011-02-22 22:58:22633 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyInProcessBrowserTest,
634 NoLeak);
[email protected]bee16c0b2013-09-16 20:30:48635 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, FilePermissions);
Alex Moshchukef8c2562021-03-12 06:37:45636 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
637 AddFutureIsolatedOrigins);
Alex Moshchuk8e5c1952019-01-15 03:39:50638 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
639 DynamicIsolatedOrigins);
Alex Moshchuk99b795422019-03-07 00:27:32640 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
641 IsolatedOriginsForSpecificBrowserContexts);
642 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
Alex Moshchuk331fa5f2021-03-10 06:16:59643 IsolatedOriginsForSpecificBrowsingInstances);
644 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
645 IsolatedOriginsForCurrentAndFutureBrowsingInstances);
646 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
Alex Moshchuk99b795422019-03-07 00:27:32647 IsolatedOriginsRemovedWhenBrowserContextDestroyed);
Andrew Stone6ed99b22019-06-07 06:14:39648 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
649 IsolateAllSuborigins);
W. James MacLean5eaf0bd2024-06-26 21:15:32650 FRIEND_TEST_ALL_PREFIXES(
651 ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
652 WildcardAndNonWildcardOrigins);
653 FRIEND_TEST_ALL_PREFIXES(
654 ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
655 WildcardAndNonWildcardEmbedded);
Andrew Stone0a177fe22019-06-26 08:12:04656 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
657 ParseIsolatedOrigins);
658 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, WildcardDefaultPort);
Alex Moshchuk989aa22c2024-11-06 02:09:07659 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
660 MatchesCommittedOrigin);
[email protected]df8e899b2011-02-22 22:58:22661
662 class SecurityState;
663
664 typedef std::set<std::string> SchemeSet;
Aaron Colwell67f93006c2019-04-01 22:45:28665 typedef std::map<int, std::unique_ptr<SecurityState>> SecurityStateMap;
[email protected]cd501a72014-08-22 19:58:31666 typedef std::map<storage::FileSystemType, int> FileSystemPermissionPolicyMap;
[email protected]df8e899b2011-02-22 22:58:22667
Alex Moshchuk99b795422019-03-07 00:27:32668 // This class holds an isolated origin along with information such as which
669 // BrowsingInstances and profile it applies to. See |isolated_origins_|
670 // below for more details.
671 class CONTENT_EXPORT IsolatedOriginEntry {
672 public:
Alex Moshchuk8e5c1952019-01-15 03:39:50673 IsolatedOriginEntry(const url::Origin& origin,
Alex Moshchuk331fa5f2021-03-10 06:16:59674 bool applies_to_future_browsing_instances,
675 BrowsingInstanceId browsing_instance_id,
Alex Moshchuk99b795422019-03-07 00:27:32676 BrowserContext* browser_context,
Andrew Stone6ed99b22019-06-07 06:14:39677 ResourceContext* resource_context,
Alex Moshchukc4679422019-06-11 17:04:48678 bool isolate_all_subdomains,
679 IsolatedOriginSource source);
Alex Moshchuk8e5c1952019-01-15 03:39:50680 // Copyable and movable.
681 IsolatedOriginEntry(const IsolatedOriginEntry& other);
682 IsolatedOriginEntry& operator=(const IsolatedOriginEntry& other);
683 IsolatedOriginEntry(IsolatedOriginEntry&& other);
684 IsolatedOriginEntry& operator=(IsolatedOriginEntry&& other);
685 ~IsolatedOriginEntry();
686
687 // Allow this class to be used as a key in STL.
688 bool operator<(const IsolatedOriginEntry& other) const {
Alex Moshchuk331fa5f2021-03-10 06:16:59689 return std::tie(origin_, applies_to_future_browsing_instances_,
690 browsing_instance_id_, browser_context_,
Alex Moshchukc4679422019-06-11 17:04:48691 resource_context_, isolate_all_subdomains_, source_) <
Alex Moshchuk331fa5f2021-03-10 06:16:59692 std::tie(other.origin_,
693 other.applies_to_future_browsing_instances_,
694 other.browsing_instance_id_, other.browser_context_,
695 other.resource_context_, other.isolate_all_subdomains_,
696 source_);
Alex Moshchuk8e5c1952019-01-15 03:39:50697 }
698
699 bool operator==(const IsolatedOriginEntry& other) const {
Alex Moshchuk99b795422019-03-07 00:27:32700 return origin_ == other.origin_ &&
Alex Moshchuk331fa5f2021-03-10 06:16:59701 applies_to_future_browsing_instances_ ==
702 other.applies_to_future_browsing_instances_ &&
703 browsing_instance_id_ == other.browsing_instance_id_ &&
Alex Moshchuk99b795422019-03-07 00:27:32704 browser_context_ == other.browser_context_ &&
Andrew Stone6ed99b22019-06-07 06:14:39705 resource_context_ == other.resource_context_ &&
Alex Moshchukc4679422019-06-11 17:04:48706 isolate_all_subdomains_ == other.isolate_all_subdomains_ &&
707 source_ == other.source_;
Alex Moshchuk8e5c1952019-01-15 03:39:50708 }
709
Alex Moshchuk99b795422019-03-07 00:27:32710 // True if this isolated origin applies globally to all profiles.
711 bool AppliesToAllBrowserContexts() const;
712
713 // True if (1) this entry is associated with the same profile as
714 // |browser_or_resource_context|, or (2) this entry applies to all
715 // profiles. May be used on UI or IO threads.
716 bool MatchesProfile(
717 const BrowserOrResourceContext& browser_or_resource_context) const;
718
Alex Moshchuk331fa5f2021-03-10 06:16:59719 // True if this entry applies to the BrowsingInstance specified by
720 // `browsing_instance_id`. See `applies_to_future_browsing_instances_` and
721 // `browsing_instance_id_` for more details.
722 bool MatchesBrowsingInstance(BrowsingInstanceId browsing_instance_id) const;
723
Alex Moshchuk99b795422019-03-07 00:27:32724 const url::Origin& origin() const { return origin_; }
725
Alex Moshchuk331fa5f2021-03-10 06:16:59726 // See the declaration of `applies_to_future_browsing_instances_` for
727 // details.
728 bool applies_to_future_browsing_instances() const {
729 return applies_to_future_browsing_instances_;
730 }
731
732 // See the declaration of `browsing_instance_id_` for details.
733 BrowsingInstanceId browsing_instance_id() const {
734 return browsing_instance_id_;
Alex Moshchuk99b795422019-03-07 00:27:32735 }
736
737 const BrowserContext* browser_context() const { return browser_context_; }
738
Andrew Stone6ed99b22019-06-07 06:14:39739 bool isolate_all_subdomains() const { return isolate_all_subdomains_; }
740
Alex Moshchukc4679422019-06-11 17:04:48741 IsolatedOriginSource source() const { return source_; }
742
Alex Moshchuk99b795422019-03-07 00:27:32743 private:
744 url::Origin origin_;
Alex Moshchuk331fa5f2021-03-10 06:16:59745
746 // If this is false, the origin is isolated only in the BrowsingInstance
747 // specified by `browsing_instance_id_`. If this is true, the origin is
748 // isolated in all BrowsingInstances that have an ID equal to or
749 // greater than `browsing_instance_id_`.
750 bool applies_to_future_browsing_instances_;
751
752 // Specifies which BrowsingInstance(s) this IsolatedOriginEntry applies to.
753 // When `applies_to_future_browsing_instances_` is false, this refers to a
754 // specific BrowsingInstance. Otherwise, it specifies the minimum
755 // BrowsingInstance ID, and the origin is isolated in all
756 // BrowsingInstances with IDs greater than or equal to this value.
757 BrowsingInstanceId browsing_instance_id_;
Alex Moshchuk99b795422019-03-07 00:27:32758
759 // Optional information about the profile where the isolated origin
760 // applies. |browser_context_| may be used on the UI thread, and
761 // |resource_context_| may be used on the IO thread. If these are null,
762 // then the isolated origin applies globally to all profiles.
Arthur Sonzogniff837582023-12-22 10:05:45763 raw_ptr<BrowserContext> browser_context_;
764 raw_ptr<ResourceContext> resource_context_;
Alex Moshchuk99b795422019-03-07 00:27:32765
Andrew Stone6ed99b22019-06-07 06:14:39766 // True if origins at this or lower level should be treated as distinct
767 // isolated origins, effectively isolating all domains below a given domain,
768 // e.g. if the origin is https://foo.com and isolate_all_subdomains_ is
769 // true, then https://bar.foo.com, https://qux.bar.foo.com and all
770 // subdomains of the form https://<<any pattern here>>.foo.com are
771 // considered isolated origins.
772 bool isolate_all_subdomains_;
773
Alex Moshchukc4679422019-06-11 17:04:48774 // This tracks the source of each isolated origin entry, e.g., to
Alex Moshchuk8e5c1952019-01-15 03:39:50775 // distinguish those that should be displayed to the user from those that
776 // should not. See https://crbug.com/920911.
Alex Moshchukc4679422019-06-11 17:04:48777 IsolatedOriginSource source_;
Alex Moshchuk8e5c1952019-01-15 03:39:50778 };
779
W. James MacLean7f76c2202021-11-15 16:27:49780 // A struct to hold the OAC opted-in origins and their isolation state. It
781 // associates a specific |origin| with its OriginAgentClusterIsolationState,
782 // and is tracked in |origin_isolation_by_browsing_instance_|.
783 struct OriginAgentClusterOptInEntry {
784 OriginAgentClusterOptInEntry(
785 const OriginAgentClusterIsolationState& oac_isolation_state_in,
786 const url::Origin& origin_in);
787 OriginAgentClusterOptInEntry(const OriginAgentClusterOptInEntry&);
788 ~OriginAgentClusterOptInEntry();
789
790 OriginAgentClusterIsolationState oac_isolation_state;
791 url::Origin origin;
792 };
793
[email protected]b9535422012-02-09 01:47:59794 // Obtain an instance of ChildProcessSecurityPolicyImpl via GetInstance().
795 ChildProcessSecurityPolicyImpl();
olli.raula36aa8be2015-09-10 11:14:22796 friend struct base::DefaultSingletonTraits<ChildProcessSecurityPolicyImpl>;
[email protected]df8e899b2011-02-22 22:58:22797
[email protected]cee64fd32011-05-02 18:59:07798 // Determines if certain permissions were granted for a file to given child
[email protected]322a6eb2013-11-12 06:13:09799 // process. |permissions| is an internally defined bit-set.
[email protected]cee64fd32011-05-02 18:59:07800 bool ChildProcessHasPermissionsForFile(int child_id,
[email protected]a3ef4832013-02-02 05:12:33801 const base::FilePath& file,
Lukasz Anforowicz40066f52018-09-21 21:14:41802 int permissions)
803 EXCLUSIVE_LOCKS_REQUIRED(lock_);
[email protected]cee64fd32011-05-02 18:59:07804
[email protected]322a6eb2013-11-12 06:13:09805 // Grant a particular permission set for a file. |permissions| is an
806 // internally defined bit-set.
[email protected]bfcf1e92013-07-11 04:37:25807 void GrantPermissionsForFile(int child_id,
808 const base::FilePath& file,
809 int permissions);
810
811 // Grants access permission to the given isolated file system
812 // identified by |filesystem_id|. See comments for
813 // ChildProcessSecurityPolicy::GrantReadFileSystem() for more details.
Andrew Stone6ed99b22019-06-07 06:14:39814 void GrantPermissionsForFileSystem(int child_id,
815 const std::string& filesystem_id,
816 int permission);
[email protected]bfcf1e92013-07-11 04:37:25817
[email protected]bee16c0b2013-09-16 20:30:48818 // Determines if certain permissions were granted for a file. |permissions|
Aaron Colwellf1408702018-12-03 18:23:25819 // is an internally defined bit-set.
[email protected]bee16c0b2013-09-16 20:30:48820 bool HasPermissionsForFile(int child_id,
821 const base::FilePath& file,
822 int permissions);
823
[email protected]bee16c0b2013-09-16 20:30:48824 // Determines if certain permissions were granted for a file in FileSystem
[email protected]322a6eb2013-11-12 06:13:09825 // API. |permissions| is an internally defined bit-set.
nickb3c1e272016-10-07 22:56:37826 bool HasPermissionsForFileSystemFile(
827 int child_id,
828 const storage::FileSystemURL& filesystem_url,
829 int permissions);
[email protected]bee16c0b2013-09-16 20:30:48830
[email protected]322a6eb2013-11-12 06:13:09831 // Determines if certain permissions were granted for a file system.
832 // |permissions| is an internally defined bit-set.
Andrew Stone6ed99b22019-06-07 06:14:39833 bool HasPermissionsForFileSystem(int child_id,
834 const std::string& filesystem_id,
835 int permission);
[email protected]322a6eb2013-11-12 06:13:09836
Aaron Colwell220d5022019-01-16 04:56:55837 // Gets the SecurityState object associated with |child_id|.
838 // Note: Returned object is only valid for the duration the caller holds
839 // |lock_|.
840 SecurityState* GetSecurityState(int child_id) EXCLUSIVE_LOCKS_REQUIRED(lock_);
841
Andrew Stone0a177fe22019-06-26 08:12:04842 // Convert a list of comma separated isolated origins in |pattern_list|,
843 // specified either as wildcard origins, non-wildcard origins or a mix of the
844 // two into IsolatedOriginPatterns, suitable for addition via
Alex Moshchukef8c2562021-03-12 06:37:45845 // AddFutureIsolatedOrigins().
Andrew Stone0a177fe22019-06-26 08:12:04846 static std::vector<IsolatedOriginPattern> ParseIsolatedOrigins(
Md Hasibul Hasana963a9342024-04-03 10:15:14847 std::string_view pattern_list);
Andrew Stone0a177fe22019-06-26 08:12:04848
Alex Moshchukef8c2562021-03-12 06:37:45849 void AddFutureIsolatedOrigins(
850 const std::vector<IsolatedOriginPattern>& patterns,
851 IsolatedOriginSource source,
852 BrowserContext* browser_context = nullptr);
Andrew Stone0a177fe22019-06-26 08:12:04853
Alex Moshchuk331fa5f2021-03-10 06:16:59854 // Internal helper used for adding a particular isolated origin. See
855 // IsolatedOriginEntry for descriptions of various parameters.
856 void AddIsolatedOriginInternal(BrowserContext* browser_context,
857 const url::Origin& origin,
858 bool applies_to_future_browsing_instances,
859 BrowsingInstanceId browsing_instance_id,
860 bool isolate_all_subdomains,
861 IsolatedOriginSource source)
862 EXCLUSIVE_LOCKS_REQUIRED(isolated_origins_lock_);
863
Aaron Colwelldd9dce32020-06-04 21:03:52864 bool AddProcessReference(int child_id, bool duplicating_handle);
865 bool AddProcessReferenceLocked(int child_id, bool duplicating_handle)
866 EXCLUSIVE_LOCKS_REQUIRED(lock_);
Aaron Colwell4fcbe4152020-01-16 07:10:59867 void RemoveProcessReference(int child_id);
868 void RemoveProcessReferenceLocked(int child_id)
869 EXCLUSIVE_LOCKS_REQUIRED(lock_);
870
Peter KHa027bf62025-07-29 15:22:52871 // Internal helper for RemoveAllStateForBrowsingInstance().
872 void RemoveAllStateForBrowsingInstanceInternal(
W. James MacLean89307252020-11-11 00:16:44873 const BrowsingInstanceId browsing_instance_id);
874
Aaron Colwell01466ed2019-10-24 01:17:52875 // Creates the value to place in the "killed_process_origin_lock" crash key
876 // based on the contents of |security_state|.
877 static std::string GetKilledProcessOriginLock(
878 const SecurityState* security_state);
879
Alex Moshchukdf44817e2024-10-02 22:54:54880 // Helper for CanAccessMaybeOpaqueOrigin, to perform two security checks:
881 // - Jail check: a process locked to a particular site shouldn't access data
882 // belonging to other sites.
883 // - Citadel check: a process not locked to any site shouldn't access data
884 // belonging to sites that require a dedicated process.
885 //
886 // These checks are performed by comparing the actual ProcessLock of the
887 // process represented by `child_id` and `security_state` to an expected
888 // ProcessLock computed from `url`, which takes into account factors such as
889 // whether `url` should be site-isolated or origin-isolated (or not isolated,
890 // e.g. on Android). Determining site-vs-origin isolation is non-trivial: the
891 // answer may differ depending on BrowsingInstance (e.g., OriginAgentCluster
892 // might require origin isolation only for certain BrowsingInstances), so all
893 // BrowsingInstances hosting in the process must be consulted.
894 //
895 // This function returns true only if both Jail and Citadel checks pass. On
896 // failure, it also populates `out_failure_reason` with debugging information
897 // about the cause of the failure, as well as `out_expected_process_lock` with
898 // what the process lock was expected to be (e.g., to be used in crash keys).
899 //
900 // This function must be called while already holding `lock_`.
901 bool PerformJailAndCitadelChecks(int child_id,
902 SecurityState* security_state,
903 const GURL& url,
904 bool url_is_precursor_of_opaque_origin,
905 AccessType access_type,
906 ProcessLock& out_expected_process_lock,
907 std::string& out_failure_reason)
908 EXCLUSIVE_LOCKS_REQUIRED(lock_);
909
Alex Moshchuk99c22682024-03-28 22:43:46910 // Helper for public CanAccessOrigin overloads.
911 bool CanAccessMaybeOpaqueOrigin(int child_id,
912 const GURL& url,
913 bool url_is_precursor_of_opaque_origin,
914 AccessType access_type);
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:47915
Alex Moshchuk31e0f3452024-03-29 20:56:10916 // Helper used by CanAccessOrigin to impose additional restrictions on a
917 // sandboxed process locked to `process_lock`.
918 bool IsAccessAllowedForSandboxedProcess(const ProcessLock& process_lock,
919 const GURL& url,
920 bool url_is_for_opaque_origin,
921 AccessType access_type);
922
Alex Moshchuk304a54b2024-06-26 15:58:54923 // Helper used by CanAccessOrigin to impose additional restrictions on a
924 // process that only hosts PDF documents.
925 bool IsAccessAllowedForPdfProcess(AccessType access_type);
926
W. James MacLeand42fa812021-11-18 22:59:26927 // Utility function to simplify lookups for OriginAgentClusterOptInEntry
928 // values by origin.
929 OriginAgentClusterIsolationState* LookupOriginIsolationState(
930 const BrowsingInstanceId& browsing_instance_id,
931 const url::Origin& origin)
932 EXCLUSIVE_LOCKS_REQUIRED(origins_isolation_opt_in_lock_);
933
[email protected]826ad7112011-09-02 21:39:03934 // You must acquire this lock before reading or writing any members of this
Elly14008c32024-08-15 16:15:43935 // class, except for isolated_origins_, schemes_okay_to_*, and
936 // pseudo_schemes_, which use their own locks. You must not block while
937 // holding this lock.
[email protected]df8e899b2011-02-22 22:58:22938 base::Lock lock_;
939
Elly14008c32024-08-15 16:15:43940 // These schemes are allow-listed for all child processes in various contexts.
941 // These sets are protected by |schemes_lock_| rather than |lock_|.
942 base::Lock schemes_lock_;
943 SchemeSet schemes_okay_to_commit_in_any_process_ GUARDED_BY(schemes_lock_);
944 SchemeSet schemes_okay_to_request_in_any_process_ GUARDED_BY(schemes_lock_);
945 SchemeSet schemes_okay_to_appear_as_origin_headers_ GUARDED_BY(schemes_lock_);
[email protected]df8e899b2011-02-22 22:58:22946
947 // These schemes do not actually represent retrievable URLs. For example,
948 // the the URLs in the "about" scheme are aliases to other URLs. This set is
Elly14008c32024-08-15 16:15:43949 // protected by |schemes_lock_|.
950 SchemeSet pseudo_schemes_ GUARDED_BY(schemes_lock_);
[email protected]df8e899b2011-02-22 22:58:22951
[email protected]df8e899b2011-02-22 22:58:22952 // This map holds a SecurityState for each child process. The key for the
953 // map is the ID of the ChildProcessHost. The SecurityState objects are
954 // owned by this object and are protected by |lock_|. References to them must
955 // not escape this class.
Lukasz Anforowicz40066f52018-09-21 21:14:41956 SecurityStateMap security_state_ GUARDED_BY(lock_);
[email protected]df8e899b2011-02-22 22:58:22957
Aaron Colwelldc211742019-04-05 21:04:01958 // This map holds the SecurityState for a child process after Remove()
959 // is called on the UI thread. An entry stays in this map until a task has
960 // run on the IO thread. This is necessary to provide consistent security
961 // decisions and avoid races between the UI & IO threads during child process
962 // shutdown. This separate map is used to preserve SecurityState info AND
963 // preventing mutation of that state after Remove() is called.
964 SecurityStateMap pending_remove_state_ GUARDED_BY(lock_);
965
Lukasz Anforowicz40066f52018-09-21 21:14:41966 FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_);
[email protected]ce5cbed82013-07-01 11:52:31967
Aaron Colwell4fcbe4152020-01-16 07:10:59968 // Contains a mapping between child process ID and the number of outstanding
969 // references that want to keep the SecurityState for each process alive.
970 // This object and Handles created by this object increment/decrement
971 // the counts in this map and only destroy a SecurityState object for a
972 // process when its count goes to zero.
973 std::map<int, int> process_reference_counts_ GUARDED_BY(lock_);
974
Alex Moshchukf01172e2019-01-16 00:54:17975 // You must acquire this lock before reading or writing isolated_origins_.
976 // You must not block while holding this lock.
977 //
978 // It is allowed to hold both |lock_| and |isolated_origins_lock_|, but in
979 // this case, |lock_| should always be acquired first to prevent deadlock.
980 base::Lock isolated_origins_lock_ ACQUIRED_AFTER(lock_);
981
alexmos3b9ad102017-05-26 23:41:08982 // Tracks origins for which the entire origin should be treated as a site
983 // when making process model decisions, rather than the origin's scheme and
984 // eTLD+1. Each of these origins requires a dedicated process. This set is
Alex Moshchukf01172e2019-01-16 00:54:17985 // protected by |isolated_origins_lock_|.
Alex Moshchuk4e19b362018-09-10 21:14:36986 //
987 // The origins are stored in a map indexed by a site URL computed for each
988 // origin. For example, adding https://foo.com, https://bar.foo.com, and
989 // https://www.bar.com would result in the following structure:
990 // https://foo.com -> { https://foo.com, https://bar.foo.com }
991 // https://bar.com -> { https://www.bar.com }
992 // This organization speeds up lookups of isolated origins. The site can be
993 // found in O(log n) time, and the corresponding list of origins to search
994 // using the expensive DoesOriginMatchIsolatedOrigin() comparison is
995 // typically small.
Alex Moshchuk8e5c1952019-01-15 03:39:50996 //
Alex Moshchuk99b795422019-03-07 00:27:32997 // Each origin entry stores information about:
Alex Moshchuk331fa5f2021-03-10 06:16:59998 // 1. Which BrowsingInstances it applies to. This is a combination of a
999 // BrowsingInstance ID |browsing_instance_id_| and a bool flag
1000 // |applies_to_future_browsing_instances_| stored in in each origin's
1001 // IsolatedOriginEntry. When |applies_to_future_browsing_instances_| is
1002 // true, the origin will be isolated in all BrowsingInstances with
1003 // IDs equal to or greater than |browsing_instance_id_|. When
1004 // |applies_to_future_browsing_instances_| is false, the origin will be
1005 // isolated only in a single BrowsingInstance with ID
1006 // |browsing_instance_id_|.
Alex Moshchuk99b795422019-03-07 00:27:321007 // 2. Optionally, which BrowserContext (profile) it applies to. When the
1008 // |browser_context| field in the IsolatedOriginEntry is non-null, a
1009 // particular isolated origin entry only applies to that BrowserContext.
1010 // A ResourceContext, BrowserContext's representation on the IO thread,
1011 // is also stored in the entry to facilitate checks on the IO thread.
1012 // Note that the same origin may be isolated in different profiles,
1013 // possibly with different BrowsingInstance ID cut-offs. For example:
1014 // https://foo.com -> { [https://test.foo.com profile1 4],
1015 // [https://test.foo.com profile2 7] }
Alex Moshchuk331fa5f2021-03-10 06:16:591016 // represents https://test.foo.com being isolated in profile1
1017 // with BrowsingInstance ID 4, and also in profile2 with
Alex Moshchuk99b795422019-03-07 00:27:321018 // BrowsingInstance ID 7.
Andrew Stone6ed99b22019-06-07 06:14:391019 base::flat_map<GURL, std::vector<IsolatedOriginEntry>> isolated_origins_
Alex Moshchukf01172e2019-01-16 00:54:171020 GUARDED_BY(isolated_origins_lock_);
alexmos3b9ad102017-05-26 23:41:081021
W. James MacLean1c40862c2020-04-27 21:05:571022 // TODO(wjmaclean): Move these lists into a per-BrowserContext container, to
1023 // prevent any record of sites visible in one profile from being visible to
1024 // another profile.
W. James MacLean64ddbcc2020-01-24 22:34:221025 base::Lock origins_isolation_opt_in_lock_;
W. James MacLeanc07dc41b2022-07-25 18:52:161026 // The set of all origins that have ever requested opt-in isolation or
1027 // requested to opt-out, organized by BrowserContext. This is tracked so we
1028 // know which origins need to be tracked when using default isolation in any
1029 // given BrowsingInstance. Origins requesting isolation opt-in or out, if
1030 // successful, are marked as isolated or not via
W. James MacLeand42fa812021-11-18 22:59:261031 // DetermineOriginAgentClusterIsolation's checking
1032 // |requested_isolation_state|. Each BrowserContext's state is tracked
1033 // separately so that timing attacks do not reveal whether an origin has been
1034 // visited in another (e.g., incognito) BrowserContext. In general, the state
1035 // of other BrowsingInstances is not observable outside such timing side
1036 // channels.
W. James MacLeand7eb1562020-11-17 17:56:101037 base::flat_map<BrowserContext*, base::flat_set<url::Origin>>
W. James MacLeanc07dc41b2022-07-25 18:52:161038 origin_isolation_opt_ins_and_outs_
1039 GUARDED_BY(origins_isolation_opt_in_lock_);
W. James MacLeand42fa812021-11-18 22:59:261040
W. James MacLean1c40862c2020-04-27 21:05:571041 // A map to track origins that have been isolated within a given
W. James MacLeand42fa812021-11-18 22:59:261042 // BrowsingInstance, or that have been loaded in a BrowsingInstance
1043 // without isolation, but that have requested isolation in at least one other
1044 // BrowsingInstance. Origins loaded without isolation are tracked to make sure
1045 // we don't try to isolate the origin in the associated BrowsingInstance at a
1046 // later time, in order to keep the isolation consistent over the lifetime of
1047 // the BrowsingInstance.
W. James MacLean7f76c2202021-11-15 16:27:491048 base::flat_map<BrowsingInstanceId, std::vector<OriginAgentClusterOptInEntry>>
W. James MacLean64ddbcc2020-01-24 22:34:221049 origin_isolation_by_browsing_instance_
1050 GUARDED_BY(origins_isolation_opt_in_lock_);
W. James MacLean1c40862c2020-04-27 21:05:571051
Peter KHa027bf62025-07-29 15:22:521052 base::Lock are_v8_optimizations_disabled_lock_;
1053
1054 // A map of BrowsingInstances and process-lock-origins to v8-optimization
1055 // verdicts. The purpose of the map is to ensure that changes in the return
1056 // value of ContentBrowserClient::AreV8OptimizationsDisabledForSite() only
1057 // affect process reuse decisions for future BrowsingInstances.
1058 base::flat_map<BrowsingInstanceId, base::flat_map<url::Origin, bool>>
1059 are_v8_optimizations_disabled_map_
1060 GUARDED_BY(are_v8_optimizations_disabled_lock_);
1061
W. James MacLean89307252020-11-11 00:16:441062 // When we are notified a BrowsingInstance has destructed, delay cleanup by
1063 // this amount to allow outstanding IO thread requests to complete. May be set
W. James MacLean07f99092021-02-24 21:55:341064 // to different values in tests. Note: the value is chosen to be slightly
1065 // longer than the KeepAliveHandleFactory delay of 30 seconds, with the aim of
1066 // covering the maximum time needed by any IncrementKeepAliveRefCount callers.
1067 // TODO(wjmaclean): we know the IncrementKeepAliveRefCount API needs
1068 // improvement, and with it the BrowsingInstance cleanup here can also be
1069 // improved.
Takashi Toyoshimab89ec842021-07-12 10:39:491070 base::TimeDelta browsing_instance_cleanup_delay_;
[email protected]df8e899b2011-02-22 22:58:221071};
1072
[email protected]46488322012-10-30 03:22:201073} // namespace content
1074
[email protected]b9535422012-02-09 01:47:591075#endif // CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_