Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 5 | #ifndef CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_ |
| 6 | #define CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_ |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 7 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 8 | #include <map> |
avi | 6f9a1d41 | 2016-08-16 16:07:31 | [diff] [blame] | 9 | #include <memory> |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 10 | #include <set> |
| 11 | #include <string> |
Md Hasibul Hasan | a963a934 | 2024-04-03 10:15:14 | [diff] [blame] | 12 | #include <string_view> |
lukasza | 43c38f12 | 2016-06-17 20:07:38 | [diff] [blame] | 13 | #include <vector> |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 14 | |
Alex Moshchuk | 4e19b36 | 2018-09-10 21:14:36 | [diff] [blame] | 15 | #include "base/containers/flat_map.h" |
Lukasz Anforowicz | 0672f8a | 2017-11-30 01:07:06 | [diff] [blame] | 16 | #include "base/containers/flat_set.h" |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 17 | #include "base/gtest_prod_util.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 18 | #include "base/memory/raw_ptr.h" |
lukasza | 4ec2e757 | 2017-05-26 23:18:10 | [diff] [blame] | 19 | #include "base/memory/ref_counted.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 20 | #include "base/memory/singleton.h" |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 21 | #include "base/synchronization/lock.h" |
Lukasz Anforowicz | 5e71bd4 | 2018-09-17 19:28:57 | [diff] [blame] | 22 | #include "base/thread_annotations.h" |
Takashi Toyoshima | b89ec84 | 2021-07-12 10:39:49 | [diff] [blame] | 23 | #include "base/time/time.h" |
Aaron Colwell | 1325f84 | 2019-10-07 20:37:58 | [diff] [blame] | 24 | #include "content/browser/can_commit_status.h" |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 25 | #include "content/browser/isolated_origin_util.h" |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 26 | #include "content/browser/isolation_context.h" |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 27 | #include "content/browser/origin_agent_cluster_isolation_state.h" |
Lei Zhang | 7ab31375 | 2021-11-17 01:26:00 | [diff] [blame] | 28 | #include "content/common/content_export.h" |
[email protected] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 29 | #include "content/public/browser/child_process_security_policy.h" |
Avi Drissman | 78865bbb | 2024-08-22 20:57:19 | [diff] [blame] | 30 | #include "content/public/common/bindings_policy.h" |
DongJun Kim | d6930ea | 2019-10-24 08:49:25 | [diff] [blame] | 31 | #include "storage/common/file_system/file_system_types.h" |
alexmos | 3b9ad10 | 2017-05-26 23:41:08 | [diff] [blame] | 32 | #include "url/origin.h" |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 33 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 34 | class GURL; |
| 35 | |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame] | 36 | namespace base { |
| 37 | class FilePath; |
Sharon Yang | a005ca1 | 2021-11-16 20:09:42 | [diff] [blame] | 38 | } // namespace base |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame] | 39 | |
John Abd-El-Malek | b49606cf | 2018-01-12 17:23:34 | [diff] [blame] | 40 | namespace network { |
| 41 | class ResourceRequestBody; |
Sharon Yang | a005ca1 | 2021-11-16 20:09:42 | [diff] [blame] | 42 | } // namespace network |
John Abd-El-Malek | b49606cf | 2018-01-12 17:23:34 | [diff] [blame] | 43 | |
[email protected] | cd501a7 | 2014-08-22 19:58:31 | [diff] [blame] | 44 | namespace storage { |
lukasza | 4ec2e757 | 2017-05-26 23:18:10 | [diff] [blame] | 45 | class FileSystemContext; |
[email protected] | ce5cbed8 | 2013-07-01 11:52:31 | [diff] [blame] | 46 | class FileSystemURL; |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 47 | } // namespace storage |
[email protected] | ce5cbed8 | 2013-07-01 11:52:31 | [diff] [blame] | 48 | |
[email protected] | 4648832 | 2012-10-30 03:22:20 | [diff] [blame] | 49 | namespace content { |
| 50 | |
Aaron Colwell | ea6921f | 2019-01-29 16:50:39 | [diff] [blame] | 51 | class BrowserContext; |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 52 | class IsolationContext; |
Sharon Yang | a005ca1 | 2021-11-16 20:09:42 | [diff] [blame] | 53 | class ProcessLock; |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 54 | class ResourceContext; |
David Sanders | c6fd826 | 2022-02-22 19:20:33 | [diff] [blame] | 55 | struct UrlInfo; |
Alex Moshchuk | 8865a06 | 2021-03-12 21:33:44 | [diff] [blame] | 56 | |
[email protected] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 57 | class CONTENT_EXPORT ChildProcessSecurityPolicyImpl |
Nico Weber | 43ddd7a3 | 2017-08-15 19:19:27 | [diff] [blame] | 58 | : public ChildProcessSecurityPolicy { |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 59 | public: |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 60 | // 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 Moshchuk | c170154 | 2020-02-06 19:29:32 | [diff] [blame] | 83 | // Create a new instance of Handle, holding another reference to the same |
| 84 | // process ID as the current one. |
| 85 | Handle Duplicate(); |
| 86 | |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 87 | // 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 Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 94 | // 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 Moshchuk | 174e172 | 2023-11-30 02:17:20 | [diff] [blame] | 103 | // the given `origin`. For more details, see |
| 104 | // ChildProcessSecurityPolicy::CanAccessDataForOrigin(). |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 105 | bool CanAccessDataForOrigin(const url::Origin& origin); |
| 106 | |
Ari Chivukula | ccb16aeb | 2021-10-01 01:47:12 | [diff] [blame] | 107 | // Returns the original `child_id` used to create the handle. |
| 108 | int child_id() { return child_id_; } |
| 109 | |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 110 | private: |
| 111 | friend class ChildProcessSecurityPolicyImpl; |
Aaron Colwell | dd9dce3 | 2020-06-04 21:03:52 | [diff] [blame] | 112 | // |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 Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 120 | |
| 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öm | 9b03653 | 2021-10-28 23:37:28 | [diff] [blame] | 126 | ChildProcessSecurityPolicyImpl(const ChildProcessSecurityPolicyImpl&) = |
| 127 | delete; |
| 128 | ChildProcessSecurityPolicyImpl& operator=( |
| 129 | const ChildProcessSecurityPolicyImpl&) = delete; |
| 130 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 131 | // Object can only be created through GetInstance() so the constructor is |
| 132 | // private. |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 133 | ~ChildProcessSecurityPolicyImpl() override; |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 134 | |
[email protected] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 135 | static ChildProcessSecurityPolicyImpl* GetInstance(); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 136 | |
[email protected] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 137 | // ChildProcessSecurityPolicy implementation. |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 138 | void RegisterWebSafeScheme(const std::string& scheme) override; |
nick | 2a8ba8c | 2016-10-03 18:51:39 | [diff] [blame] | 139 | void RegisterWebSafeIsolatedScheme( |
| 140 | const std::string& scheme, |
| 141 | bool always_allow_in_origin_headers) override; |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 142 | 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] | aa7cfbf | 2012-06-01 08:48:09 | [diff] [blame] | 155 | int child_id, |
mohan.reddy | 7fc3ac7 | 2014-10-09 05:24:13 | [diff] [blame] | 156 | const std::string& filesystem_id) override; |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 157 | void GrantCopyIntoFileSystem(int child_id, |
| 158 | const std::string& filesystem_id) override; |
| 159 | void GrantDeleteFromFileSystem(int child_id, |
mohan.reddy | 7fc3ac7 | 2014-10-09 05:24:13 | [diff] [blame] | 160 | const std::string& filesystem_id) override; |
Daniel Cheng | 4ebba55 | 2018-07-06 21:43:16 | [diff] [blame] | 161 | 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; |
nick | 2a8ba8c | 2016-10-03 18:51:39 | [diff] [blame] | 164 | bool CanRequestURL(int child_id, const GURL& url) override; |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 165 | 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 Wilson | a24fe88 | 2023-06-01 01:02:50 | [diff] [blame] | 177 | void GrantSendMidiMessage(int child_id) override; |
mlamouri | 97de25e4 | 2014-11-25 10:50:23 | [diff] [blame] | 178 | void GrantSendMidiSysExMessage(int child_id) override; |
Lukasz Anforowicz | d0d8cdb | 2021-01-27 22:20:47 | [diff] [blame] | 179 | bool CanAccessDataForOrigin(int child_id, const url::Origin& origin) override; |
Alex Moshchuk | 99c2268 | 2024-03-28 22:43:46 | [diff] [blame] | 180 | bool HostsOrigin(int child_id, const url::Origin& origin) override; |
Alex Moshchuk | ef8c256 | 2021-03-12 06:37:45 | [diff] [blame] | 181 | void AddFutureIsolatedOrigins( |
Md Hasibul Hasan | a963a934 | 2024-04-03 10:15:14 | [diff] [blame] | 182 | std::string_view origins_list, |
Alex Moshchuk | ef8c256 | 2021-03-12 06:37:45 | [diff] [blame] | 183 | 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 Anforowicz | 65c6116 | 2019-03-27 20:33:58 | [diff] [blame] | 189 | bool IsGloballyIsolatedOriginForTesting(const url::Origin& origin) override; |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 190 | std::vector<url::Origin> GetIsolatedOrigins( |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 191 | std::optional<IsolatedOriginSource> source = std::nullopt, |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 192 | BrowserContext* browser_context = nullptr) override; |
rajendrant | 015529c | 2020-12-18 04:21:52 | [diff] [blame] | 193 | bool IsIsolatedSiteFromSource(const url::Origin& origin, |
| 194 | IsolatedOriginSource source) override; |
Alex Moshchuk | 51e1428b | 2020-04-22 18:00:54 | [diff] [blame] | 195 | void ClearIsolatedOriginsForTesting() override; |
Alex Moshchuk | 25754cd4 | 2018-12-05 22:43:08 | [diff] [blame] | 196 | |
Alex Moshchuk | 99c2268 | 2024-03-28 22:43:46 | [diff] [blame] | 197 | // 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 Hemery | 821fa5d | 2021-08-30 13:32:42 | [diff] [blame] | 230 | // 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 Colwell | 1325f84 | 2019-10-07 20:37:58 | [diff] [blame] | 233 | // |
Arthur Hemery | 821fa5d | 2021-08-30 13:32:42 | [diff] [blame] | 234 | // 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 Colwell | d759e54 | 2019-10-09 17:45:06 | [diff] [blame] | 238 | CanCommitStatus CanCommitOriginAndUrl( |
| 239 | int child_id, |
| 240 | const IsolationContext& isolation_context, |
Arthur Hemery | 821fa5d | 2021-08-30 13:32:42 | [diff] [blame] | 241 | const UrlInfo& url_info); |
Aaron Colwell | 1325f84 | 2019-10-07 20:37:58 | [diff] [blame] | 242 | |
Alex Moshchuk | b5198477 | 2024-03-29 00:57:31 | [diff] [blame] | 243 | // 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 250 | // 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 Moshchuk | 25754cd4 | 2018-12-05 22:43:08 | [diff] [blame] | 253 | // |
| 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 272 | // |
| 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 MacLean | 92e39c8 | 2021-02-25 23:27:34 | [diff] [blame] | 276 | bool GetMatchingProcessIsolatedOrigin( |
| 277 | const IsolationContext& isolation_context, |
| 278 | const url::Origin& origin, |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 279 | bool requests_origin_keyed_process, |
W. James MacLean | 92e39c8 | 2021-02-25 23:27:34 | [diff] [blame] | 280 | url::Origin* result); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 281 | |
Peter KH | a027bf6 | 2025-07-29 15:22:52 | [diff] [blame] | 282 | // Removes any state associated with `browsing_instance_id`. |
| 283 | void RemoveAllStateForBrowsingInstance( |
W. James MacLean | 8930725 | 2020-11-11 00:16:44 | [diff] [blame] | 284 | const BrowsingInstanceId& browsing_instance_id); |
W. James MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 285 | |
W. James MacLean | c07dc41b | 2022-07-25 18:52:16 | [diff] [blame] | 286 | // Registers |origin| isolation state in the BrowsingInstance associated |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 287 | // with |isolation_context|. |
| 288 | // |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 289 | // |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 Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 295 | // |
| 296 | // If |origin| has already been registered as isolated for the same |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 297 | // BrowsingInstance, then nothing will be changed by this call. |
| 298 | void AddOriginAgentClusterStateForBrowsingInstance( |
W. James MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 299 | const IsolationContext& isolation_context, |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 300 | const url::Origin& origin, |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 301 | const OriginAgentClusterIsolationState& oac_isolation_state); |
W. James MacLean | c07dc41b | 2022-07-25 18:52:16 | [diff] [blame] | 302 | |
| 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 Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 309 | IsolatedOriginSource source); |
W. James MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 310 | |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 311 | // 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 MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 317 | // 1) whether |origin| already is assigned to a SiteInstance in the |
W. James MacLean | d42fa81 | 2021-11-18 22:59:26 | [diff] [blame] | 318 | // |isolation_context| by being tracked in |
W. James MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 319 | // |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 MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 322 | // currently requesting isolation via |requested_isolation_state|. |
W. James MacLean | d42fa81 | 2021-11-18 22:59:26 | [diff] [blame] | 323 | OriginAgentClusterIsolationState DetermineOriginAgentClusterIsolation( |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 324 | const IsolationContext& isolation_context, |
| 325 | const url::Origin& origin, |
| 326 | const OriginAgentClusterIsolationState& requested_isolation_state); |
W. James MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 327 | |
W. James MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 328 | // This function adds |origin| to the master list of origins that have |
W. James MacLean | 46fc0b6 | 2020-11-18 16:18:45 | [diff] [blame] | 329 | // ever requested opt-in isolation in the given |browser_context|, either via |
W. James MacLean | d7eb156 | 2020-11-17 17:56:10 | [diff] [blame] | 330 | // 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 MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 335 | |
W. James MacLean | 92e39c8 | 2021-02-25 23:27:34 | [diff] [blame] | 336 | // 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 339 | // |isolation_context|; this function allows it to be passed in when it is |
| 340 | // already known to avoid recomputing it internally. |
W. James MacLean | 92e39c8 | 2021-02-25 23:27:34 | [diff] [blame] | 341 | bool GetMatchingProcessIsolatedOrigin( |
| 342 | const IsolationContext& isolation_context, |
| 343 | const url::Origin& origin, |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 344 | bool requests_origin_keyed_process, |
W. James MacLean | 92e39c8 | 2021-02-25 23:27:34 | [diff] [blame] | 345 | const GURL& site_url, |
| 346 | url::Origin* result); |
Alex Moshchuk | 4e19b36 | 2018-09-10 21:14:36 | [diff] [blame] | 347 | |
Peter KH | a027bf6 | 2025-07-29 15:22:52 | [diff] [blame] | 348 | // 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 | |
lukasza | 43c38f12 | 2016-06-17 20:07:38 | [diff] [blame] | 362 | // Returns if |child_id| can read all of the |files|. |
| 363 | bool CanReadAllFiles(int child_id, const std::vector<base::FilePath>& files); |
| 364 | |
lukasza | 5e8bef0e | 2017-05-30 23:41:45 | [diff] [blame] | 365 | // 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-Malek | b49606cf | 2018-01-12 17:23:34 | [diff] [blame] | 367 | bool CanReadRequestBody( |
| 368 | int child_id, |
| 369 | const storage::FileSystemContext* file_system_context, |
| 370 | const scoped_refptr<network::ResourceRequestBody>& body); |
lukasza | 5e8bef0e | 2017-05-30 23:41:45 | [diff] [blame] | 371 | |
Sharon Yang | 59197b2a | 2023-03-24 17:49:24 | [diff] [blame] | 372 | // 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-Malek | b49606cf | 2018-01-12 17:23:34 | [diff] [blame] | 374 | bool CanReadRequestBody( |
Sharon Yang | 59197b2a | 2023-03-24 17:49:24 | [diff] [blame] | 375 | RenderProcessHost* process, |
John Abd-El-Malek | b49606cf | 2018-01-12 17:23:34 | [diff] [blame] | 376 | const scoped_refptr<network::ResourceRequestBody>& body); |
lukasza | 4ec2e757 | 2017-05-26 23:18:10 | [diff] [blame] | 377 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 378 | // 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 Colwell | ea6921f | 2019-01-29 16:50:39 | [diff] [blame] | 387 | // this method exactly once. This call must be made on the UI thread. |
| 388 | void Add(int child_id, BrowserContext* browser_context); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 389 | |
Aaron Colwell | ffade2a | 2020-09-16 20:54:41 | [diff] [blame] | 390 | // 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 Colwell | 529eb6e | 2019-01-24 04:31:53 | [diff] [blame] | 396 | // Upon destruction, child processes should unregister themselves by calling |
Aaron Colwell | ea6921f | 2019-01-29 16:50:39 | [diff] [blame] | 397 | // this method exactly once. This call must be made on the UI thread. |
Aaron Colwell | dc21174 | 2019-04-05 21:04:01 | [diff] [blame] | 398 | // |
| 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] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 405 | void Remove(int child_id); |
| 406 | |
Daniel Cheng | 4ebba55 | 2018-07-06 21:43:16 | [diff] [blame] | 407 | // Whenever the browser processes commands the child process to commit a URL, |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 408 | // it should call this method to grant the child process the capability to |
Daniel Cheng | 4ebba55 | 2018-07-06 21:43:16 | [diff] [blame] | 409 | // 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] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 412 | |
[email protected] | dc67e1c3 | 2012-06-08 00:10:40 | [diff] [blame] | 413 | // 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 Hockey | 91f58d7aa | 2024-10-03 22:59:21 | [diff] [blame] | 415 | // 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] | dc67e1c3 | 2012-06-08 00:10:40 | [diff] [blame] | 418 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 419 | // Revokes all permissions granted to the given file. |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame] | 420 | void RevokeAllPermissionsForFile(int child_id, const base::FilePath& file); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 421 | |
Avi Drissman | 78865bbb | 2024-08-22 20:57:19 | [diff] [blame] | 422 | // Grant the child process the ability to use Web UI Bindings. |
| 423 | void GrantWebUIBindings(int child_id, BindingsPolicySet bindings); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 424 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 425 | // 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 Reis | c1f5da6 | 2024-05-17 16:13:43 | [diff] [blame] | 431 | // Some APIs for Android WebView and <webview> tags allow bypassing some |
Charlie Reis | 0555626 | 2024-04-25 21:30:49 | [diff] [blame] | 432 | // security checks, such as which URLs are allowed to commit. This method |
Charlie Reis | c1f5da6 | 2024-05-17 16:13:43 | [diff] [blame] | 433 | // 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 Reis | 0555626 | 2024-04-25 21:30:49 | [diff] [blame] | 440 | // |
| 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 Reis | c1f5da6 | 2024-05-17 16:13:43 | [diff] [blame] | 444 | void GrantOriginCheckExemptionForWebView(int child_id, |
| 445 | const url::Origin& origin); |
Charlie Reis | 0555626 | 2024-04-25 21:30:49 | [diff] [blame] | 446 | |
Charlie Reis | c1f5da6 | 2024-05-17 16:13:43 | [diff] [blame] | 447 | // 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 Reis | 0555626 | 2024-04-25 21:30:49 | [diff] [blame] | 452 | |
[email protected] | 9f10431 | 2013-07-23 23:18:19 | [diff] [blame] | 453 | // Explicit permissions checks for FileSystemURL specified files. |
nick | b3c1e27 | 2016-10-07 22:56:37 | [diff] [blame] | 454 | 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] | 4b9d086 | 2013-10-15 19:49:41 | [diff] [blame] | 463 | bool CanCopyIntoFileSystemFile(int child_id, |
nick | b3c1e27 | 2016-10-07 22:56:37 | [diff] [blame] | 464 | const storage::FileSystemURL& filesystem_url); |
| 465 | bool CanDeleteFileSystemFile(int child_id, |
| 466 | const storage::FileSystemURL& filesystem_url); |
Chris Bookholt | 6b6383e | 2021-12-10 21:37:54 | [diff] [blame] | 467 | 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] | 9f10431 | 2013-07-23 23:18:19 | [diff] [blame] | 473 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 474 | // Returns true if the specified child_id has been granted ReadRawCookies. |
| 475 | bool CanReadRawCookies(int child_id); |
| 476 | |
Lukasz Anforowicz | 3800358 | 2019-09-24 19:08:05 | [diff] [blame] | 477 | // 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 483 | // Sets the process identified by |child_id| as only permitted to access data |
W. James MacLean | e84fa11 | 2020-07-14 17:25:54 | [diff] [blame] | 484 | // 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 Reis | 47457a6 | 2022-05-18 21:57:37 | [diff] [blame] | 489 | // 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 MacLean | e84fa11 | 2020-07-14 17:25:54 | [diff] [blame] | 491 | void LockProcess(const IsolationContext& isolation_context, |
| 492 | int child_id, |
Charlie Reis | 47457a6 | 2022-05-18 21:57:37 | [diff] [blame] | 493 | bool is_process_used, |
W. James MacLean | e84fa11 | 2020-07-14 17:25:54 | [diff] [blame] | 494 | const ProcessLock& process_lock); |
[email protected] | 313b80bd | 2011-11-23 03:49:10 | [diff] [blame] | 495 | |
Aaron Colwell | 80f85bb | 2020-05-19 01:55:06 | [diff] [blame] | 496 | // Testing helper method that generates a lock_url from |url| and then |
W. James MacLean | e84fa11 | 2020-07-14 17:25:54 | [diff] [blame] | 497 | // calls LockProcess() with that lock URL. |
Aaron Colwell | 80f85bb | 2020-05-19 01:55:06 | [diff] [blame] | 498 | void LockProcessForTesting(const IsolationContext& isolation_context, |
| 499 | int child_id, |
| 500 | const GURL& url); |
| 501 | |
W. James MacLean | e84fa11 | 2020-07-14 17:25:54 | [diff] [blame] | 502 | // 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 Moshchuk | 75cffa9 | 2017-10-11 20:24:02 | [diff] [blame] | 505 | |
[email protected] | ce5cbed8 | 2013-07-01 11:52:31 | [diff] [blame] | 506 | // 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] | cd501a7 | 2014-08-22 19:58:31 | [diff] [blame] | 508 | // storage::FilePermissionPolicy. |
| 509 | void RegisterFileSystemPermissionPolicy(storage::FileSystemType type, |
| 510 | int policy); |
[email protected] | ce5cbed8 | 2013-07-01 11:52:31 | [diff] [blame] | 511 | |
Michael Wilson | a24fe88 | 2023-06-01 01:02:50 | [diff] [blame] | 512 | // 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] | 6e068ea | 2014-02-04 07:05:47 | [diff] [blame] | 516 | bool CanSendMidiSysExMessage(int child_id); |
[email protected] | 4ca7cf0f | 2013-08-28 14:19:03 | [diff] [blame] | 517 | |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 518 | // Remove all isolated origins associated with |browser_context| and clear any |
| 519 | // pointers that may reference |browser_context|. This is |
Aaron Colwell | 67f93006c | 2019-04-01 22:45:28 | [diff] [blame] | 520 | // 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 Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 525 | void RemoveStateForBrowserContext(const BrowserContext& browser_context); |
alexmos | 3b9ad10 | 2017-05-26 23:41:08 | [diff] [blame] | 526 | |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 527 | // Check whether |origin| requires origin-wide process isolation within |
| 528 | // |isolation_context|. |
alexmos | 4bc2632 | 2017-07-01 00:57:14 | [diff] [blame] | 529 | // |
| 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 535 | // |
| 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 MacLean | 46cf2621 | 2020-10-01 16:43:37 | [diff] [blame] | 538 | // 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 542 | bool IsIsolatedOrigin(const IsolationContext& isolation_context, |
W. James MacLean | 46cf2621 | 2020-10-01 16:43:37 | [diff] [blame] | 543 | const url::Origin& origin, |
| 544 | bool origin_requests_isolation); |
alexmos | 3b9ad10 | 2017-05-26 23:41:08 | [diff] [blame] | 545 | |
alexmos | 4bc2632 | 2017-07-01 00:57:14 | [diff] [blame] | 546 | // 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 | |
arthursonzogni | 98e5a23 | 2017-07-13 15:18:16 | [diff] [blame] | 552 | // 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 Colwell | 01466ed | 2019-10-24 01:17:52 | [diff] [blame] | 559 | // 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 Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 563 | // 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 MacLean | c07dc41b | 2022-07-25 18:52:16 | [diff] [blame] | 576 | // 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 MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 582 | |
W. James MacLean | c07dc41b | 2022-07-25 18:52:16 | [diff] [blame] | 583 | // 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 MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 596 | |
Alex Moshchuk | 989aa22c | 2024-11-06 02:09:07 | [diff] [blame] | 597 | // 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 MacLean | 8930725 | 2020-11-11 00:16:44 | [diff] [blame] | 605 | // 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 Kasting | e5a38ed | 2021-10-02 03:06:35 | [diff] [blame] | 608 | browsing_instance_cleanup_delay_ = base::Seconds(delay_in_seconds); |
W. James MacLean | 8930725 | 2020-11-11 00:16:44 | [diff] [blame] | 609 | } |
| 610 | |
W. James MacLean | 24d534b | 2021-11-22 18:51:35 | [diff] [blame] | 611 | // Allows tests to query the number of BrowsingInstanceIds associated with a |
| 612 | // child process. |
| 613 | size_t BrowsingInstanceIdCountForTesting(int child_id); |
| 614 | |
Alex Moshchuk | 71ca290 | 2023-04-07 18:08:37 | [diff] [blame] | 615 | void ClearRegisteredSchemeForTesting(const std::string& scheme); |
| 616 | |
Alex Moshchuk | 989aa22c | 2024-11-06 02:09:07 | [diff] [blame] | 617 | // 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 MacLean | 2a84fbf | 2023-05-12 18:13:43 | [diff] [blame] | 624 | // Exposes LookupOriginIsolationState() for tests. |
| 625 | OriginAgentClusterIsolationState* LookupOriginIsolationStateForTesting( |
| 626 | const BrowsingInstanceId& browsing_instance_id, |
| 627 | const url::Origin& origin); |
| 628 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 629 | private: |
| 630 | friend class ChildProcessSecurityPolicyInProcessBrowserTest; |
[email protected] | bfcf1e9 | 2013-07-11 04:37:25 | [diff] [blame] | 631 | friend class ChildProcessSecurityPolicyTest; |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 632 | friend class ChildProcessSecurityPolicyImpl::Handle; |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 633 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyInProcessBrowserTest, |
| 634 | NoLeak); |
[email protected] | bee16c0b | 2013-09-16 20:30:48 | [diff] [blame] | 635 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, FilePermissions); |
Alex Moshchuk | ef8c256 | 2021-03-12 06:37:45 | [diff] [blame] | 636 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 637 | AddFutureIsolatedOrigins); |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 638 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 639 | DynamicIsolatedOrigins); |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 640 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 641 | IsolatedOriginsForSpecificBrowserContexts); |
| 642 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 643 | IsolatedOriginsForSpecificBrowsingInstances); |
| 644 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 645 | IsolatedOriginsForCurrentAndFutureBrowsingInstances); |
| 646 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 647 | IsolatedOriginsRemovedWhenBrowserContextDestroyed); |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 648 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 649 | IsolateAllSuborigins); |
W. James MacLean | 5eaf0bd | 2024-06-26 21:15:32 | [diff] [blame] | 650 | FRIEND_TEST_ALL_PREFIXES( |
| 651 | ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault, |
| 652 | WildcardAndNonWildcardOrigins); |
| 653 | FRIEND_TEST_ALL_PREFIXES( |
| 654 | ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault, |
| 655 | WildcardAndNonWildcardEmbedded); |
Andrew Stone | 0a177fe2 | 2019-06-26 08:12:04 | [diff] [blame] | 656 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 657 | ParseIsolatedOrigins); |
| 658 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, WildcardDefaultPort); |
Alex Moshchuk | 989aa22c | 2024-11-06 02:09:07 | [diff] [blame] | 659 | FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, |
| 660 | MatchesCommittedOrigin); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 661 | |
| 662 | class SecurityState; |
| 663 | |
| 664 | typedef std::set<std::string> SchemeSet; |
Aaron Colwell | 67f93006c | 2019-04-01 22:45:28 | [diff] [blame] | 665 | typedef std::map<int, std::unique_ptr<SecurityState>> SecurityStateMap; |
[email protected] | cd501a7 | 2014-08-22 19:58:31 | [diff] [blame] | 666 | typedef std::map<storage::FileSystemType, int> FileSystemPermissionPolicyMap; |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 667 | |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 668 | // 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 673 | IsolatedOriginEntry(const url::Origin& origin, |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 674 | bool applies_to_future_browsing_instances, |
| 675 | BrowsingInstanceId browsing_instance_id, |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 676 | BrowserContext* browser_context, |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 677 | ResourceContext* resource_context, |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 678 | bool isolate_all_subdomains, |
| 679 | IsolatedOriginSource source); |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 680 | // 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 Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 689 | return std::tie(origin_, applies_to_future_browsing_instances_, |
| 690 | browsing_instance_id_, browser_context_, |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 691 | resource_context_, isolate_all_subdomains_, source_) < |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 692 | 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 697 | } |
| 698 | |
| 699 | bool operator==(const IsolatedOriginEntry& other) const { |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 700 | return origin_ == other.origin_ && |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 701 | applies_to_future_browsing_instances_ == |
| 702 | other.applies_to_future_browsing_instances_ && |
| 703 | browsing_instance_id_ == other.browsing_instance_id_ && |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 704 | browser_context_ == other.browser_context_ && |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 705 | resource_context_ == other.resource_context_ && |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 706 | isolate_all_subdomains_ == other.isolate_all_subdomains_ && |
| 707 | source_ == other.source_; |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 708 | } |
| 709 | |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 710 | // 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 Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 719 | // 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 Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 724 | const url::Origin& origin() const { return origin_; } |
| 725 | |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 726 | // 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 Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 735 | } |
| 736 | |
| 737 | const BrowserContext* browser_context() const { return browser_context_; } |
| 738 | |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 739 | bool isolate_all_subdomains() const { return isolate_all_subdomains_; } |
| 740 | |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 741 | IsolatedOriginSource source() const { return source_; } |
| 742 | |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 743 | private: |
| 744 | url::Origin origin_; |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 745 | |
| 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 Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 758 | |
| 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 Sonzogni | ff83758 | 2023-12-22 10:05:45 | [diff] [blame] | 763 | raw_ptr<BrowserContext> browser_context_; |
| 764 | raw_ptr<ResourceContext> resource_context_; |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 765 | |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 766 | // 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 Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 774 | // This tracks the source of each isolated origin entry, e.g., to |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 775 | // distinguish those that should be displayed to the user from those that |
| 776 | // should not. See https://crbug.com/920911. |
Alex Moshchuk | c467942 | 2019-06-11 17:04:48 | [diff] [blame] | 777 | IsolatedOriginSource source_; |
Alex Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 778 | }; |
| 779 | |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 780 | // 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] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 794 | // Obtain an instance of ChildProcessSecurityPolicyImpl via GetInstance(). |
| 795 | ChildProcessSecurityPolicyImpl(); |
olli.raula | 36aa8be | 2015-09-10 11:14:22 | [diff] [blame] | 796 | friend struct base::DefaultSingletonTraits<ChildProcessSecurityPolicyImpl>; |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 797 | |
[email protected] | cee64fd3 | 2011-05-02 18:59:07 | [diff] [blame] | 798 | // Determines if certain permissions were granted for a file to given child |
[email protected] | 322a6eb | 2013-11-12 06:13:09 | [diff] [blame] | 799 | // process. |permissions| is an internally defined bit-set. |
[email protected] | cee64fd3 | 2011-05-02 18:59:07 | [diff] [blame] | 800 | bool ChildProcessHasPermissionsForFile(int child_id, |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame] | 801 | const base::FilePath& file, |
Lukasz Anforowicz | 40066f5 | 2018-09-21 21:14:41 | [diff] [blame] | 802 | int permissions) |
| 803 | EXCLUSIVE_LOCKS_REQUIRED(lock_); |
[email protected] | cee64fd3 | 2011-05-02 18:59:07 | [diff] [blame] | 804 | |
[email protected] | 322a6eb | 2013-11-12 06:13:09 | [diff] [blame] | 805 | // Grant a particular permission set for a file. |permissions| is an |
| 806 | // internally defined bit-set. |
[email protected] | bfcf1e9 | 2013-07-11 04:37:25 | [diff] [blame] | 807 | 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 Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 814 | void GrantPermissionsForFileSystem(int child_id, |
| 815 | const std::string& filesystem_id, |
| 816 | int permission); |
[email protected] | bfcf1e9 | 2013-07-11 04:37:25 | [diff] [blame] | 817 | |
[email protected] | bee16c0b | 2013-09-16 20:30:48 | [diff] [blame] | 818 | // Determines if certain permissions were granted for a file. |permissions| |
Aaron Colwell | f140870 | 2018-12-03 18:23:25 | [diff] [blame] | 819 | // is an internally defined bit-set. |
[email protected] | bee16c0b | 2013-09-16 20:30:48 | [diff] [blame] | 820 | bool HasPermissionsForFile(int child_id, |
| 821 | const base::FilePath& file, |
| 822 | int permissions); |
| 823 | |
[email protected] | bee16c0b | 2013-09-16 20:30:48 | [diff] [blame] | 824 | // Determines if certain permissions were granted for a file in FileSystem |
[email protected] | 322a6eb | 2013-11-12 06:13:09 | [diff] [blame] | 825 | // API. |permissions| is an internally defined bit-set. |
nick | b3c1e27 | 2016-10-07 22:56:37 | [diff] [blame] | 826 | bool HasPermissionsForFileSystemFile( |
| 827 | int child_id, |
| 828 | const storage::FileSystemURL& filesystem_url, |
| 829 | int permissions); |
[email protected] | bee16c0b | 2013-09-16 20:30:48 | [diff] [blame] | 830 | |
[email protected] | 322a6eb | 2013-11-12 06:13:09 | [diff] [blame] | 831 | // Determines if certain permissions were granted for a file system. |
| 832 | // |permissions| is an internally defined bit-set. |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 833 | bool HasPermissionsForFileSystem(int child_id, |
| 834 | const std::string& filesystem_id, |
| 835 | int permission); |
[email protected] | 322a6eb | 2013-11-12 06:13:09 | [diff] [blame] | 836 | |
Aaron Colwell | 220d502 | 2019-01-16 04:56:55 | [diff] [blame] | 837 | // 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 Stone | 0a177fe2 | 2019-06-26 08:12:04 | [diff] [blame] | 842 | // 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 Moshchuk | ef8c256 | 2021-03-12 06:37:45 | [diff] [blame] | 845 | // AddFutureIsolatedOrigins(). |
Andrew Stone | 0a177fe2 | 2019-06-26 08:12:04 | [diff] [blame] | 846 | static std::vector<IsolatedOriginPattern> ParseIsolatedOrigins( |
Md Hasibul Hasan | a963a934 | 2024-04-03 10:15:14 | [diff] [blame] | 847 | std::string_view pattern_list); |
Andrew Stone | 0a177fe2 | 2019-06-26 08:12:04 | [diff] [blame] | 848 | |
Alex Moshchuk | ef8c256 | 2021-03-12 06:37:45 | [diff] [blame] | 849 | void AddFutureIsolatedOrigins( |
| 850 | const std::vector<IsolatedOriginPattern>& patterns, |
| 851 | IsolatedOriginSource source, |
| 852 | BrowserContext* browser_context = nullptr); |
Andrew Stone | 0a177fe2 | 2019-06-26 08:12:04 | [diff] [blame] | 853 | |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 854 | // 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 Colwell | dd9dce3 | 2020-06-04 21:03:52 | [diff] [blame] | 864 | bool AddProcessReference(int child_id, bool duplicating_handle); |
| 865 | bool AddProcessReferenceLocked(int child_id, bool duplicating_handle) |
| 866 | EXCLUSIVE_LOCKS_REQUIRED(lock_); |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 867 | void RemoveProcessReference(int child_id); |
| 868 | void RemoveProcessReferenceLocked(int child_id) |
| 869 | EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| 870 | |
Peter KH | a027bf6 | 2025-07-29 15:22:52 | [diff] [blame] | 871 | // Internal helper for RemoveAllStateForBrowsingInstance(). |
| 872 | void RemoveAllStateForBrowsingInstanceInternal( |
W. James MacLean | 8930725 | 2020-11-11 00:16:44 | [diff] [blame] | 873 | const BrowsingInstanceId browsing_instance_id); |
| 874 | |
Aaron Colwell | 01466ed | 2019-10-24 01:17:52 | [diff] [blame] | 875 | // 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 Moshchuk | df44817e | 2024-10-02 22:54:54 | [diff] [blame] | 880 | // 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 Moshchuk | 99c2268 | 2024-03-28 22:43:46 | [diff] [blame] | 910 | // 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 Anforowicz | d0d8cdb | 2021-01-27 22:20:47 | [diff] [blame] | 915 | |
Alex Moshchuk | 31e0f345 | 2024-03-29 20:56:10 | [diff] [blame] | 916 | // 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 Moshchuk | 304a54b | 2024-06-26 15:58:54 | [diff] [blame] | 923 | // 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 MacLean | d42fa81 | 2021-11-18 22:59:26 | [diff] [blame] | 927 | // 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] | 826ad711 | 2011-09-02 21:39:03 | [diff] [blame] | 934 | // You must acquire this lock before reading or writing any members of this |
Elly | 14008c3 | 2024-08-15 16:15:43 | [diff] [blame] | 935 | // 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] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 938 | base::Lock lock_; |
| 939 | |
Elly | 14008c3 | 2024-08-15 16:15:43 | [diff] [blame] | 940 | // 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] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 946 | |
| 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 |
Elly | 14008c3 | 2024-08-15 16:15:43 | [diff] [blame] | 949 | // protected by |schemes_lock_|. |
| 950 | SchemeSet pseudo_schemes_ GUARDED_BY(schemes_lock_); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 951 | |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 952 | // 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 Anforowicz | 40066f5 | 2018-09-21 21:14:41 | [diff] [blame] | 956 | SecurityStateMap security_state_ GUARDED_BY(lock_); |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 957 | |
Aaron Colwell | dc21174 | 2019-04-05 21:04:01 | [diff] [blame] | 958 | // 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 Anforowicz | 40066f5 | 2018-09-21 21:14:41 | [diff] [blame] | 966 | FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_); |
[email protected] | ce5cbed8 | 2013-07-01 11:52:31 | [diff] [blame] | 967 | |
Aaron Colwell | 4fcbe415 | 2020-01-16 07:10:59 | [diff] [blame] | 968 | // 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 Moshchuk | f01172e | 2019-01-16 00:54:17 | [diff] [blame] | 975 | // 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 | |
alexmos | 3b9ad10 | 2017-05-26 23:41:08 | [diff] [blame] | 982 | // 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 Moshchuk | f01172e | 2019-01-16 00:54:17 | [diff] [blame] | 985 | // protected by |isolated_origins_lock_|. |
Alex Moshchuk | 4e19b36 | 2018-09-10 21:14:36 | [diff] [blame] | 986 | // |
| 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 Moshchuk | 8e5c195 | 2019-01-15 03:39:50 | [diff] [blame] | 996 | // |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 997 | // Each origin entry stores information about: |
Alex Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 998 | // 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 Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 1007 | // 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 Moshchuk | 331fa5f | 2021-03-10 06:16:59 | [diff] [blame] | 1016 | // represents https://test.foo.com being isolated in profile1 |
| 1017 | // with BrowsingInstance ID 4, and also in profile2 with |
Alex Moshchuk | 99b79542 | 2019-03-07 00:27:32 | [diff] [blame] | 1018 | // BrowsingInstance ID 7. |
Andrew Stone | 6ed99b2 | 2019-06-07 06:14:39 | [diff] [blame] | 1019 | base::flat_map<GURL, std::vector<IsolatedOriginEntry>> isolated_origins_ |
Alex Moshchuk | f01172e | 2019-01-16 00:54:17 | [diff] [blame] | 1020 | GUARDED_BY(isolated_origins_lock_); |
alexmos | 3b9ad10 | 2017-05-26 23:41:08 | [diff] [blame] | 1021 | |
W. James MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 1022 | // 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 MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 1025 | base::Lock origins_isolation_opt_in_lock_; |
W. James MacLean | c07dc41b | 2022-07-25 18:52:16 | [diff] [blame] | 1026 | // 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 MacLean | d42fa81 | 2021-11-18 22:59:26 | [diff] [blame] | 1031 | // 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 MacLean | d7eb156 | 2020-11-17 17:56:10 | [diff] [blame] | 1037 | base::flat_map<BrowserContext*, base::flat_set<url::Origin>> |
W. James MacLean | c07dc41b | 2022-07-25 18:52:16 | [diff] [blame] | 1038 | origin_isolation_opt_ins_and_outs_ |
| 1039 | GUARDED_BY(origins_isolation_opt_in_lock_); |
W. James MacLean | d42fa81 | 2021-11-18 22:59:26 | [diff] [blame] | 1040 | |
W. James MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 1041 | // A map to track origins that have been isolated within a given |
W. James MacLean | d42fa81 | 2021-11-18 22:59:26 | [diff] [blame] | 1042 | // 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 MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 1048 | base::flat_map<BrowsingInstanceId, std::vector<OriginAgentClusterOptInEntry>> |
W. James MacLean | 64ddbcc | 2020-01-24 22:34:22 | [diff] [blame] | 1049 | origin_isolation_by_browsing_instance_ |
| 1050 | GUARDED_BY(origins_isolation_opt_in_lock_); |
W. James MacLean | 1c40862c | 2020-04-27 21:05:57 | [diff] [blame] | 1051 | |
Peter KH | a027bf6 | 2025-07-29 15:22:52 | [diff] [blame] | 1052 | 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 MacLean | 8930725 | 2020-11-11 00:16:44 | [diff] [blame] | 1062 | // 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 MacLean | 07f9909 | 2021-02-24 21:55:34 | [diff] [blame] | 1064 | // 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 Toyoshima | b89ec84 | 2021-07-12 10:39:49 | [diff] [blame] | 1070 | base::TimeDelta browsing_instance_cleanup_delay_; |
[email protected] | df8e899b | 2011-02-22 22:58:22 | [diff] [blame] | 1071 | }; |
| 1072 | |
[email protected] | 4648832 | 2012-10-30 03:22:20 | [diff] [blame] | 1073 | } // namespace content |
| 1074 | |
[email protected] | b953542 | 2012-02-09 01:47:59 | [diff] [blame] | 1075 | #endif // CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_ |