blob: b7e60facb728c38f9f2470e0749c0520ac73d0cd [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2021 The Chromium Authors
Sharon Yanga005ca12021-11-16 20:09:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_PROCESS_LOCK_H_
6#define CONTENT_BROWSER_PROCESS_LOCK_H_
7
Arthur Sonzognic686e8f2024-01-11 08:36:378#include <optional>
9
Sharon Yanga005ca12021-11-16 20:09:4210#include "content/browser/site_info.h"
11#include "content/browser/url_info.h"
12#include "content/browser/web_exposed_isolation_info.h"
13#include "content/public/browser/storage_partition_config.h"
Robbie McElratheae661e2023-08-10 19:05:2814#include "content/public/browser/web_exposed_isolation_level.h"
Sharon Yanga005ca12021-11-16 20:09:4215#include "url/origin.h"
16
17namespace content {
18
19class IsolationContext;
20
21// ProcessLock is a core part of Site Isolation, which is used to determine
22// which documents are allowed to load in a process and which site data the
Charlie Reis47457a62022-05-18 21:57:3723// process is allowed to access, based on the SiteInfo principal.
24//
25// If a process has a ProcessLock in the "invalid" state, then no SiteInstances
26// have been associated with the process and access should not be granted to
27// anything.
28//
Sharon Yanga005ca12021-11-16 20:09:4229// Once a process is associated with its first SiteInstance, it transitions to
30// the "locked_to_site" or "allow_any_site" state depending on whether the
31// SiteInstance requires the process to be locked to a specific site or not.
32// If the SiteInstance does not require the process to be locked to a site, the
33// process will transition to the "allow_any_site" state and will allow any
34// site to commit in the process. Such a process can later be upgraded to the
35// "locked_to_site" state if something later determines that the process should
Charlie Reis47457a62022-05-18 21:57:3736// only allow access to a single site, but only if it hasn't otherwise been used
37// to render content. Once the process is in the "locked_to_site" state, it will
38// not be able to access site data from other sites.
Sharon Yanga005ca12021-11-16 20:09:4239//
40// ProcessLock is currently defined in terms of a single SiteInfo with a process
41// lock URL, but it could be possible to define it in terms of multiple
Charlie Reis47457a62022-05-18 21:57:3742// SiteInfos that are compatible with each other.
Sharon Yanga005ca12021-11-16 20:09:4243class CONTENT_EXPORT ProcessLock {
44 public:
45 // Create a lock that that represents a process that is associated with at
46 // least one SiteInstance, but is not locked to a specific site. Any request
47 // that wants to commit in this process must have a StoragePartitionConfig
Camille Lamy52a51202025-07-29 14:16:1248 // and cross-origin isolation and web-exposed isolation information
49 // (COOP/COEP, for example) that match the values used to create this lock.
Sharon Yanga005ca12021-11-16 20:09:4250 static ProcessLock CreateAllowAnySite(
51 const StoragePartitionConfig& storage_partition_config,
Camille Lamy52a51202025-07-29 14:16:1252 const WebExposedIsolationInfo& web_exposed_isolation_info,
53 const std::optional<AgentClusterKey::CrossOriginIsolationKey>&
54 cross_origin_isolation_key);
Sharon Yanga005ca12021-11-16 20:09:4255
56 // Create a lock for a specific UrlInfo. This method can be called from both
57 // the UI and IO threads. Locks created with the same parameters must always
58 // be considered equal independent of what thread they are called on. Special
59 // care must be taken since SiteInfos created on different threads don't
60 // always have the same contents for all their fields (e.g. site_url field is
61 // thread dependent).
62 static ProcessLock Create(const IsolationContext& isolation_context,
63 const UrlInfo& url_info);
64
Sharon Yang2c077a72021-11-30 02:27:5865 // Returns a ProcessLock representing what the given |site_info| requires.
66 // Note that this may be different from the actual ProcessLock of the
67 // resulting process, in cases where a locked process is not required (e.g.,
Alex Moshchuk4b137ea2023-03-30 17:49:3668 // SiteInfos for http://unisolated.invalid).
Sharon Yang2c077a72021-11-30 02:27:5869 static ProcessLock FromSiteInfo(const SiteInfo& site_info);
70
Sharon Yanga005ca12021-11-16 20:09:4271 ProcessLock();
Sharon Yanga005ca12021-11-16 20:09:4272 ProcessLock(const ProcessLock& rhs);
73 ProcessLock& operator=(const ProcessLock& rhs);
74
75 ~ProcessLock();
76
77 // Returns true if no information has been set on the lock.
78 bool is_invalid() const { return !site_info_.has_value(); }
79
80 // Returns true if the process is locked, but it is not restricted to a
81 // specific site. Any site is allowed to commit in the process as long as
82 // the request's COOP/COEP information matches the info provided when
83 // the lock was created.
Camille Lamybc43eff2025-08-22 09:32:1484 bool AllowsAnySite() const;
Sharon Yanga005ca12021-11-16 20:09:4285
86 // Returns true if the lock is restricted to a specific site and requires
87 // the request's COOP/COEP information to match the values provided when
88 // the lock was created.
Camille Lamybc43eff2025-08-22 09:32:1489 bool IsLockedToSite() const;
Sharon Yanga005ca12021-11-16 20:09:4290
91 // Returns the url that corresponds to the SiteInfo the lock is used with. It
92 // will always be the same as the site URL, except in cases where effective
93 // urls are in use. Always empty if the SiteInfo uses the default site url.
Camille Lamybc43eff2025-08-22 09:32:1494 // Note: this is derived from the AgentClusterKey. It's possible for two
95 // ProcessLocks to have the same process lock URL but different
96 // AgentClusterKeys when one of the AgentClusterKey is site keyed and the
97 // other is origin keyed, or when the two process locks have different
98 // cross-origin isolation status. This means that two ProcessLocks with the
99 // same process lock URL might not be considered equal. Therefore, compare
100 // ProcessLocks directly as much as possible.
101 GURL GetProcessLockURL() const;
Sharon Yanga005ca12021-11-16 20:09:42102
Alex Moshchuk50000062023-01-03 23:08:59103 // Returns the site URL of the SiteInfo with which the lock was constructed.
Camille Lamybc43eff2025-08-22 09:32:14104 // Prefer comparing ProcessLocks directly or using agent_cluster_key(), unless
105 // you care about effective URLs.
Alex Moshchuk50000062023-01-03 23:08:59106 const GURL site_url() const {
107 return site_info_.has_value() ? site_info_->site_url() : GURL();
108 }
109
Camille Lamyd1f015d2024-07-06 14:14:10110 // Returns the AgentClusterKey shared by agents allowed in this ProcessLock.
Camille Lamy52a51202025-07-29 14:16:12111 const AgentClusterKey agent_cluster_key() const {
Camille Lamyd1f015d2024-07-06 14:14:10112 return site_info_.has_value() ? site_info_->agent_cluster_key()
Camille Lamy52a51202025-07-29 14:16:12113 : AgentClusterKey();
Camille Lamyd1f015d2024-07-06 14:14:10114 }
115
W. James MacLean37dd4aade2022-07-28 15:40:51116 // True if this ProcessLock is for a sandboxed iframe without
117 // allow-same-origin.
W. James MacLeanc79153d2022-02-10 19:17:34118 // TODO(wjmaclean): This function's return type could mutate to an enum in
119 // future if required for sandboxed iframes that are restricted with different
120 // sandbox flags.
121 bool is_sandboxed() const {
122 return site_info_.has_value() && site_info_->is_sandboxed();
123 }
124
W. James MacLean37dd4aade2022-07-28 15:40:51125 // If this ProcessLock is for a sandboxed iframe without allow-same-origin,
126 // and per-document grouping has been enabled for kIsolateSandboxedIframes,
127 // then each SiteInfo will have a unique sandbox id encoded as part of the
128 // lock. If per-document grouping is not enabled, this returns
129 // UrlInfo::kInvalidUniqueSandboxId.
130 int unique_sandbox_id() const {
131 return (site_info_.has_value() ? site_info_->unique_sandbox_id()
132 : UrlInfo::kInvalidUniqueSandboxId);
133 }
134
Sharon Yanga005ca12021-11-16 20:09:42135 // Returns whether this ProcessLock is specific to PDF contents.
136 bool is_pdf() const { return site_info_.has_value() && site_info_->is_pdf(); }
137
Charlie Reis33312832022-05-23 17:26:57138 // Returns whether this ProcessLock can only be used for error pages.
Sharon Yanga6942552021-11-16 21:15:09139 bool is_error_page() const {
140 return site_info_.has_value() && site_info_->is_error_page();
141 }
142
Charlie Reis33312832022-05-23 17:26:57143 // Returns whether this ProcessLock is used for a <webview> guest process.
144 // This may be false for other types of GuestView.
Alex Moshchukdf15d8e2022-02-01 04:43:49145 bool is_guest() const {
146 return site_info_.has_value() && site_info_->is_guest();
147 }
148
Adithya Srinivasanf6377b12022-08-31 21:58:44149 // Returns whether this ProcessLock is used for a process that exclusively
150 // hosts content inside a <fencedframe>.
151 bool is_fenced() const {
152 return site_info_.has_value() && site_info_->is_fenced();
153 }
154
Sharon Yanga005ca12021-11-16 20:09:42155 // Returns the StoragePartitionConfig that corresponds to the SiteInfo the
156 // lock is used with.
Sharon Yanga6942552021-11-16 21:15:09157 StoragePartitionConfig GetStoragePartitionConfig() const;
Sharon Yanga005ca12021-11-16 20:09:42158
Robbie McElratheae661e2023-08-10 19:05:28159 // Returns the cross-origin isolation mode of the BrowsingInstance that all
160 // agents allowed in this ProcessLock belong to. See
161 // https://html.spec.whatwg.org/multipage/document-sequences.html#cross-origin-isolation-mode
Charlie Reis33312832022-05-23 17:26:57162 // This is tracked on ProcessLock because a RenderProcessHost can host only
163 // cross-origin isolated agents or only non-cross-origin isolated agents, not
164 // both.
Sharon Yanga6942552021-11-16 21:15:09165 WebExposedIsolationInfo GetWebExposedIsolationInfo() const;
Sharon Yanga005ca12021-11-16 20:09:42166
Robbie McElratheae661e2023-08-10 19:05:28167 // Returns the cross-origin isolated capability of all agents allowed in this
168 // ProcessLock, without taking into account the 'cross-origin-isolated'
169 // permissions policy. This ignores permissions policy because it's currently
170 // possible for agents with the same ProcessLock to have different
171 // 'cross-origin-isolated' permission policies. This can return a lower
172 // isolation level than `GetWebExposedIsolationInfo()` if this ProcessLock
173 // hosts agents that are cross-origin to a top-level document with the
174 // 'isolated application' isolation level. See
175 // https://html.spec.whatwg.org/multipage/webappapis.html#dom-crossoriginisolated
176 WebExposedIsolationLevel GetWebExposedIsolationLevel() const;
177
Sharon Yanga005ca12021-11-16 20:09:42178 // Returns whether lock_url() is at least at the granularity of a site (i.e.,
179 // a scheme plus eTLD+1, like https://google.com). Also returns true if the
180 // lock is to a more specific origin (e.g., https://accounts.google.com), but
181 // not if the lock is empty or applies to an entire scheme (e.g., file://).
182 bool IsASiteOrOrigin() const;
183
Camille Lamybc43eff2025-08-22 09:32:14184 bool MatchesScheme(const std::string& scheme) const;
Sharon Yanga005ca12021-11-16 20:09:42185
186 // Returns true if lock_url() has an opaque origin.
187 bool HasOpaqueOrigin() const;
188
189 // Returns true if |origin| matches the lock's origin.
190 bool MatchesOrigin(const url::Origin& origin) const;
191
192 // Returns true if the COOP/COEP origin isolation information in this lock
193 // is set and matches the information in |site_info|.
194 // Returns true if the web-exposed isolation level in this lock is set and
195 // matches (or exceeds) the level set in |site_info|.|.
196 bool IsCompatibleWithWebExposedIsolation(const SiteInfo& site_info) const;
197
198 bool operator==(const ProcessLock& rhs) const;
Sharon Yanga005ca12021-11-16 20:09:42199 // Defined to allow this object to act as a key for std::map.
200 bool operator<(const ProcessLock& rhs) const;
201
202 std::string ToString() const;
203
204 private:
Sharon Yang2c077a72021-11-30 02:27:58205 explicit ProcessLock(const SiteInfo& site_info);
206
Sharon Yanga005ca12021-11-16 20:09:42207 // TODO(creis): Consider tracking multiple compatible SiteInfos in ProcessLock
Charlie Reis33312832022-05-23 17:26:57208 // (e.g., multiple sites when Site Isolation is disabled). This can better
209 // restrict what the process has access to in cases that we currently use an
210 // allows-any-site ProcessLock.
Arthur Sonzognic686e8f2024-01-11 08:36:37211 std::optional<SiteInfo> site_info_;
Sharon Yanga005ca12021-11-16 20:09:42212};
213
214CONTENT_EXPORT std::ostream& operator<<(std::ostream& out,
215 const ProcessLock& process_lock);
216
217} // namespace content
218
219#endif // CONTENT_BROWSER_PROCESS_LOCK_H_