Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2021 The Chromium Authors |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [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 | |
| 5 | #ifndef CONTENT_BROWSER_URL_INFO_H_ |
| 6 | #define CONTENT_BROWSER_URL_INFO_H_ |
| 7 | |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 8 | #include <optional> |
| 9 | |
Alex Moshchuk | f8236e1 | 2024-12-10 01:13:01 | [diff] [blame] | 10 | #include "base/tracing/protos/chrome_track_event.pbzero.h" |
Camille Lamy | d1f015d | 2024-07-06 14:14:10 | [diff] [blame] | 11 | #include "content/browser/agent_cluster_key.h" |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 12 | #include "content/browser/origin_agent_cluster_isolation_state.h" |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 13 | #include "content/browser/web_exposed_isolation_info.h" |
| 14 | #include "content/common/content_export.h" |
| 15 | #include "content/public/browser/storage_partition_config.h" |
Alex Moshchuk | f8236e1 | 2024-12-10 01:13:01 | [diff] [blame] | 16 | #include "third_party/perfetto/include/perfetto/tracing/traced_proto.h" |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 17 | #include "url/gurl.h" |
| 18 | #include "url/origin.h" |
| 19 | |
| 20 | namespace content { |
| 21 | |
| 22 | // This struct is used to package a GURL together with extra state required to |
| 23 | // make SiteInstance/process allocation decisions, e.g. whether the url's |
| 24 | // origin or site is requesting isolation as determined by response headers in |
| 25 | // the corresponding NavigationRequest. The extra state is generally most |
| 26 | // relevant when navigation to the URL is in progress, since once placed into a |
| 27 | // SiteInstance, the extra state will be available via SiteInfo. Otherwise, |
| 28 | // most callsites requiring a UrlInfo can create with a GURL, specifying kNone |
| 29 | // for |origin_isolation_request|. Some examples of where passing kNone for |
| 30 | // |origin_isolation_request| is safe are: |
| 31 | // * at DidCommitNavigation time, since at that point the SiteInstance has |
| 32 | // already been picked and the navigation can be considered finished, |
| 33 | // * before a response is received (the only way to request isolation is via |
| 34 | // response headers), and |
| 35 | // * outside of a navigation. |
| 36 | // |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 37 | // If UrlInfo::origin_isolation_state_request is nullopt, that does *not* imply |
| 38 | // that the URL's origin will not be isolated, and vice versa. The isolation |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 39 | // decision involves both response headers and consistency within a |
| 40 | // BrowsingInstance, and once we decide on the isolation outcome for an origin, |
| 41 | // it won't change for the lifetime of the BrowsingInstance. |
| 42 | // |
| 43 | // To check whether a frame ends up in a site-isolated process, use |
| 44 | // SiteInfo::RequiresDedicatedProcess() on its SiteInstance's SiteInfo. To |
W. James MacLean | 7f76c220 | 2021-11-15 16:27:49 | [diff] [blame] | 45 | // check whether a frame ends up being origin-isolated in a separate process |
| 46 | // (e.g., due to the Origin-Agent-Cluster header), use |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 47 | // SiteInfo::agent_cluster_key()::IsOriginKeyed(). To check whether the |
| 48 | // origin-isolation is due to OAC specifically, check SiteInfo::oac_status(). |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 49 | // |
| 50 | // Note: it is not expected that this struct will be exposed in content/public. |
W. James MacLean | 53e24b7 | 2023-05-09 20:57:07 | [diff] [blame] | 51 | class IsolationContext; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 52 | class UrlInfoInit; |
| 53 | |
| 54 | struct CONTENT_EXPORT UrlInfo { |
| 55 | public: |
W. James MacLean | 37dd4aade | 2022-07-28 15:40:51 | [diff] [blame] | 56 | // For isolated sandboxed iframes, when per-document mode is used, we |
| 57 | // assign each sandboxed SiteInstance a unique identifier to prevent other |
| 58 | // same-site/same-origin frames from re-using the same SiteInstance. This |
| 59 | // identifier is used to indicate that the sandbox id is not in use. |
| 60 | static const int64_t kInvalidUniqueSandboxId; |
| 61 | |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 62 | UrlInfo(); // Needed for inclusion in SiteInstanceDescriptor. |
| 63 | UrlInfo(const UrlInfo& other); |
| 64 | explicit UrlInfo(const UrlInfoInit& init); |
| 65 | ~UrlInfo(); |
| 66 | |
| 67 | // Used to convert GURL to UrlInfo in tests where opt-in isolation is not |
| 68 | // being tested. |
| 69 | static UrlInfo CreateForTesting(const GURL& url_in, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 70 | std::optional<StoragePartitionConfig> |
| 71 | storage_partition_config = std::nullopt); |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 72 | |
W. James MacLean | 53e24b7 | 2023-05-09 20:57:07 | [diff] [blame] | 73 | // Returns whether this UrlInfo is requesting an origin-keyed process for |
| 74 | // `url`'s origin due to the OriginAgentCluster header, or whether it should |
| 75 | // try to use an origin-keyed process by default within the given `context`, |
| 76 | // in cases without an explicit header. |
| 77 | bool RequestsOriginKeyedProcess(const IsolationContext& context) const; |
| 78 | |
W. James MacLean | e5d210f | 2023-04-06 13:21:50 | [diff] [blame] | 79 | // Returns whether this UrlInfo is requesting site isolation for its site in |
| 80 | // response to the Cross-Origin-Opener-Policy header. See |
| 81 | // https://chromium.googlesource.com/chromium/src/+/main/docs/process_model_and_site_isolation.md#Partial-Site-Isolation |
| 82 | // for details. |
| 83 | bool requests_coop_isolation() const { return is_coop_isolation_requested; } |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 84 | |
Arthur Hemery | 3a991c09 | 2021-12-22 12:04:24 | [diff] [blame] | 85 | // Returns whether this UrlInfo is for a page that should be cross-origin |
| 86 | // isolated. |
| 87 | bool IsIsolated() const; |
| 88 | |
Alex Moshchuk | f8236e1 | 2024-12-10 01:13:01 | [diff] [blame] | 89 | using TraceProto = perfetto::protos::pbzero::UrlInfo; |
| 90 | void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const; |
| 91 | |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 92 | GURL url; |
| 93 | |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 94 | // This field tracks the desired OriginAgentClusterIsolationState requested |
| 95 | // by the document. The OriginAgentClusterIsolationState tracks whether |
| 96 | // the document should be given an origin-keyed agent cluster in the renderer |
| 97 | // process (logical isolation), and whether this logical isolation should be |
| 98 | // backed by actual process isolation. This is only set when the document has |
| 99 | // an actual OAC header. |
| 100 | std::optional<OriginAgentClusterIsolationState> oac_header_request; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 101 | |
W. James MacLean | e5d210f | 2023-04-06 13:21:50 | [diff] [blame] | 102 | // True if the Cross-Origin-Opener-Policy header has triggered a hint to turn |
| 103 | // on site isolation for `url`'s site. |
| 104 | bool is_coop_isolation_requested = false; |
| 105 | |
Jeremy Roman | 3146e87 | 2024-03-12 18:57:24 | [diff] [blame] | 106 | // True if this resource is served from the prefetch cache, and its success |
| 107 | // may have been influenced by cross-site state. Such responses may require |
| 108 | // special handling to make it harder to detect that this has happened. |
| 109 | bool is_prefetch_with_cross_site_contamination = false; |
| 110 | |
Alex Moshchuk | c38d52b8 | 2022-05-03 18:43:10 | [diff] [blame] | 111 | // This allows overriding the origin of |url| for process assignment purposes |
Sharon Yang | 1311816 | 2023-11-14 19:40:23 | [diff] [blame] | 112 | // in certain very special cases. |
| 113 | // - The navigation to |url| is through loadDataWithBaseURL (e.g., in a |
| 114 | // <webview> tag or on Android Webview): this will be the base origin |
| 115 | // provided via that API. |
| 116 | // - For renderer-initiated about:blank navigations: this will be the |
| 117 | // initiator's origin that about:blank should inherit. |
| 118 | // - data: URLs that will be rendered (e.g. not downloads) that do NOT use |
| 119 | // loadDataWithBaseURL: this will be the value of the tentative origin to |
| 120 | // commit, which we will use to keep the nonce of the opaque origin |
| 121 | // consistent across a navigation. |
| 122 | // - All other cases: this will be nullopt. |
Alex Moshchuk | c38d52b8 | 2022-05-03 18:43:10 | [diff] [blame] | 123 | // |
| 124 | // TODO(alexmos): Currently, this is also used to hold the origin committed |
| 125 | // by the renderer at DidCommitNavigation() time, for use in commit-time URL |
| 126 | // and origin checks that require a UrlInfo. Investigate whether there's a |
| 127 | // cleaner way to organize these checks. See https://crbug.com/1320402. |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 128 | std::optional<url::Origin> origin; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 129 | |
W. James MacLean | c79153d | 2022-02-10 19:17:34 | [diff] [blame] | 130 | // If url is being loaded in a frame that is in a origin-restricted sandboxed, |
| 131 | // then this flag will be true. |
| 132 | bool is_sandboxed = false; |
| 133 | |
W. James MacLean | 37dd4aade | 2022-07-28 15:40:51 | [diff] [blame] | 134 | // Only used when `is_sandboxed` is true, this unique identifier allows for |
| 135 | // per-document SiteInfo grouping. |
| 136 | int64_t unique_sandbox_id = kInvalidUniqueSandboxId; |
| 137 | |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 138 | // The StoragePartitionConfig that should be used when loading content from |
| 139 | // |url|. If absent, ContentBrowserClient::GetStoragePartitionConfig will be |
| 140 | // used to determine which StoragePartitionConfig to use. |
| 141 | // |
| 142 | // If present, this value will be used as the StoragePartitionConfig in the |
| 143 | // SiteInfo, regardless of its validity. SiteInstances created from a UrlInfo |
| 144 | // containing a StoragePartitionConfig that isn't compatible with the |
| 145 | // BrowsingInstance that the SiteInstance should belong to will lead to a |
| 146 | // CHECK failure. |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 147 | std::optional<StoragePartitionConfig> storage_partition_config; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 148 | |
| 149 | // Pages may choose to isolate themselves more strongly than the web's |
| 150 | // default, thus allowing access to APIs that would be difficult to |
| 151 | // safely expose otherwise. "Cross-origin isolation", for example, requires |
| 152 | // assertion of a Cross-Origin-Opener-Policy and |
| 153 | // Cross-Origin-Embedder-Policy, and unlocks SharedArrayBuffer. |
Arthur Hemery | 3a991c09 | 2021-12-22 12:04:24 | [diff] [blame] | 154 | // When we haven't yet been to the network or inherited properties that are |
| 155 | // sufficient to know the future isolation state - we are in a speculative |
| 156 | // state - this member will be empty. |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 157 | std::optional<WebExposedIsolationInfo> web_exposed_isolation_info; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 158 | |
| 159 | // Indicates that the URL directs to PDF content, which should be isolated |
Min Qin | 1b84727c | 2024-03-08 18:39:35 | [diff] [blame] | 160 | // from other types of content. On Android, this can only be true when a PDF |
| 161 | // NativePage is created for a main frame navigation. |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 162 | bool is_pdf = false; |
| 163 | |
Camille Lamy | d1f015d | 2024-07-06 14:14:10 | [diff] [blame] | 164 | // The CrossOriginIsolationKey to use for the navigation. This represents the |
| 165 | // isolation requested by the page itself through the use of COOP, COEP and |
| 166 | // DIP. Right now, this is only set when DocumentIsolationPolicy is enabled, |
| 167 | // but it should eventually for COOP and COEP. It will eventually replace |
| 168 | // WebExposedIsolationInfo. |
| 169 | std::optional<AgentClusterKey::CrossOriginIsolationKey> |
| 170 | cross_origin_isolation_key; |
| 171 | |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 172 | // Any new UrlInfo fields should be added to UrlInfoInit as well, and the |
| 173 | // UrlInfo constructor that takes a UrlInfoInit should be updated as well. |
| 174 | }; |
| 175 | |
| 176 | class CONTENT_EXPORT UrlInfoInit { |
| 177 | public: |
| 178 | UrlInfoInit() = delete; |
| 179 | explicit UrlInfoInit(const GURL& url); |
| 180 | explicit UrlInfoInit(const UrlInfo& base); |
| 181 | ~UrlInfoInit(); |
| 182 | |
| 183 | UrlInfoInit& operator=(const UrlInfoInit&) = delete; |
| 184 | |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 185 | UrlInfoInit& WithOACHeaderRequest( |
| 186 | std::optional<OriginAgentClusterIsolationState> oac_header_request); |
W. James MacLean | e5d210f | 2023-04-06 13:21:50 | [diff] [blame] | 187 | UrlInfoInit& WithCOOPSiteIsolation(bool requests_coop_isolation); |
Jeremy Roman | 3146e87 | 2024-03-12 18:57:24 | [diff] [blame] | 188 | UrlInfoInit& WithCrossSitePrefetchContamination(bool contaminated); |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 189 | UrlInfoInit& WithOrigin(const url::Origin& origin); |
W. James MacLean | c79153d | 2022-02-10 19:17:34 | [diff] [blame] | 190 | UrlInfoInit& WithSandbox(bool is_sandboxed); |
W. James MacLean | 37dd4aade | 2022-07-28 15:40:51 | [diff] [blame] | 191 | UrlInfoInit& WithUniqueSandboxId(int unique_sandbox_id); |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 192 | UrlInfoInit& WithStoragePartitionConfig( |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 193 | std::optional<StoragePartitionConfig> storage_partition_config); |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 194 | UrlInfoInit& WithWebExposedIsolationInfo( |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 195 | std::optional<WebExposedIsolationInfo> web_exposed_isolation_info); |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 196 | UrlInfoInit& WithIsPdf(bool is_pdf); |
Camille Lamy | d1f015d | 2024-07-06 14:14:10 | [diff] [blame] | 197 | UrlInfoInit& WithCrossOriginIsolationKey( |
| 198 | const std::optional<AgentClusterKey::CrossOriginIsolationKey>& |
| 199 | cross_origin_isolation_key); |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 200 | |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 201 | const std::optional<url::Origin>& origin() { return origin_; } |
Alex Moshchuk | c38d52b8 | 2022-05-03 18:43:10 | [diff] [blame] | 202 | |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 203 | private: |
| 204 | UrlInfoInit(UrlInfoInit&); |
| 205 | |
| 206 | friend UrlInfo; |
| 207 | |
| 208 | GURL url_; |
Camille Lamy | 5ce9b96 | 2025-08-08 12:10:45 | [diff] [blame] | 209 | std::optional<OriginAgentClusterIsolationState> oac_header_request_; |
W. James MacLean | e5d210f | 2023-04-06 13:21:50 | [diff] [blame] | 210 | bool requests_coop_isolation_ = false; |
Jeremy Roman | 3146e87 | 2024-03-12 18:57:24 | [diff] [blame] | 211 | bool is_prefetch_with_cross_site_contamination_ = false; |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 212 | std::optional<url::Origin> origin_; |
W. James MacLean | c79153d | 2022-02-10 19:17:34 | [diff] [blame] | 213 | bool is_sandboxed_ = false; |
W. James MacLean | 37dd4aade | 2022-07-28 15:40:51 | [diff] [blame] | 214 | int64_t unique_sandbox_id_ = UrlInfo::kInvalidUniqueSandboxId; |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 215 | std::optional<StoragePartitionConfig> storage_partition_config_; |
| 216 | std::optional<WebExposedIsolationInfo> web_exposed_isolation_info_; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 217 | bool is_pdf_ = false; |
Camille Lamy | d1f015d | 2024-07-06 14:14:10 | [diff] [blame] | 218 | std::optional<AgentClusterKey::CrossOriginIsolationKey> |
| 219 | cross_origin_isolation_key_; |
Sharon Yang | d70a539 | 2021-10-26 23:06:32 | [diff] [blame] | 220 | |
| 221 | // Any new fields should be added to the UrlInfoInit(UrlInfo) constructor. |
| 222 | }; // class UrlInfoInit |
| 223 | |
| 224 | } // namespace content |
| 225 | |
| 226 | #endif // CONTENT_BROWSER_URL_INFO_H_ |