blob: c79107f7761b1d79362a61bde5c59cf6ddfef605 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
Peter Kasting1557e5f2025-01-28 01:14:085#include <algorithm>
[email protected]46fb9442011-12-09 17:57:476#include <set>
initial.commit09911bf2008-07-26 23:55:297#include <string>
Md Hasibul Hasana963a9342024-04-03 10:15:148#include <string_view>
initial.commit09911bf2008-07-26 23:55:299
Ho Cheung9722cbb2023-09-07 17:36:5110#include "base/containers/contains.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
Avi Drissmanadac21992023-01-11 23:46:3912#include "base/functional/callback_helpers.h"
Lukasz Anforowicz0672f8a2017-11-30 01:07:0613#include "base/logging.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
Lukasz Anforowicz38003582019-09-24 19:08:0515#include "base/memory/ref_counted.h"
Aaron Colwell220d5022019-01-16 04:56:5516#include "base/synchronization/waitable_event.h"
Guido Urdanetaef4e91942020-11-09 15:06:2417#include "base/test/bind.h"
Arthur Sonzogni4b818ae2022-10-25 22:09:5218#include "base/test/gtest_util.h"
Lukasz Anforowicz0672f8a2017-11-30 01:07:0619#include "base/test/mock_log.h"
W. James MacLean24d534b2021-11-22 18:51:3520#include "base/test/scoped_command_line.h"
21#include "base/test/scoped_feature_list.h"
Lukasz Anforowicz38003582019-09-24 19:08:0522#include "build/build_config.h"
[email protected]b9535422012-02-09 01:47:5923#include "content/browser/child_process_security_policy_impl.h"
Andrew Stone6ed99b22019-06-07 06:14:3924#include "content/browser/isolated_origin_util.h"
W. James MacLean24d534b2021-11-22 18:51:3525#include "content/browser/origin_agent_cluster_isolation_state.h"
Sharon Yanga005ca12021-11-16 20:09:4226#include "content/browser/process_lock.h"
Sharon Yangd70a5392021-10-26 23:06:3227#include "content/browser/site_info.h"
Alex Moshchuk4e19b362018-09-10 21:14:3628#include "content/browser/site_instance_impl.h"
Sharon Yangc09c9e13f2022-12-16 04:40:2329#include "content/common/content_navigation_policy.h"
Alex Moshchuk5345a3f2023-04-03 23:36:3330#include "content/common/features.h"
Lei Zhangec78a312021-04-27 21:14:2631#include "content/public/browser/browser_task_traits.h"
Gabriel Charettee7cdc5cd2020-05-27 23:35:0532#include "content/public/browser/browser_thread.h"
W. James MacLean24d534b2021-11-22 18:51:3533#include "content/public/browser/site_isolation_policy.h"
Christopher Lama4dc3142018-06-01 03:17:0734#include "content/public/common/bindings_policy.h"
Hans Wennborg5ffd1392019-10-16 11:00:0235#include "content/public/common/content_client.h"
W. James MacLean5eaf0bd2024-06-26 21:15:3236#include "content/public/common/content_features.h"
W. James MacLean24d534b2021-11-22 18:51:3537#include "content/public/common/content_switches.h"
[email protected]a1d29162011-10-14 17:14:0338#include "content/public/common/url_constants.h"
Gabriel Charettec7108742019-08-23 03:31:4039#include "content/public/test/browser_task_environment.h"
Alex Moshchuk8e5c1952019-01-15 03:39:5040#include "content/public/test/test_browser_context.h"
Matt Siembor9cb08392019-04-24 21:34:3941#include "content/public/test/test_utils.h"
Robbie McElrath7d4bd852021-07-24 04:02:1942#include "content/test/storage_partition_test_helpers.h"
[email protected]c6681f32012-06-05 14:43:0143#include "content/test/test_content_browser_client.h"
Joel Hockey91f58d7aa2024-10-03 22:59:2144#include "net/base/filename_util.h"
DongJun Kimfebb3c22019-10-21 02:08:0645#include "storage/browser/file_system/file_permission_policy.h"
46#include "storage/browser/file_system/file_system_url.h"
47#include "storage/browser/file_system/isolated_context.h"
DongJun Kimd6930ea2019-10-24 08:49:2548#include "storage/common/file_system/file_system_types.h"
Lukasz Anforowicz0672f8a2017-11-30 01:07:0649#include "testing/gmock/include/gmock/gmock.h"
initial.commit09911bf2008-07-26 23:55:2950#include "testing/gtest/include/gtest/gtest.h"
Kyra Seevers86ecaf52021-07-13 13:48:1751#include "third_party/blink/public/common/storage_key/storage_key.h"
[email protected]707e1c42013-07-09 21:18:5852#include "url/gurl.h"
paulmeyer1eefa26e2015-10-01 02:11:1353#include "url/origin.h"
initial.commit09911bf2008-07-26 23:55:2954
[email protected]46488322012-10-30 03:22:2055namespace content {
[email protected]46fb9442011-12-09 17:57:4756namespace {
57
Alex Moshchukc4679422019-06-11 17:04:4858using IsolatedOriginSource = ChildProcessSecurityPolicy::IsolatedOriginSource;
59
[email protected]46fb9442011-12-09 17:57:4760const int kRendererID = 42;
[email protected]46fb9442011-12-09 17:57:4761
[email protected]f0ecca4522013-01-07 21:50:5662#if defined(FILE_PATH_USES_DRIVE_LETTERS)
63#define TEST_PATH(x) FILE_PATH_LITERAL("c:") FILE_PATH_LITERAL(x)
64#else
65#define TEST_PATH(x) FILE_PATH_LITERAL(x)
66#endif
67
[email protected]46fb9442011-12-09 17:57:4768class ChildProcessSecurityPolicyTestBrowserClient
[email protected]46488322012-10-30 03:22:2069 : public TestContentBrowserClient {
[email protected]46fb9442011-12-09 17:57:4770 public:
71 ChildProcessSecurityPolicyTestBrowserClient() {}
72
dchengc2282aa2014-10-21 12:07:5873 bool IsHandledURL(const GURL& url) override {
Ho Cheung9722cbb2023-09-07 17:36:5174 return base::Contains(schemes_, url.scheme());
[email protected]e3539402011-07-19 09:31:0875 }
76
[email protected]46fb9442011-12-09 17:57:4777 void ClearSchemes() {
78 schemes_.clear();
initial.commit09911bf2008-07-26 23:55:2979 }
[email protected]46fb9442011-12-09 17:57:4780
81 void AddScheme(const std::string& scheme) {
82 schemes_.insert(scheme);
83 }
84
85 private:
86 std::set<std::string> schemes_;
initial.commit09911bf2008-07-26 23:55:2987};
88
Lukasz Anforowicz38003582019-09-24 19:08:0589void LockProcessIfNeeded(int process_id,
90 BrowserContext* browser_context,
91 const GURL& url) {
92 scoped_refptr<SiteInstanceImpl> site_instance =
Alex Moshchukdf15d8e2022-02-01 04:43:4993 SiteInstanceImpl::CreateForTesting(browser_context, url);
Lukasz Anforowicz38003582019-09-24 19:08:0594 if (site_instance->RequiresDedicatedProcess() &&
Aaron Colwell8812a972020-10-02 23:36:5695 site_instance->GetSiteInfo().ShouldLockProcessToSite(
Aaron Colwellbb5c39f2020-10-14 23:55:4996 site_instance->GetIsolationContext())) {
W. James MacLeane84fa112020-07-14 17:25:5497 ChildProcessSecurityPolicyImpl::GetInstance()->LockProcess(
Charlie Reis47457a62022-05-18 21:57:3798 site_instance->GetIsolationContext(), process_id, false,
Sharon Yang2c077a72021-11-30 02:27:5899 ProcessLock::FromSiteInfo(site_instance->GetSiteInfo()));
Lukasz Anforowicz38003582019-09-24 19:08:05100 }
101}
102
[email protected]46fb9442011-12-09 17:57:47103} // namespace
104
Alex Moshchuk989aa22c2024-11-06 02:09:07105// Parameterize the tests to run with and without
106// features::kCommittedOriginEnforcements, for https://crbug.com/40148776.
107enum class ChildProcessSecurityPolicyTestCase {
108 kCommittedOriginEnforcementsDisabled,
109 kCommittedOriginEnforcementsEnabled,
110};
111class ChildProcessSecurityPolicyTest
112 : public testing::Test,
113 public ::testing::WithParamInterface<ChildProcessSecurityPolicyTestCase> {
[email protected]46fb9442011-12-09 17:57:47114 public:
Aaron Colwell220d5022019-01-16 04:56:55115 ChildProcessSecurityPolicyTest()
Gabriel Charette798fde72019-08-20 22:24:04116 : task_environment_(BrowserTaskEnvironment::REAL_IO_THREAD),
Alex Moshchuk71ca2902023-04-07 18:08:37117 old_browser_client_(nullptr) {
Alex Moshchuk989aa22c2024-11-06 02:09:07118 // Force committed origin tracking to always be performed, and enable the
119 // enforcements based on that tracking according to test parameterization.
120 feature_list_.InitWithFeatureStates(
121 {{features::kCommittedOriginEnforcements,
122 GetParam() == ChildProcessSecurityPolicyTestCase::
123 kCommittedOriginEnforcementsEnabled},
124 {features::kCommittedOriginTracking, true}});
125 }
126
127 static std::string DescribeParams(
128 const testing::TestParamInfo<ParamType>& info) {
129 return info.param == ChildProcessSecurityPolicyTestCase::
130 kCommittedOriginEnforcementsEnabled
131 ? "CommittedOriginEnforcementsEnabled"
132 : "CommittedOriginEnforcementsDisabled";
Alex Moshchuk71ca2902023-04-07 18:08:37133 }
[email protected]46fb9442011-12-09 17:57:47134
dchengfa85b152014-10-28 01:13:42135 void SetUp() override {
[email protected]eabbfb12013-04-05 23:28:35136 old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
[email protected]46fb9442011-12-09 17:57:47137
138 // Claim to always handle chrome:// URLs because the CPSP's notion of
139 // allowing WebUI bindings is hard-wired to this particular scheme.
[email protected]2d9748b22014-02-11 00:17:29140 test_browser_client_.AddScheme(kChromeUIScheme);
[email protected]e0f35c92013-05-08 16:04:34141
Joel Hockey91f58d7aa2024-10-03 22:59:21142 // Claim to always handle file:// and android content:// URLs like the
143 // browser would. net::URLRequest::IsHandledURL() no longer claims support
144 // for default protocols as this is the responsibility of the browser (which
145 // is responsible for adding the appropriate ProtocolHandler).
[email protected]cca6f392014-05-28 21:32:26146 test_browser_client_.AddScheme(url::kFileScheme);
Joel Hockey91f58d7aa2024-10-03 22:59:21147#if BUILDFLAG(IS_ANDROID)
148 test_browser_client_.AddScheme(url::kContentScheme);
149#endif
W. James MacLean24d534b2021-11-22 18:51:35150 SiteIsolationPolicy::DisableFlagCachingForTesting();
Alex Moshchuk71ca2902023-04-07 18:08:37151
152 auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
153 {
154 base::AutoLock lock(policy->lock_);
155 EXPECT_EQ(0u, policy->security_state_.size())
156 << "ChildProcessSecurityPolicy should not be tracking any processes "
157 << "at test startup. Some other test probably forgot to call "
158 << "Remove() at the end.";
159 }
[email protected]46fb9442011-12-09 17:57:47160 }
161
dchengfa85b152014-10-28 01:13:42162 void TearDown() override {
Nasko Oskovac3617e2022-12-15 21:38:41163 auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
164 {
165 base::AutoLock lock(policy->lock_);
166 EXPECT_EQ(0u, policy->security_state_.size())
167 << "ChildProcessSecurityPolicy should not be tracking any processes "
168 << "at test shutdown. Did you forget to call Remove() at the end of "
169 << "a test?";
170 }
[email protected]46fb9442011-12-09 17:57:47171 test_browser_client_.ClearSchemes();
[email protected]eabbfb12013-04-05 23:28:35172 SetBrowserClientForTesting(old_browser_client_);
[email protected]46fb9442011-12-09 17:57:47173 }
174
Alex Moshchuk8e5c1952019-01-15 03:39:50175 // Helpers to construct (key, value) entries used to validate the
176 // isolated_origins_ map. The key is a site URL, calculated from the
177 // provided origin, and the value is a list of IsolatedOriginEntries. These
178 // helpers are members of ChildProcessSecurityPolicyTest so they can access
179 // the private IsolatedOriginEntry struct.
180 using IsolatedOriginEntry =
181 ChildProcessSecurityPolicyImpl::IsolatedOriginEntry;
Alex Moshchuk331fa5f2021-03-10 06:16:59182 // Converts |browsing_instance_id|, |origin| -> (site_url, {entry}) where
183 // site_url is created from |origin|, and {entry} contains |origin|
184 // and |browsing_instance_id|.
Lukasz Anforowicz15ba43e2021-07-21 22:50:09185 auto GetIsolatedOriginEntry(BrowsingInstanceId browsing_instance_id,
Andrew Stone6ed99b22019-06-07 06:14:39186 const url::Origin& origin,
187 bool isolate_all_subdomains = false) {
188 return std::pair<GURL, std::vector<IsolatedOriginEntry>>(
Aaron Colwell9d0f9392021-02-11 21:51:52189 SiteInfo::GetSiteForOrigin(origin),
Alex Moshchuk99b795422019-03-07 00:27:32190 {IsolatedOriginEntry(
Alex Moshchuk331fa5f2021-03-10 06:16:59191 origin, true /* applies_to_future_browsing_instances */,
Lukasz Anforowicz15ba43e2021-07-21 22:50:09192 browsing_instance_id, nullptr, nullptr, isolate_all_subdomains,
193 IsolatedOriginSource::TEST)});
194 }
195 auto GetIsolatedOriginEntry(int browsing_instance_id,
196 const url::Origin& origin,
197 bool isolate_all_subdomains = false) {
198 return GetIsolatedOriginEntry(BrowsingInstanceId(browsing_instance_id),
199 origin, isolate_all_subdomains);
Alex Moshchuk331fa5f2021-03-10 06:16:59200 }
201 // Converts the provided params into a (site_url, {entry}) tuple, where
202 // site_url is created from |origin| and {entry} contains |origin| and
203 // matches the provided BrowserContext, BrowsingInstance ID, and whether the
204 // isolation applies to future BrowsingInstances.
205 auto GetIsolatedOriginEntry(BrowserContext* browser_context,
206 bool applies_to_future_browsing_instances,
Lukasz Anforowicz15ba43e2021-07-21 22:50:09207 BrowsingInstanceId browsing_instance_id,
Alex Moshchuk331fa5f2021-03-10 06:16:59208 const url::Origin& origin) {
209 return std::pair<GURL, std::vector<IsolatedOriginEntry>>(
210 SiteInfo::GetSiteForOrigin(origin),
211 {IsolatedOriginEntry(
Lukasz Anforowicz15ba43e2021-07-21 22:50:09212 origin, applies_to_future_browsing_instances, browsing_instance_id,
Alex Moshchuk331fa5f2021-03-10 06:16:59213 browser_context,
214 browser_context ? browser_context->GetResourceContext() : nullptr,
215 false /* isolate_all_subdomains */, IsolatedOriginSource::TEST)});
Alex Moshchuk8e5c1952019-01-15 03:39:50216 }
217 // Converts |origin| -> (site_url, {entry})
218 // where site_url is created from |origin| and
219 // entry contains |origin| and the latest BrowsingInstance ID.
Andrew Stone6ed99b22019-06-07 06:14:39220 auto GetIsolatedOriginEntry(const url::Origin& origin,
221 bool isolate_all_subdomains = false) {
Lukasz Anforowicz15ba43e2021-07-21 22:50:09222 return GetIsolatedOriginEntry(SiteInstanceImpl::NextBrowsingInstanceId(),
223 origin, isolate_all_subdomains);
Alex Moshchuk8e5c1952019-01-15 03:39:50224 }
225 // Converts |origin1|, |origin2| -> (site_url, {entry1, entry2})
226 // where |site_url| is created from |origin1|, but is assumed to be the
227 // same for |origin2| (i.e., |origin1| and |origin2| are
228 // same-site),
229 // entry1 contains |origin1| and the latest BrowsingInstance ID,
230 // entry2 contains |origin2| and the latest BrowsingInstance ID.
231 auto GetIsolatedOriginEntry(const url::Origin& origin1,
Andrew Stone6ed99b22019-06-07 06:14:39232 const url::Origin& origin2,
233 bool origin1_isolate_all_subdomains = false,
234 bool origin2_isolate_all_subdomains = false) {
Aaron Colwell9d0f9392021-02-11 21:51:52235 EXPECT_EQ(SiteInfo::GetSiteForOrigin(origin1),
236 SiteInfo::GetSiteForOrigin(origin2));
Andrew Stone6ed99b22019-06-07 06:14:39237 return std::pair<GURL, std::vector<IsolatedOriginEntry>>(
Aaron Colwell9d0f9392021-02-11 21:51:52238 SiteInfo::GetSiteForOrigin(origin1),
Alex Moshchuk331fa5f2021-03-10 06:16:59239 {IsolatedOriginEntry(
240 origin1, true /* applies_to_future_browsing_contexts */,
241 SiteInstanceImpl::NextBrowsingInstanceId(), nullptr, nullptr,
242 origin1_isolate_all_subdomains, IsolatedOriginSource::TEST),
243 IsolatedOriginEntry(
244 origin2, true /* applies_to_future_browsing_contexts */,
245 SiteInstanceImpl::NextBrowsingInstanceId(), nullptr, nullptr,
246 origin2_isolate_all_subdomains, IsolatedOriginSource::TEST)});
Alex Moshchuk8e5c1952019-01-15 03:39:50247 }
248
Alex Moshchuk99b795422019-03-07 00:27:32249 bool IsIsolatedOrigin(BrowserContext* context,
250 int browsing_instance_id,
251 const url::Origin& origin) {
Lukasz Anforowicz15ba43e2021-07-21 22:50:09252 return IsIsolatedOrigin(context, BrowsingInstanceId(browsing_instance_id),
253 origin);
Alex Moshchuk331fa5f2021-03-10 06:16:59254 }
255
256 bool IsIsolatedOrigin(BrowserContext* context,
257 BrowsingInstanceId browsing_instance_id,
258 const url::Origin& origin) {
Alex Moshchuk8e5c1952019-01-15 03:39:50259 ChildProcessSecurityPolicyImpl* p =
260 ChildProcessSecurityPolicyImpl::GetInstance();
Adithya Srinivasanf6377b12022-08-31 21:58:44261 return p->IsIsolatedOrigin(
W. James MacLeane66843c2023-04-26 19:15:57262 IsolationContext(
263 browsing_instance_id, context,
264 /*is_guest=*/false, /*is_fenced=*/false,
265 OriginAgentClusterIsolationState::CreateForDefaultIsolation(
266 &browser_context_)),
Adithya Srinivasanf6377b12022-08-31 21:58:44267 origin, false /* origin_requests_isolation */);
Alex Moshchuk8e5c1952019-01-15 03:39:50268 }
269
Alex Moshchuk99b795422019-03-07 00:27:32270 // Returns the number of isolated origin entries for a particular origin.
271 // There may be more than one such entry if each is associated with a
272 // different profile.
273 int GetIsolatedOriginEntryCount(const url::Origin& origin) {
274 ChildProcessSecurityPolicyImpl* p =
275 ChildProcessSecurityPolicyImpl::GetInstance();
Aaron Colwell9d0f9392021-02-11 21:51:52276 GURL key(SiteInfo::GetSiteForOrigin(origin));
Alex Moshchuk99b795422019-03-07 00:27:32277 base::AutoLock isolated_origins_lock(p->isolated_origins_lock_);
278 auto origins_for_key = p->isolated_origins_[key];
Peter Kasting1557e5f2025-01-28 01:14:08279 return std::ranges::count(origins_for_key, origin,
280 &IsolatedOriginEntry::origin);
Alex Moshchuk99b795422019-03-07 00:27:32281 }
282
Andrew Stone6ed99b22019-06-07 06:14:39283 void CheckGetSiteForURL(BrowserContext* context,
284 std::map<GURL, GURL> to_test) {
285 for (const auto& entry : to_test) {
Aaron Colwell9d0f9392021-02-11 21:51:52286 auto site_info =
287 SiteInfo::CreateForTesting(IsolationContext(context), entry.first);
288 EXPECT_EQ(site_info.site_url(), entry.second);
Andrew Stone6ed99b22019-06-07 06:14:39289 }
290 }
291
[email protected]46fb9442011-12-09 17:57:47292 protected:
293 void RegisterTestScheme(const std::string& scheme) {
294 test_browser_client_.AddScheme(scheme);
295 }
296
[email protected]bfcf1e92013-07-11 04:37:25297 void GrantPermissionsForFile(ChildProcessSecurityPolicyImpl* p,
298 int child_id,
299 const base::FilePath& file,
300 int permissions) {
301 p->GrantPermissionsForFile(child_id, file, permissions);
302 }
303
[email protected]5a65fde32013-10-22 05:15:34304 void CheckHasNoFileSystemPermission(ChildProcessSecurityPolicyImpl* p,
305 const std::string& child_id) {
306 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, child_id));
307 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, child_id));
308 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, child_id));
309 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, child_id));
310 }
311
312 void CheckHasNoFileSystemFilePermission(ChildProcessSecurityPolicyImpl* p,
313 const base::FilePath& file,
[email protected]cd501a72014-08-22 19:58:31314 const storage::FileSystemURL& url) {
[email protected]5a65fde32013-10-22 05:15:34315 EXPECT_FALSE(p->CanReadFile(kRendererID, file));
316 EXPECT_FALSE(p->CanCreateReadWriteFile(kRendererID, file));
317 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url));
318 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
319 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
320 EXPECT_FALSE(p->CanCreateReadWriteFileSystemFile(kRendererID, url));
321 EXPECT_FALSE(p->CanCopyIntoFileSystemFile(kRendererID, url));
322 EXPECT_FALSE(p->CanDeleteFileSystemFile(kRendererID, url));
Aaron Colwell4fcbe4152020-01-16 07:10:59323
324 auto handle = p->CreateHandle(kRendererID);
325 EXPECT_FALSE(handle.CanReadFile(file));
326 EXPECT_FALSE(handle.CanReadFileSystemFile(url));
[email protected]5a65fde32013-10-22 05:15:34327 }
328
Aaron Colwellea6921f2019-01-29 16:50:39329 BrowserContext* browser_context() { return &browser_context_; }
330
[email protected]46fb9442011-12-09 17:57:47331 private:
Gabriel Charette798fde72019-08-20 22:24:04332 BrowserTaskEnvironment task_environment_;
Aaron Colwellea6921f2019-01-29 16:50:39333 TestBrowserContext browser_context_;
[email protected]46fb9442011-12-09 17:57:47334 ChildProcessSecurityPolicyTestBrowserClient test_browser_client_;
Keishi Hattori0e45c022021-11-27 09:25:52335 raw_ptr<ContentBrowserClient> old_browser_client_;
Alex Moshchuk989aa22c2024-11-06 02:09:07336 base::test::ScopedFeatureList feature_list_;
[email protected]46fb9442011-12-09 17:57:47337};
initial.commit09911bf2008-07-26 23:55:29338
W. James MacLean5eaf0bd2024-06-26 21:15:32339// A test class that forces kOriginKeyedProcessesByDefault off in
340// ChildProcessSecurityPolicyTest. Used for tests that are trying to verify
341// behavior that is inconsistent with Origin Isolation.
342class ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault
343 : public ChildProcessSecurityPolicyTest {
344 public:
345 ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault() {
346 feature_list_.InitAndDisableFeature(
347 features::kOriginKeyedProcessesByDefault);
348 }
349
350 private:
351 base::test::ScopedFeatureList feature_list_;
352};
353
Alex Moshchuk989aa22c2024-11-06 02:09:07354TEST_P(ChildProcessSecurityPolicyTest, ChildID) {
Ari Chivukulaccb16aeb2021-10-01 01:47:12355 ChildProcessSecurityPolicyImpl* p =
356 ChildProcessSecurityPolicyImpl::GetInstance();
357 p->AddForTesting(kRendererID, browser_context());
358 auto handle = p->CreateHandle(kRendererID);
359 EXPECT_EQ(handle.child_id(), kRendererID);
Eric Lawrence66600a652021-11-11 18:01:32360 p->Remove(kRendererID);
Ari Chivukulaccb16aeb2021-10-01 01:47:12361}
[email protected]9f104312013-07-23 23:18:19362
Alex Moshchuk989aa22c2024-11-06 02:09:07363TEST_P(ChildProcessSecurityPolicyTest, IsWebSafeSchemeTest) {
[email protected]b9535422012-02-09 01:47:59364 ChildProcessSecurityPolicyImpl* p =
365 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29366
[email protected]e8ca69c2014-05-07 15:31:19367 EXPECT_TRUE(p->IsWebSafeScheme(url::kHttpScheme));
368 EXPECT_TRUE(p->IsWebSafeScheme(url::kHttpsScheme));
[email protected]cca6f392014-05-28 21:32:26369 EXPECT_TRUE(p->IsWebSafeScheme(url::kDataScheme));
[email protected]cca6f392014-05-28 21:32:26370 EXPECT_TRUE(p->IsWebSafeScheme(url::kBlobScheme));
371 EXPECT_TRUE(p->IsWebSafeScheme(url::kFileSystemScheme));
initial.commit09911bf2008-07-26 23:55:29372
373 EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme"));
374 p->RegisterWebSafeScheme("registered-web-safe-scheme");
375 EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme"));
[email protected]89f550b2011-06-08 18:34:03376
[email protected]2d9748b22014-02-11 00:17:29377 EXPECT_FALSE(p->IsWebSafeScheme(kChromeUIScheme));
Alex Moshchuk71ca2902023-04-07 18:08:37378
379 p->ClearRegisteredSchemeForTesting("registered-web-safe-scheme");
initial.commit09911bf2008-07-26 23:55:29380}
381
Alex Moshchuk989aa22c2024-11-06 02:09:07382TEST_P(ChildProcessSecurityPolicyTest, IsPseudoSchemeTest) {
[email protected]b9535422012-02-09 01:47:59383 ChildProcessSecurityPolicyImpl* p =
384 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29385
[email protected]8e09c7af2014-06-10 11:46:17386 EXPECT_TRUE(p->IsPseudoScheme(url::kAboutScheme));
[email protected]cca6f392014-05-28 21:32:26387 EXPECT_TRUE(p->IsPseudoScheme(url::kJavaScriptScheme));
[email protected]dbdda5402013-05-30 22:13:48388 EXPECT_TRUE(p->IsPseudoScheme(kViewSourceScheme));
Mike Westb96a52a2019-07-24 17:08:50389 EXPECT_TRUE(p->IsPseudoScheme(kGoogleChromeScheme));
initial.commit09911bf2008-07-26 23:55:29390
[email protected]419a0572011-04-18 22:21:46391 EXPECT_FALSE(p->IsPseudoScheme("registered-pseudo-scheme"));
392 p->RegisterPseudoScheme("registered-pseudo-scheme");
393 EXPECT_TRUE(p->IsPseudoScheme("registered-pseudo-scheme"));
[email protected]89f550b2011-06-08 18:34:03394
[email protected]2d9748b22014-02-11 00:17:29395 EXPECT_FALSE(p->IsPseudoScheme(kChromeUIScheme));
Alex Moshchuk71ca2902023-04-07 18:08:37396
397 p->ClearRegisteredSchemeForTesting("registered-pseudo-scheme");
[email protected]419a0572011-04-18 22:21:46398}
399
Alex Moshchuk989aa22c2024-11-06 02:09:07400TEST_P(ChildProcessSecurityPolicyTest, StandardSchemesTest) {
[email protected]b9535422012-02-09 01:47:59401 ChildProcessSecurityPolicyImpl* p =
402 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29403
Aaron Colwellffade2a2020-09-16 20:54:41404 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:29405
Aaron Colwell4fcbe4152020-01-16 07:10:59406 auto handle = p->CreateHandle(kRendererID);
407
arthursonzogni98e5a232017-07-13 15:18:16408 // Safe to request, redirect or commit.
initial.commit09911bf2008-07-26 23:55:29409 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/")));
410 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/")));
initial.commit09911bf2008-07-26 23:55:29411 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,<b>Hi</b>")));
[email protected]039c7b0b22011-03-04 23:15:42412 EXPECT_TRUE(p->CanRequestURL(
413 kRendererID, GURL("filesystem:http://localhost/temporary/a.gif")));
arthursonzogni98e5a232017-07-13 15:18:16414 EXPECT_TRUE(p->CanRedirectToURL(GURL("http://www.google.com/")));
415 EXPECT_TRUE(p->CanRedirectToURL(GURL("https://www.paypal.com/")));
arthursonzogni98e5a232017-07-13 15:18:16416 EXPECT_TRUE(p->CanRedirectToURL(GURL("data:text/html,<b>Hi</b>")));
417 EXPECT_TRUE(
418 p->CanRedirectToURL(GURL("filesystem:http://localhost/temporary/a.gif")));
Aaron Colwell4fcbe4152020-01-16 07:10:59419
420 const std::vector<std::string> kCommitURLs({
421 "http://www.google.com/",
422 "https://www.paypal.com/",
Aaron Colwell4fcbe4152020-01-16 07:10:59423 "filesystem:http://localhost/temporary/a.gif",
424 });
Nico Weber6dcde5b2020-02-22 20:49:20425 for (const auto& url_string : kCommitURLs) {
Aaron Colwell4fcbe4152020-01-16 07:10:59426 const GURL commit_url(url_string);
Ari Chivukula03059192024-09-24 00:45:48427 if (AreAllSitesIsolatedForTesting()) {
Aaron Colwell4fcbe4152020-01-16 07:10:59428 // A non-locked process cannot access URL (because with
429 // site-per-process all the URLs need to be isolated).
430 EXPECT_FALSE(p->CanCommitURL(kRendererID, commit_url)) << commit_url;
Aaron Colwell4fcbe4152020-01-16 07:10:59431 } else {
432 EXPECT_TRUE(p->CanCommitURL(kRendererID, commit_url)) << commit_url;
Aaron Colwell4fcbe4152020-01-16 07:10:59433 }
Lukasz Anforowicz38003582019-09-24 19:08:05434 }
initial.commit09911bf2008-07-26 23:55:29435
Ari Chivukula03059192024-09-24 00:45:48436 // A data URL can commit in any process.
Charlie Reisc8e511e2024-02-14 17:23:06437 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("data:text/html,<b>Hi</b>")));
438
jww2cdad9e2016-09-24 05:42:02439 // Dangerous to request, commit, or set as origin header.
initial.commit09911bf2008-07-26 23:55:29440 EXPECT_FALSE(p->CanRequestURL(kRendererID,
441 GURL("file:///etc/passwd")));
Matt Siembor9cb08392019-04-24 21:34:39442 EXPECT_FALSE(p->CanRequestURL(kRendererID, GetWebUIURL("foo/bar")));
meacerce6b66032016-06-02 20:56:05443 EXPECT_FALSE(p->CanRequestURL(kRendererID,
444 GURL("view-source:http://www.google.com/")));
arthursonzogni98e5a232017-07-13 15:18:16445 EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
Matt Siembor9cb08392019-04-24 21:34:39446 EXPECT_TRUE(p->CanRedirectToURL(GetWebUIURL("foo/bar")));
arthursonzogni98e5a232017-07-13 15:18:16447 EXPECT_FALSE(p->CanRedirectToURL(GURL("view-source:http://www.google.com/")));
Alex Moshchuk71f485592017-08-16 16:20:00448 EXPECT_FALSE(p->CanRedirectToURL(GURL(kUnreachableWebDataURL)));
Aaron Colwell4fcbe4152020-01-16 07:10:59449
450 const std::vector<std::string> kFailedCommitURLs(
451 {"file:///etc/passwd", "view-source:http://www.google.com/",
452 kUnreachableWebDataURL, GetWebUIURL("foo/bar").spec()});
Nico Weber6dcde5b2020-02-22 20:49:20453 for (const auto& url_string : kFailedCommitURLs) {
Aaron Colwell4fcbe4152020-01-16 07:10:59454 const GURL commit_url(url_string);
455 EXPECT_FALSE(p->CanCommitURL(kRendererID, commit_url)) << commit_url;
Aaron Colwell4fcbe4152020-01-16 07:10:59456 }
initial.commit09911bf2008-07-26 23:55:29457
458 p->Remove(kRendererID);
459}
460
Alex Moshchuk989aa22c2024-11-06 02:09:07461TEST_P(ChildProcessSecurityPolicyTest, BlobSchemeTest) {
nicka76cc402016-09-22 20:02:59462 ChildProcessSecurityPolicyImpl* p =
463 ChildProcessSecurityPolicyImpl::GetInstance();
464
Lukasz Anforowicz38003582019-09-24 19:08:05465 GURL localhost_url("http://localhost/");
Aaron Colwellffade2a2020-09-16 20:54:41466 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:05467 LockProcessIfNeeded(kRendererID, browser_context(), localhost_url);
nicka76cc402016-09-22 20:02:59468
469 EXPECT_TRUE(
470 p->CanRequestURL(kRendererID, GURL("blob:http://localhost/some-guid")));
471 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("blob:null/some-guid")));
472 EXPECT_TRUE(
473 p->CanRequestURL(kRendererID, GURL("blob:http://localhost/some-guid")));
474 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("blob:NulL/some-guid")));
475 EXPECT_TRUE(
476 p->CanRequestURL(kRendererID, GURL("blob:NulL/some-guid#fragment")));
477 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("blob:NulL/some-guid?query")));
nicka76cc402016-09-22 20:02:59478 EXPECT_FALSE(p->CanRequestURL(
479 kRendererID, GURL("blob:http://username@localhost/some-guid")));
480 EXPECT_FALSE(p->CanRequestURL(
481 kRendererID, GURL("blob:http://username @localhost/some-guid")));
482 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("blob:blob:some-guid")));
483 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("blob:some-guid")));
484 EXPECT_FALSE(p->CanRequestURL(kRendererID,
485 GURL("blob:filesystem:http://localhost/path")));
486 EXPECT_FALSE(p->CanRequestURL(kRendererID,
487 GURL("filesystem:blob:http://localhost/guid")));
488
arthursonzogni98e5a232017-07-13 15:18:16489 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:http://localhost/some-guid")));
490 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:null/some-guid")));
491 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:http://localhost/some-guid")));
492 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:NulL/some-guid")));
493 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:NulL/some-guid#fragment")));
494 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:NulL/some-guid?query")));
arthursonzogni98e5a232017-07-13 15:18:16495 EXPECT_TRUE(
496 p->CanRedirectToURL(GURL("blob:http://username@localhost/some-guid")));
497 EXPECT_TRUE(p->CanRedirectToURL(
498 GURL("blob:http://username @localhost/some-guid")));
499 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:blob:some-guid")));
500 EXPECT_TRUE(p->CanRedirectToURL(GURL("blob:some-guid")));
501 EXPECT_TRUE(
502 p->CanRedirectToURL(GURL("blob:filesystem:http://localhost/path")));
503 EXPECT_FALSE(
504 p->CanRedirectToURL(GURL("filesystem:blob:http://localhost/guid")));
505
nicka76cc402016-09-22 20:02:59506 EXPECT_TRUE(
507 p->CanCommitURL(kRendererID, GURL("blob:http://localhost/some-guid")));
508 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("blob:null/some-guid")));
509 EXPECT_TRUE(
510 p->CanCommitURL(kRendererID, GURL("blob:http://localhost/some-guid")));
511 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("blob:NulL/some-guid")));
512 EXPECT_TRUE(
513 p->CanCommitURL(kRendererID, GURL("blob:NulL/some-guid#fragment")));
nicka76cc402016-09-22 20:02:59514 EXPECT_FALSE(p->CanCommitURL(
515 kRendererID, GURL("blob:http://username@localhost/some-guid")));
516 EXPECT_FALSE(p->CanCommitURL(
517 kRendererID, GURL("blob:http://username @localhost/some-guid")));
518 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("blob:blob:some-guid")));
519 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("blob:some-guid")));
520 EXPECT_FALSE(p->CanCommitURL(kRendererID,
521 GURL("blob:filesystem:http://localhost/path")));
522 EXPECT_FALSE(p->CanCommitURL(kRendererID,
523 GURL("filesystem:blob:http://localhost/guid")));
524
525 p->Remove(kRendererID);
526}
527
Alex Moshchuk989aa22c2024-11-06 02:09:07528TEST_P(ChildProcessSecurityPolicyTest, AboutTest) {
[email protected]b9535422012-02-09 01:47:59529 ChildProcessSecurityPolicyImpl* p =
530 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29531
Aaron Colwellffade2a2020-09-16 20:54:41532 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:29533
534 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank")));
arthursonzogniee7f43b2016-12-06 10:52:29535 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:BlAnK")));
536 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK")));
initial.commit09911bf2008-07-26 23:55:29537 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank")));
arthursonzogni98e5a232017-07-13 15:18:16538 EXPECT_TRUE(p->CanRedirectToURL(GURL("about:blank")));
539 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:BlAnK")));
540 EXPECT_FALSE(p->CanRedirectToURL(GURL("aBouT:BlAnK")));
541 EXPECT_TRUE(p->CanRedirectToURL(GURL("aBouT:blank")));
creis3710b2382015-08-18 00:12:15542 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("about:blank")));
arthursonzogniee7f43b2016-12-06 10:52:29543 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:BlAnK")));
544 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("aBouT:BlAnK")));
creis3710b2382015-08-18 00:12:15545 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("aBouT:blank")));
initial.commit09911bf2008-07-26 23:55:29546
arthursonzogniee7f43b2016-12-06 10:52:29547 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:srcdoc")));
arthursonzogni98e5a232017-07-13 15:18:16548 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:srcdoc")));
arthursonzogniee7f43b2016-12-06 10:52:29549 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("about:srcdoc")));
arthursonzogniee7f43b2016-12-06 10:52:29550 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:SRCDOC")));
551 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:SRCDOC")));
arthursonzogniee7f43b2016-12-06 10:52:29552
[email protected]ed3456f2009-02-26 20:24:48553 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash")));
554 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache")));
555 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang")));
asvitkine2c4b4d1a2016-03-19 14:18:07556 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:version")));
arthursonzogni98e5a232017-07-13 15:18:16557 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:crash")));
558 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:cache")));
559 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:hang")));
560 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:version")));
creis3710b2382015-08-18 00:12:15561 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:crash")));
562 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:cache")));
563 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:hang")));
asvitkine2c4b4d1a2016-03-19 14:18:07564 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:version")));
initial.commit09911bf2008-07-26 23:55:29565
asvitkine2c4b4d1a2016-03-19 14:18:07566 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:version")));
initial.commit09911bf2008-07-26 23:55:29567 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh")));
568 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe")));
arthursonzogni98e5a232017-07-13 15:18:16569 EXPECT_FALSE(p->CanRedirectToURL(GURL("aBoUt:version")));
570 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:CrASh")));
571 EXPECT_FALSE(p->CanRedirectToURL(GURL("abOuT:cAChe")));
asvitkine2c4b4d1a2016-03-19 14:18:07572 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("aBoUt:version")));
creis3710b2382015-08-18 00:12:15573 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:CrASh")));
574 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("abOuT:cAChe")));
asvitkine2c4b4d1a2016-03-19 14:18:07575 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("aBoUt:version")));
initial.commit09911bf2008-07-26 23:55:29576
[email protected]8bf1048012012-02-08 01:22:18577 // Requests for about: pages should be denied.
Daniel Cheng4ebba552018-07-06 21:43:16578 p->GrantCommitURL(kRendererID, GURL("about:crash"));
[email protected]8bf1048012012-02-08 01:22:18579 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash")));
arthursonzogni98e5a232017-07-13 15:18:16580 EXPECT_FALSE(p->CanRedirectToURL(GURL("about:crash")));
creis3710b2382015-08-18 00:12:15581 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:crash")));
initial.commit09911bf2008-07-26 23:55:29582
583 p->Remove(kRendererID);
584}
585
Alex Moshchuk989aa22c2024-11-06 02:09:07586TEST_P(ChildProcessSecurityPolicyTest, JavaScriptTest) {
[email protected]b9535422012-02-09 01:47:59587 ChildProcessSecurityPolicyImpl* p =
588 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29589
Aaron Colwellffade2a2020-09-16 20:54:41590 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:29591
592 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
arthursonzogni98e5a232017-07-13 15:18:16593 EXPECT_FALSE(p->CanRedirectToURL(GURL("javascript:alert('xss')")));
creis3710b2382015-08-18 00:12:15594 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("javascript:alert('xss')")));
Daniel Cheng4ebba552018-07-06 21:43:16595 p->GrantCommitURL(kRendererID, GURL("javascript:alert('xss')"));
initial.commit09911bf2008-07-26 23:55:29596 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
arthursonzogni98e5a232017-07-13 15:18:16597 EXPECT_FALSE(p->CanRedirectToURL(GURL("javascript:alert('xss')")));
creis3710b2382015-08-18 00:12:15598 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("javascript:alert('xss')")));
jww2cdad9e2016-09-24 05:42:02599
600 p->Remove(kRendererID);
601}
602
Alex Moshchuk989aa22c2024-11-06 02:09:07603TEST_P(ChildProcessSecurityPolicyTest, RegisterWebSafeSchemeTest) {
[email protected]b9535422012-02-09 01:47:59604 ChildProcessSecurityPolicyImpl* p =
605 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29606
Aaron Colwellffade2a2020-09-16 20:54:41607 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:29608
creis3710b2382015-08-18 00:12:15609 // Currently, "asdf" is destined for ShellExecute, so it is allowed to be
610 // requested but not committed.
initial.commit09911bf2008-07-26 23:55:29611 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));
arthursonzogni98e5a232017-07-13 15:18:16612 EXPECT_TRUE(p->CanRedirectToURL(GURL("asdf:rockers")));
creis3710b2382015-08-18 00:12:15613 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("asdf:rockers")));
initial.commit09911bf2008-07-26 23:55:29614
[email protected]46fb9442011-12-09 17:57:47615 // Once we register "asdf", we default to deny.
616 RegisterTestScheme("asdf");
initial.commit09911bf2008-07-26 23:55:29617 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));
arthursonzogni98e5a232017-07-13 15:18:16618 EXPECT_TRUE(p->CanRedirectToURL(GURL("asdf:rockers")));
creis3710b2382015-08-18 00:12:15619 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("asdf:rockers")));
initial.commit09911bf2008-07-26 23:55:29620
621 // We can allow new schemes by adding them to the whitelist.
622 p->RegisterWebSafeScheme("asdf");
623 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));
arthursonzogni98e5a232017-07-13 15:18:16624 EXPECT_TRUE(p->CanRedirectToURL(GURL("asdf:rockers")));
Ari Chivukula03059192024-09-24 00:45:48625 if (AreAllSitesIsolatedForTesting()) {
Lukasz Anforowicz38003582019-09-24 19:08:05626 // With site-per-process, all URLs (including the one below) will ask to be
627 // hosted in isolated processes. Since |p| is not locked, CanCommitURL
628 // should return false.
629 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("asdf:rockers")));
630
631 // After locking the process, CanCommitURL should start returning true.
632 LockProcessIfNeeded(kRendererID, browser_context(), GURL("asdf:rockers"));
633 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("asdf:rockers")));
634 } else {
635 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("asdf:rockers")));
636 }
initial.commit09911bf2008-07-26 23:55:29637
638 // Cleanup.
initial.commit09911bf2008-07-26 23:55:29639 p->Remove(kRendererID);
Alex Moshchuk71ca2902023-04-07 18:08:37640 p->ClearRegisteredSchemeForTesting("asdf");
initial.commit09911bf2008-07-26 23:55:29641}
642
Alex Moshchuk989aa22c2024-11-06 02:09:07643TEST_P(ChildProcessSecurityPolicyTest, CanServiceCommandsTest) {
[email protected]b9535422012-02-09 01:47:59644 ChildProcessSecurityPolicyImpl* p =
645 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29646
Lukasz Anforowicz38003582019-09-24 19:08:05647 GURL file_url("file:///etc/passwd");
Aaron Colwellffade2a2020-09-16 20:54:41648 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:05649 LockProcessIfNeeded(kRendererID, browser_context(), file_url);
initial.commit09911bf2008-07-26 23:55:29650
651 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
arthursonzogni98e5a232017-07-13 15:18:16652 EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
creis3710b2382015-08-18 00:12:15653 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
Daniel Cheng4ebba552018-07-06 21:43:16654 p->GrantCommitURL(kRendererID, GURL("file:///etc/passwd"));
initial.commit09911bf2008-07-26 23:55:29655 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
arthursonzogni98e5a232017-07-13 15:18:16656 EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
creis3710b2382015-08-18 00:12:15657 EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
initial.commit09911bf2008-07-26 23:55:29658
659 // We should forget our state if we repeat a renderer id.
660 p->Remove(kRendererID);
Aaron Colwellffade2a2020-09-16 20:54:41661 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:29662 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
arthursonzogni98e5a232017-07-13 15:18:16663 EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
creis3710b2382015-08-18 00:12:15664 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
initial.commit09911bf2008-07-26 23:55:29665 p->Remove(kRendererID);
666}
667
Alex Moshchuk989aa22c2024-11-06 02:09:07668TEST_P(ChildProcessSecurityPolicyTest, ViewSource) {
[email protected]b9535422012-02-09 01:47:59669 ChildProcessSecurityPolicyImpl* p =
670 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29671
Aaron Colwellffade2a2020-09-16 20:54:41672 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:29673
meacerce6b66032016-06-02 20:56:05674 // Child processes cannot request view source URLs.
675 EXPECT_FALSE(p->CanRequestURL(kRendererID,
676 GURL("view-source:http://www.google.com/")));
initial.commit09911bf2008-07-26 23:55:29677 EXPECT_FALSE(p->CanRequestURL(kRendererID,
678 GURL("view-source:file:///etc/passwd")));
679 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
[email protected]690d0a9172010-01-06 00:19:36680 EXPECT_FALSE(p->CanRequestURL(
681 kRendererID, GURL("view-source:view-source:http://www.google.com/")));
initial.commit09911bf2008-07-26 23:55:29682
arthursonzogni98e5a232017-07-13 15:18:16683 // Child processes cannot be redirected to view source URLs.
684 EXPECT_FALSE(p->CanRedirectToURL(GURL("view-source:http://www.google.com/")));
685 EXPECT_FALSE(p->CanRedirectToURL(GURL("view-source:file:///etc/passwd")));
686 EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
687 EXPECT_FALSE(p->CanRedirectToURL(
688 GURL("view-source:view-source:http://www.google.com/")));
689
creis3710b2382015-08-18 00:12:15690 // View source URLs don't actually commit; the renderer is put into view
691 // source mode, and the inner URL commits.
692 EXPECT_FALSE(p->CanCommitURL(kRendererID,
693 GURL("view-source:http://www.google.com/")));
694 EXPECT_FALSE(p->CanCommitURL(kRendererID,
695 GURL("view-source:file:///etc/passwd")));
696 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
697 EXPECT_FALSE(p->CanCommitURL(
698 kRendererID, GURL("view-source:view-source:http://www.google.com/")));
699
Daniel Cheng4ebba552018-07-06 21:43:16700 p->GrantCommitURL(kRendererID, GURL("view-source:file:///etc/passwd"));
meacerce6b66032016-06-02 20:56:05701 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
arthursonzogni98e5a232017-07-13 15:18:16702 EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
meacerce6b66032016-06-02 20:56:05703 EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
704 EXPECT_FALSE(
705 p->CanRequestURL(kRendererID, GURL("view-source:file:///etc/passwd")));
arthursonzogni98e5a232017-07-13 15:18:16706 EXPECT_FALSE(p->CanRedirectToURL(GURL("view-source:file:///etc/passwd")));
creis3710b2382015-08-18 00:12:15707 EXPECT_FALSE(p->CanCommitURL(kRendererID,
708 GURL("view-source:file:///etc/passwd")));
initial.commit09911bf2008-07-26 23:55:29709 p->Remove(kRendererID);
710}
711
Alex Moshchuk989aa22c2024-11-06 02:09:07712TEST_P(ChildProcessSecurityPolicyTest, GoogleChromeScheme) {
Mike Westb96a52a2019-07-24 17:08:50713 ChildProcessSecurityPolicyImpl* p =
714 ChildProcessSecurityPolicyImpl::GetInstance();
715
Aaron Colwellffade2a2020-09-16 20:54:41716 p->AddForTesting(kRendererID, browser_context());
Mike Westb96a52a2019-07-24 17:08:50717
718 GURL test_url("googlechrome://whatever");
719
720 EXPECT_FALSE(p->CanRequestURL(kRendererID, test_url));
721 EXPECT_FALSE(p->CanRedirectToURL(test_url));
722 EXPECT_FALSE(p->CanCommitURL(kRendererID, test_url));
Mike Westb96a52a2019-07-24 17:08:50723
724 p->Remove(kRendererID);
725}
726
Alex Moshchuk989aa22c2024-11-06 02:09:07727TEST_P(ChildProcessSecurityPolicyTest, GrantCommitURLToNonStandardScheme) {
Daniel Cheng4ebba552018-07-06 21:43:16728 ChildProcessSecurityPolicyImpl* p =
729 ChildProcessSecurityPolicyImpl::GetInstance();
730
731 const GURL url("httpxml://awesome");
732 const GURL url2("httpxml://also-awesome");
733
Chris Palmerab5e5b52018-09-28 19:19:30734 ASSERT_TRUE(url::Origin::Create(url).opaque());
735 ASSERT_TRUE(url::Origin::Create(url2).opaque());
Daniel Cheng4ebba552018-07-06 21:43:16736 RegisterTestScheme("httpxml");
737
Aaron Colwellffade2a2020-09-16 20:54:41738 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:05739 LockProcessIfNeeded(kRendererID, browser_context(), url);
Daniel Cheng4ebba552018-07-06 21:43:16740
741 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
742 EXPECT_FALSE(p->CanRequestURL(kRendererID, url2));
743 EXPECT_TRUE(p->CanRedirectToURL(url));
744 EXPECT_TRUE(p->CanRedirectToURL(url2));
745 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
746 EXPECT_FALSE(p->CanCommitURL(kRendererID, url2));
Daniel Cheng4ebba552018-07-06 21:43:16747
748 // GrantCommitURL with a non-standard scheme should grant commit access to the
749 // entire scheme.
750 p->GrantCommitURL(kRendererID, url);
751
752 EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
753 EXPECT_TRUE(p->CanRequestURL(kRendererID, url2));
754 EXPECT_TRUE(p->CanRedirectToURL(url));
755 EXPECT_TRUE(p->CanRedirectToURL(url2));
756 EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
757 EXPECT_TRUE(p->CanCommitURL(kRendererID, url2));
Daniel Cheng4ebba552018-07-06 21:43:16758
759 p->Remove(kRendererID);
760}
761
Alex Moshchuk989aa22c2024-11-06 02:09:07762TEST_P(ChildProcessSecurityPolicyTest, SpecificFile) {
[email protected]dc67e1c32012-06-08 00:10:40763 ChildProcessSecurityPolicyImpl* p =
764 ChildProcessSecurityPolicyImpl::GetInstance();
765
[email protected]dc67e1c32012-06-08 00:10:40766 GURL icon_url("file:///tmp/foo.png");
Joel Hockey91f58d7aa2024-10-03 22:59:21767 base::FilePath icon_path;
768 ASSERT_TRUE(net::FileURLToFilePath(icon_url, &icon_path));
[email protected]dc67e1c32012-06-08 00:10:40769 GURL sensitive_url("file:///etc/passwd");
Lukasz Anforowicz38003582019-09-24 19:08:05770
Aaron Colwellffade2a2020-09-16 20:54:41771 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:05772 LockProcessIfNeeded(kRendererID, browser_context(), sensitive_url);
773
[email protected]dc67e1c32012-06-08 00:10:40774 EXPECT_FALSE(p->CanRequestURL(kRendererID, icon_url));
775 EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url));
arthursonzogni98e5a232017-07-13 15:18:16776 EXPECT_TRUE(p->CanRedirectToURL(icon_url));
777 EXPECT_TRUE(p->CanRedirectToURL(sensitive_url));
creis3710b2382015-08-18 00:12:15778 EXPECT_FALSE(p->CanCommitURL(kRendererID, icon_url));
779 EXPECT_FALSE(p->CanCommitURL(kRendererID, sensitive_url));
[email protected]dc67e1c32012-06-08 00:10:40780
Joel Hockey91f58d7aa2024-10-03 22:59:21781 p->GrantRequestOfSpecificFile(kRendererID, icon_path);
[email protected]dc67e1c32012-06-08 00:10:40782 EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url));
783 EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url));
arthursonzogni98e5a232017-07-13 15:18:16784 EXPECT_TRUE(p->CanRedirectToURL(icon_url));
785 EXPECT_TRUE(p->CanRedirectToURL(sensitive_url));
Alex Moshchuk21a120e2024-03-28 23:49:54786 EXPECT_FALSE(p->CanCommitURL(kRendererID, icon_url));
creis3710b2382015-08-18 00:12:15787 EXPECT_FALSE(p->CanCommitURL(kRendererID, sensitive_url));
[email protected]dc67e1c32012-06-08 00:10:40788
Daniel Cheng4ebba552018-07-06 21:43:16789 p->GrantCommitURL(kRendererID, icon_url);
[email protected]dc67e1c32012-06-08 00:10:40790 EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url));
791 EXPECT_TRUE(p->CanRequestURL(kRendererID, sensitive_url));
arthursonzogni98e5a232017-07-13 15:18:16792 EXPECT_TRUE(p->CanRedirectToURL(icon_url));
793 EXPECT_TRUE(p->CanRedirectToURL(sensitive_url));
creis3710b2382015-08-18 00:12:15794 EXPECT_TRUE(p->CanCommitURL(kRendererID, icon_url));
795 EXPECT_TRUE(p->CanCommitURL(kRendererID, sensitive_url));
[email protected]dc67e1c32012-06-08 00:10:40796
797 p->Remove(kRendererID);
798}
799
Alex Moshchuk989aa22c2024-11-06 02:09:07800TEST_P(ChildProcessSecurityPolicyTest, ContentUri) {
Joel Hockey91f58d7aa2024-10-03 22:59:21801 ChildProcessSecurityPolicyImpl* p =
802 ChildProcessSecurityPolicyImpl::GetInstance();
803
804 GURL content_uri("content://authority/foo.png");
805 GURL content_uri_sensitive("content://authority/bar.jpg");
806
807 p->AddForTesting(kRendererID, browser_context());
808 LockProcessIfNeeded(kRendererID, browser_context(), content_uri_sensitive);
809
810#if BUILDFLAG(IS_ANDROID)
811 // Since android handles content:// URLs, CanRequestURL() is false for a URL
812 // which was not registered with GrantRequestOfSpecificFile().
813 EXPECT_FALSE(p->CanRequestURL(kRendererID, content_uri));
814 EXPECT_FALSE(p->CanRequestURL(kRendererID, content_uri_sensitive));
815#else
816 EXPECT_TRUE(p->CanRequestURL(kRendererID, content_uri));
817 EXPECT_TRUE(p->CanRequestURL(kRendererID, content_uri_sensitive));
818#endif
819 EXPECT_TRUE(p->CanRedirectToURL(content_uri));
820 EXPECT_TRUE(p->CanRedirectToURL(content_uri_sensitive));
821 EXPECT_FALSE(p->CanCommitURL(kRendererID, content_uri));
822 EXPECT_FALSE(p->CanCommitURL(kRendererID, content_uri_sensitive));
823
824 p->GrantRequestOfSpecificFile(
825 kRendererID,
826 base::FilePath::FromUTF8Unsafe(content_uri.possibly_invalid_spec()));
827 EXPECT_TRUE(p->CanRequestURL(kRendererID, content_uri));
828#if BUILDFLAG(IS_ANDROID)
829 EXPECT_FALSE(p->CanRequestURL(kRendererID, content_uri_sensitive));
830#else
831 EXPECT_TRUE(p->CanRequestURL(kRendererID, content_uri_sensitive));
832#endif
833 EXPECT_TRUE(p->CanRedirectToURL(content_uri));
834 EXPECT_TRUE(p->CanRedirectToURL(content_uri_sensitive));
835 EXPECT_FALSE(p->CanCommitURL(kRendererID, content_uri));
836 EXPECT_FALSE(p->CanCommitURL(kRendererID, content_uri_sensitive));
837
838 p->GrantCommitURL(kRendererID, content_uri);
839 EXPECT_TRUE(p->CanRequestURL(kRendererID, content_uri));
840 EXPECT_TRUE(p->CanRequestURL(kRendererID, content_uri_sensitive));
841 EXPECT_TRUE(p->CanRedirectToURL(content_uri));
842 EXPECT_TRUE(p->CanRedirectToURL(content_uri_sensitive));
843 EXPECT_TRUE(p->CanCommitURL(kRendererID, content_uri));
844 EXPECT_TRUE(p->CanCommitURL(kRendererID, content_uri_sensitive));
845
846 p->Remove(kRendererID);
847}
848
Alex Moshchuk989aa22c2024-11-06 02:09:07849TEST_P(ChildProcessSecurityPolicyTest, FileSystemGrantsTest) {
[email protected]b78c188fa62013-07-23 18:04:45850 ChildProcessSecurityPolicyImpl* p =
851 ChildProcessSecurityPolicyImpl::GetInstance();
852
Aaron Colwellffade2a2020-09-16 20:54:41853 p->AddForTesting(kRendererID, browser_context());
[email protected]cd501a72014-08-22 19:58:31854 std::string read_id =
855 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
856 storage::kFileSystemTypeTest, "read_filesystem", base::FilePath());
857 std::string read_write_id =
858 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
859 storage::kFileSystemTypeTest,
860 "read_write_filesystem",
861 base::FilePath());
862 std::string copy_into_id =
863 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
864 storage::kFileSystemTypeTest,
865 "copy_into_filesystem",
866 base::FilePath());
867 std::string delete_from_id =
868 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
869 storage::kFileSystemTypeTest,
870 "delete_from_filesystem",
871 base::FilePath());
[email protected]b78c188fa62013-07-23 18:04:45872
873 // Test initially having no permissions.
[email protected]5a65fde32013-10-22 05:15:34874 CheckHasNoFileSystemPermission(p, read_id);
875 CheckHasNoFileSystemPermission(p, read_write_id);
876 CheckHasNoFileSystemPermission(p, copy_into_id);
877 CheckHasNoFileSystemPermission(p, delete_from_id);
[email protected]b78c188fa62013-07-23 18:04:45878
879 // Testing varying combinations of grants and checks.
880 p->GrantReadFileSystem(kRendererID, read_id);
881 EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_id));
882 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id));
883 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id));
[email protected]5a65fde32013-10-22 05:15:34884 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, read_id));
[email protected]b78c188fa62013-07-23 18:04:45885
886 p->GrantReadFileSystem(kRendererID, read_write_id);
887 p->GrantWriteFileSystem(kRendererID, read_write_id);
888 EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_write_id));
889 EXPECT_TRUE(p->CanReadWriteFileSystem(kRendererID, read_write_id));
890 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id));
[email protected]5a65fde32013-10-22 05:15:34891 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, read_write_id));
[email protected]b78c188fa62013-07-23 18:04:45892
893 p->GrantCopyIntoFileSystem(kRendererID, copy_into_id);
894 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id));
895 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id));
896 EXPECT_TRUE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id));
[email protected]5a65fde32013-10-22 05:15:34897 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, copy_into_id));
898
899 p->GrantDeleteFromFileSystem(kRendererID, delete_from_id);
900 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, delete_from_id));
901 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, delete_from_id));
902 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, delete_from_id));
903 EXPECT_TRUE(p->CanDeleteFromFileSystem(kRendererID, delete_from_id));
[email protected]b78c188fa62013-07-23 18:04:45904
905 // Test revoke permissions on renderer ID removal.
906 p->Remove(kRendererID);
[email protected]5a65fde32013-10-22 05:15:34907 CheckHasNoFileSystemPermission(p, read_id);
908 CheckHasNoFileSystemPermission(p, read_write_id);
909 CheckHasNoFileSystemPermission(p, copy_into_id);
910 CheckHasNoFileSystemPermission(p, delete_from_id);
[email protected]b78c188fa62013-07-23 18:04:45911
912 // Test having no permissions upon re-adding same renderer ID.
Aaron Colwellffade2a2020-09-16 20:54:41913 p->AddForTesting(kRendererID, browser_context());
[email protected]5a65fde32013-10-22 05:15:34914 CheckHasNoFileSystemPermission(p, read_id);
915 CheckHasNoFileSystemPermission(p, read_write_id);
916 CheckHasNoFileSystemPermission(p, copy_into_id);
917 CheckHasNoFileSystemPermission(p, delete_from_id);
[email protected]b78c188fa62013-07-23 18:04:45918
919 // Cleanup.
920 p->Remove(kRendererID);
[email protected]cd501a72014-08-22 19:58:31921 storage::IsolatedContext::GetInstance()->RevokeFileSystem(read_id);
922 storage::IsolatedContext::GetInstance()->RevokeFileSystem(read_write_id);
923 storage::IsolatedContext::GetInstance()->RevokeFileSystem(copy_into_id);
924 storage::IsolatedContext::GetInstance()->RevokeFileSystem(delete_from_id);
[email protected]b78c188fa62013-07-23 18:04:45925}
926
Alex Moshchuk989aa22c2024-11-06 02:09:07927TEST_P(ChildProcessSecurityPolicyTest, FilePermissionGrantingAndRevoking) {
[email protected]b9535422012-02-09 01:47:59928 ChildProcessSecurityPolicyImpl* p =
929 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:29930
[email protected]9f104312013-07-23 23:18:19931 p->RegisterFileSystemPermissionPolicy(
[email protected]cd501a72014-08-22 19:58:31932 storage::kFileSystemTypeTest,
933 storage::FILE_PERMISSION_USE_FILE_PERMISSION);
[email protected]9f104312013-07-23 23:18:19934
Aaron Colwellffade2a2020-09-16 20:54:41935 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:05936 LockProcessIfNeeded(kRendererID, browser_context(), GURL("http://foo/"));
937
[email protected]9f104312013-07-23 23:18:19938 base::FilePath file(TEST_PATH("/dir/testfile"));
939 file = file.NormalizePathSeparators();
[email protected]cd501a72014-08-22 19:58:31940 storage::FileSystemURL url = storage::FileSystemURL::CreateForTest(
Kyra Seevers86ecaf52021-07-13 13:48:17941 blink::StorageKey::CreateFromStringForTesting("http://foo/"),
942 storage::kFileSystemTypeTest, file);
initial.commit09911bf2008-07-26 23:55:29943
[email protected]9f104312013-07-23 23:18:19944 // Test initially having no permissions.
[email protected]5a65fde32013-10-22 05:15:34945 CheckHasNoFileSystemFilePermission(p, file, url);
initial.commit09911bf2008-07-26 23:55:29946
[email protected]9f104312013-07-23 23:18:19947 // Testing every combination of permissions granting and revoking.
948 p->GrantReadFile(kRendererID, file);
949 EXPECT_TRUE(p->CanReadFile(kRendererID, file));
[email protected]d4c797f2013-09-26 08:18:53950 EXPECT_FALSE(p->CanCreateReadWriteFile(kRendererID, file));
[email protected]9f104312013-07-23 23:18:19951 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url));
952 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url));
953 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url));
[email protected]d4c797f2013-09-26 08:18:53954 EXPECT_FALSE(p->CanCreateReadWriteFileSystemFile(kRendererID, url));
[email protected]5a65fde32013-10-22 05:15:34955 EXPECT_FALSE(p->CanCopyIntoFileSystemFile(kRendererID, url));
956 EXPECT_FALSE(p->CanDeleteFileSystemFile(kRendererID, url));
[email protected]9f104312013-07-23 23:18:19957 p->RevokeAllPermissionsForFile(kRendererID, file);
[email protected]5a65fde32013-10-22 05:15:34958 CheckHasNoFileSystemFilePermission(p, file, url);
[email protected]9f104312013-07-23 23:18:19959
960 p->GrantCreateReadWriteFile(kRendererID, file);
961 EXPECT_TRUE(p->CanReadFile(kRendererID, file));
[email protected]d4c797f2013-09-26 08:18:53962 EXPECT_TRUE(p->CanCreateReadWriteFile(kRendererID, file));
[email protected]9f104312013-07-23 23:18:19963 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url));
964 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url));
965 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url));
[email protected]d4c797f2013-09-26 08:18:53966 EXPECT_TRUE(p->CanCreateReadWriteFileSystemFile(kRendererID, url));
[email protected]5a65fde32013-10-22 05:15:34967 EXPECT_TRUE(p->CanCopyIntoFileSystemFile(kRendererID, url));
968 EXPECT_TRUE(p->CanDeleteFileSystemFile(kRendererID, url));
[email protected]9f104312013-07-23 23:18:19969 p->RevokeAllPermissionsForFile(kRendererID, file);
[email protected]5a65fde32013-10-22 05:15:34970 CheckHasNoFileSystemFilePermission(p, file, url);
[email protected]9f104312013-07-23 23:18:19971
972 // Test revoke permissions on renderer ID removal.
973 p->GrantCreateReadWriteFile(kRendererID, file);
974 EXPECT_TRUE(p->CanReadFile(kRendererID, file));
[email protected]d4c797f2013-09-26 08:18:53975 EXPECT_TRUE(p->CanCreateReadWriteFile(kRendererID, file));
[email protected]9f104312013-07-23 23:18:19976 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url));
977 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url));
978 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url));
[email protected]d4c797f2013-09-26 08:18:53979 EXPECT_TRUE(p->CanCreateReadWriteFileSystemFile(kRendererID, url));
[email protected]5a65fde32013-10-22 05:15:34980 EXPECT_TRUE(p->CanCopyIntoFileSystemFile(kRendererID, url));
981 EXPECT_TRUE(p->CanDeleteFileSystemFile(kRendererID, url));
initial.commit09911bf2008-07-26 23:55:29982 p->Remove(kRendererID);
[email protected]5a65fde32013-10-22 05:15:34983 CheckHasNoFileSystemFilePermission(p, file, url);
[email protected]9f104312013-07-23 23:18:19984
985 // Test having no permissions upon re-adding same renderer ID.
Aaron Colwellffade2a2020-09-16 20:54:41986 p->AddForTesting(kRendererID, browser_context());
[email protected]5a65fde32013-10-22 05:15:34987 CheckHasNoFileSystemFilePermission(p, file, url);
Lukasz Anforowicz38003582019-09-24 19:08:05988 LockProcessIfNeeded(kRendererID, browser_context(), GURL("http://foo/"));
989 CheckHasNoFileSystemFilePermission(p, file, url);
initial.commit09911bf2008-07-26 23:55:29990
[email protected]9f104312013-07-23 23:18:19991 // Cleanup.
initial.commit09911bf2008-07-26 23:55:29992 p->Remove(kRendererID);
993}
994
Alex Moshchuk989aa22c2024-11-06 02:09:07995TEST_P(ChildProcessSecurityPolicyTest, FilePermissions) {
[email protected]c42de732013-02-16 06:26:31996 base::FilePath granted_file = base::FilePath(TEST_PATH("/home/joe"));
997 base::FilePath sibling_file = base::FilePath(TEST_PATH("/home/bob"));
998 base::FilePath child_file = base::FilePath(TEST_PATH("/home/joe/file"));
999 base::FilePath parent_file = base::FilePath(TEST_PATH("/home"));
1000 base::FilePath parent_slash_file = base::FilePath(TEST_PATH("/home/"));
1001 base::FilePath child_traversal1 =
1002 base::FilePath(TEST_PATH("/home/joe/././file"));
1003 base::FilePath child_traversal2 = base::FilePath(
[email protected]f0ecca4522013-01-07 21:50:561004 TEST_PATH("/home/joe/file/../otherfile"));
[email protected]2dec8ec2013-02-07 19:20:341005 base::FilePath evil_traversal1 =
[email protected]023ad6ab2013-02-17 05:07:231006 base::FilePath(TEST_PATH("/home/joe/../../etc/passwd"));
[email protected]c42de732013-02-16 06:26:311007 base::FilePath evil_traversal2 = base::FilePath(
[email protected]f0ecca4522013-01-07 21:50:561008 TEST_PATH("/home/joe/./.././../etc/passwd"));
[email protected]c42de732013-02-16 06:26:311009 base::FilePath self_traversal =
1010 base::FilePath(TEST_PATH("/home/joe/../joe/file"));
1011 base::FilePath relative_file = base::FilePath(FILE_PATH_LITERAL("home/joe"));
[email protected]80838412012-11-20 01:53:591012
[email protected]b9535422012-02-09 01:47:591013 ChildProcessSecurityPolicyImpl* p =
1014 ChildProcessSecurityPolicyImpl::GetInstance();
[email protected]e54edc32010-09-28 01:09:191015
1016 // Grant permissions for a file.
Aaron Colwellffade2a2020-09-16 20:54:411017 p->AddForTesting(kRendererID, browser_context());
[email protected]80838412012-11-20 01:53:591018 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411019 base::File::FLAG_OPEN));
[email protected]e54edc32010-09-28 01:09:191020
[email protected]bfcf1e92013-07-11 04:37:251021 GrantPermissionsForFile(p, kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411022 base::File::FLAG_OPEN |
1023 base::File::FLAG_OPEN_TRUNCATED |
1024 base::File::FLAG_READ |
1025 base::File::FLAG_WRITE);
[email protected]80838412012-11-20 01:53:591026 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411027 base::File::FLAG_OPEN |
1028 base::File::FLAG_OPEN_TRUNCATED |
1029 base::File::FLAG_READ |
1030 base::File::FLAG_WRITE));
[email protected]80838412012-11-20 01:53:591031 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411032 base::File::FLAG_OPEN |
1033 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591034 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411035 base::File::FLAG_CREATE));
[email protected]f0ecca4522013-01-07 21:50:561036 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 0));
[email protected]80838412012-11-20 01:53:591037 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411038 base::File::FLAG_CREATE |
1039 base::File::FLAG_OPEN_TRUNCATED |
1040 base::File::FLAG_READ |
1041 base::File::FLAG_WRITE));
[email protected]80838412012-11-20 01:53:591042 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file,
[email protected]2c288ed2014-06-05 22:07:411043 base::File::FLAG_OPEN |
1044 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591045 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file,
[email protected]2c288ed2014-06-05 22:07:411046 base::File::FLAG_OPEN |
1047 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591048 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_file,
[email protected]2c288ed2014-06-05 22:07:411049 base::File::FLAG_OPEN |
1050 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591051 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal1,
[email protected]2c288ed2014-06-05 22:07:411052 base::File::FLAG_OPEN |
1053 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591054 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal2,
[email protected]2c288ed2014-06-05 22:07:411055 base::File::FLAG_OPEN |
1056 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591057 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal1,
[email protected]2c288ed2014-06-05 22:07:411058 base::File::FLAG_OPEN |
1059 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591060 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal2,
[email protected]2c288ed2014-06-05 22:07:411061 base::File::FLAG_OPEN |
1062 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591063 // CPSP doesn't allow this case for the sake of simplicity.
1064 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, self_traversal,
[email protected]2c288ed2014-06-05 22:07:411065 base::File::FLAG_OPEN |
1066 base::File::FLAG_READ));
[email protected]e54edc32010-09-28 01:09:191067 p->Remove(kRendererID);
1068
1069 // Grant permissions for the directory the file is in.
Aaron Colwellffade2a2020-09-16 20:54:411070 p->AddForTesting(kRendererID, browser_context());
[email protected]80838412012-11-20 01:53:591071 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411072 base::File::FLAG_OPEN));
[email protected]bfcf1e92013-07-11 04:37:251073 GrantPermissionsForFile(p, kRendererID, parent_file,
[email protected]2c288ed2014-06-05 22:07:411074 base::File::FLAG_OPEN |
1075 base::File::FLAG_READ);
[email protected]80838412012-11-20 01:53:591076 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411077 base::File::FLAG_OPEN));
[email protected]80838412012-11-20 01:53:591078 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411079 base::File::FLAG_READ |
1080 base::File::FLAG_WRITE));
[email protected]e54edc32010-09-28 01:09:191081 p->Remove(kRendererID);
1082
1083 // Grant permissions for the directory the file is in (with trailing '/').
Aaron Colwellffade2a2020-09-16 20:54:411084 p->AddForTesting(kRendererID, browser_context());
[email protected]80838412012-11-20 01:53:591085 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411086 base::File::FLAG_OPEN));
[email protected]bfcf1e92013-07-11 04:37:251087 GrantPermissionsForFile(p, kRendererID, parent_slash_file,
[email protected]2c288ed2014-06-05 22:07:411088 base::File::FLAG_OPEN |
1089 base::File::FLAG_READ);
[email protected]80838412012-11-20 01:53:591090 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411091 base::File::FLAG_OPEN));
[email protected]80838412012-11-20 01:53:591092 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411093 base::File::FLAG_READ |
1094 base::File::FLAG_WRITE));
[email protected]e54edc32010-09-28 01:09:191095
1096 // Grant permissions for the file (should overwrite the permissions granted
1097 // for the directory).
[email protected]bfcf1e92013-07-11 04:37:251098 GrantPermissionsForFile(p, kRendererID, granted_file,
Alexei Svitkine4a4965322021-12-03 06:38:201099 base::File::FLAG_WIN_TEMPORARY);
[email protected]80838412012-11-20 01:53:591100 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411101 base::File::FLAG_OPEN));
[email protected]80838412012-11-20 01:53:591102 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
Alexei Svitkine4a4965322021-12-03 06:38:201103 base::File::FLAG_WIN_TEMPORARY));
[email protected]77930fe2010-10-01 22:45:341104
1105 // Revoke all permissions for the file (it should inherit its permissions
1106 // from the directory again).
[email protected]80838412012-11-20 01:53:591107 p->RevokeAllPermissionsForFile(kRendererID, granted_file);
1108 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file,
[email protected]2c288ed2014-06-05 22:07:411109 base::File::FLAG_OPEN |
1110 base::File::FLAG_READ));
[email protected]80838412012-11-20 01:53:591111 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file,
Alexei Svitkine4a4965322021-12-03 06:38:201112 base::File::FLAG_WIN_TEMPORARY));
[email protected]e54edc32010-09-28 01:09:191113 p->Remove(kRendererID);
[email protected]cee64fd32011-05-02 18:59:071114
Aaron Colwellffade2a2020-09-16 20:54:411115 p->AddForTesting(kRendererID, browser_context());
[email protected]bfcf1e92013-07-11 04:37:251116 GrantPermissionsForFile(p, kRendererID, relative_file,
[email protected]2c288ed2014-06-05 22:07:411117 base::File::FLAG_OPEN);
[email protected]f0ecca4522013-01-07 21:50:561118 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, relative_file,
[email protected]2c288ed2014-06-05 22:07:411119 base::File::FLAG_OPEN));
[email protected]f0ecca4522013-01-07 21:50:561120 p->Remove(kRendererID);
[email protected]e54edc32010-09-28 01:09:191121}
1122
Alex Moshchuk989aa22c2024-11-06 02:09:071123TEST_P(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) {
[email protected]b9535422012-02-09 01:47:591124 ChildProcessSecurityPolicyImpl* p =
1125 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:291126
Matt Siembor9cb08392019-04-24 21:34:391127 const GURL url(GetWebUIURL("thumb/http://www.google.com/"));
1128 const GURL other_url(GetWebUIURL("not-thumb/"));
Daniel Cheng4ebba552018-07-06 21:43:161129 const url::Origin origin = url::Origin::Create(url);
Christopher Lama4dc3142018-06-01 03:17:071130 {
Aaron Colwellffade2a2020-09-16 20:54:411131 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:051132 LockProcessIfNeeded(kRendererID, browser_context(), url);
Daniel Cheng4ebba552018-07-06 21:43:161133
Christopher Lama4dc3142018-06-01 03:17:071134 EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
Daniel Cheng4ebba552018-07-06 21:43:161135
Christopher Lama4dc3142018-06-01 03:17:071136 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
Daniel Cheng4ebba552018-07-06 21:43:161137 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
Christopher Lama4dc3142018-06-01 03:17:071138 EXPECT_TRUE(p->CanRedirectToURL(url));
Daniel Cheng4ebba552018-07-06 21:43:161139
1140 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
1141 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1142 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1143
Avi Drissman78865bbb2024-08-22 20:57:191144 p->GrantWebUIBindings(kRendererID,
1145 BindingsPolicySet({BindingsPolicyValue::kWebUi}));
Daniel Cheng4ebba552018-07-06 21:43:161146
Christopher Lama4dc3142018-06-01 03:17:071147 EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
Daniel Cheng4ebba552018-07-06 21:43:161148
jessing37109f212020-02-03 01:59:201149 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
Daniel Cheng4ebba552018-07-06 21:43:161150 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
Christopher Lama4dc3142018-06-01 03:17:071151 EXPECT_TRUE(p->CanRedirectToURL(url));
Daniel Cheng4ebba552018-07-06 21:43:161152
jessing37109f212020-02-03 01:59:201153 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
Daniel Cheng4ebba552018-07-06 21:43:161154 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1155 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1156
1157 p->GrantCommitOrigin(kRendererID, origin);
1158
1159 EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
1160 EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
1161 EXPECT_TRUE(p->CanRedirectToURL(url));
1162
jessing37109f212020-02-03 01:59:201163 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
Daniel Cheng4ebba552018-07-06 21:43:161164 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1165 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1166
Christopher Lama4dc3142018-06-01 03:17:071167 p->Remove(kRendererID);
1168 }
Lukasz Anforowicz38003582019-09-24 19:08:051169
Christopher Lama4dc3142018-06-01 03:17:071170 {
Aaron Colwellffade2a2020-09-16 20:54:411171 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:051172 LockProcessIfNeeded(kRendererID, browser_context(), url);
Daniel Cheng4ebba552018-07-06 21:43:161173
Christopher Lama4dc3142018-06-01 03:17:071174 EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
Daniel Cheng4ebba552018-07-06 21:43:161175
Christopher Lama4dc3142018-06-01 03:17:071176 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
Daniel Cheng4ebba552018-07-06 21:43:161177 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
Christopher Lama4dc3142018-06-01 03:17:071178 EXPECT_TRUE(p->CanRedirectToURL(url));
Daniel Cheng4ebba552018-07-06 21:43:161179
1180 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
1181 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1182 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1183
Christopher Lama4dc3142018-06-01 03:17:071184 p->GrantWebUIBindings(kRendererID,
Avi Drissman78865bbb2024-08-22 20:57:191185 BindingsPolicySet({BindingsPolicyValue::kMojoWebUi}));
1186
1187 EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
1188
1189 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
1190 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
1191 EXPECT_TRUE(p->CanRedirectToURL(url));
1192
1193 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
1194 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1195 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1196
1197 p->GrantCommitOrigin(kRendererID, origin);
1198
1199 EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
1200 EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
1201 EXPECT_TRUE(p->CanRedirectToURL(url));
1202
1203 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
1204 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1205 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1206
1207 p->Remove(kRendererID);
1208 }
1209
1210 {
1211 p->AddForTesting(kRendererID, browser_context());
1212 LockProcessIfNeeded(kRendererID, browser_context(), url);
1213
1214 EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
1215
1216 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
1217 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
1218 EXPECT_TRUE(p->CanRedirectToURL(url));
1219
1220 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
1221 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1222 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1223
1224 p->GrantWebUIBindings(kRendererID, kWebUIBindingsPolicySet);
Daniel Cheng4ebba552018-07-06 21:43:161225
Christopher Lama4dc3142018-06-01 03:17:071226 EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
Daniel Cheng4ebba552018-07-06 21:43:161227
jessing37109f212020-02-03 01:59:201228 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
Daniel Cheng4ebba552018-07-06 21:43:161229 EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
Christopher Lama4dc3142018-06-01 03:17:071230 EXPECT_TRUE(p->CanRedirectToURL(url));
Daniel Cheng4ebba552018-07-06 21:43:161231
jessing37109f212020-02-03 01:59:201232 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
Daniel Cheng4ebba552018-07-06 21:43:161233 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1234 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1235
1236 p->GrantCommitOrigin(kRendererID, origin);
1237
1238 EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
1239 EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
1240 EXPECT_TRUE(p->CanRedirectToURL(url));
1241
jessing37109f212020-02-03 01:59:201242 EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
Daniel Cheng4ebba552018-07-06 21:43:161243 EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
1244 EXPECT_TRUE(p->CanRedirectToURL(other_url));
1245
Christopher Lama4dc3142018-06-01 03:17:071246 p->Remove(kRendererID);
1247 }
initial.commit09911bf2008-07-26 23:55:291248}
1249
Alex Moshchuk989aa22c2024-11-06 02:09:071250TEST_P(ChildProcessSecurityPolicyTest, RemoveRace) {
[email protected]b9535422012-02-09 01:47:591251 ChildProcessSecurityPolicyImpl* p =
1252 ChildProcessSecurityPolicyImpl::GetInstance();
initial.commit09911bf2008-07-26 23:55:291253
1254 GURL url("file:///etc/passwd");
[email protected]2dec8ec2013-02-07 19:20:341255 base::FilePath file(TEST_PATH("/etc/passwd"));
initial.commit09911bf2008-07-26 23:55:291256
Aaron Colwellffade2a2020-09-16 20:54:411257 p->AddForTesting(kRendererID, browser_context());
initial.commit09911bf2008-07-26 23:55:291258
Daniel Cheng4ebba552018-07-06 21:43:161259 p->GrantCommitURL(kRendererID, url);
[email protected]e54edc32010-09-28 01:09:191260 p->GrantReadFile(kRendererID, file);
Avi Drissman78865bbb2024-08-22 20:57:191261 p->GrantWebUIBindings(kRendererID, kWebUIBindingsPolicySet);
initial.commit09911bf2008-07-26 23:55:291262
1263 EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
arthursonzogni98e5a232017-07-13 15:18:161264 EXPECT_TRUE(p->CanRedirectToURL(url));
[email protected]e54edc32010-09-28 01:09:191265 EXPECT_TRUE(p->CanReadFile(kRendererID, file));
[email protected]c50008512011-02-03 01:17:271266 EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
initial.commit09911bf2008-07-26 23:55:291267
1268 p->Remove(kRendererID);
1269
1270 // Renderers are added and removed on the UI thread, but the policy can be
[email protected]580522632009-08-17 21:55:551271 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be
1272 // prepared to answer policy questions about renderers who no longer exist.
initial.commit09911bf2008-07-26 23:55:291273
1274 // In this case, we default to secure behavior.
1275 EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
arthursonzogni98e5a232017-07-13 15:18:161276 EXPECT_TRUE(p->CanRedirectToURL(url));
[email protected]e54edc32010-09-28 01:09:191277 EXPECT_FALSE(p->CanReadFile(kRendererID, file));
[email protected]c50008512011-02-03 01:17:271278 EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
initial.commit09911bf2008-07-26 23:55:291279}
[email protected]46488322012-10-30 03:22:201280
Alex Moshchuk989aa22c2024-11-06 02:09:071281TEST_P(ChildProcessSecurityPolicyTest, HandleDuplicate) {
Aaron Colwelldd9dce32020-06-04 21:03:521282 ChildProcessSecurityPolicyImpl* p =
1283 ChildProcessSecurityPolicyImpl::GetInstance();
1284
1285 GURL url("file:///etc/passwd");
1286
Aaron Colwellffade2a2020-09-16 20:54:411287 p->AddForTesting(kRendererID, browser_context());
Aaron Colwelldd9dce32020-06-04 21:03:521288 LockProcessIfNeeded(kRendererID, browser_context(), url);
Alex Moshchuk989aa22c2024-11-06 02:09:071289 p->AddCommittedOrigin(kRendererID, url::Origin::Create(url));
Aaron Colwelldd9dce32020-06-04 21:03:521290
1291 auto handle = p->CreateHandle(kRendererID);
1292
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471293 EXPECT_TRUE(handle.CanAccessDataForOrigin(url::Origin::Create(url)));
Aaron Colwelldd9dce32020-06-04 21:03:521294
1295 // Verify that a valid duplicate can be created and allows access.
1296 auto duplicate_handle = handle.Duplicate();
1297 EXPECT_TRUE(duplicate_handle.is_valid());
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471298 EXPECT_TRUE(
1299 duplicate_handle.CanAccessDataForOrigin(url::Origin::Create(url)));
Aaron Colwelldd9dce32020-06-04 21:03:521300
1301 p->Remove(kRendererID);
1302
1303 // Verify that both handles still work even after Remove() has been called.
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471304 EXPECT_TRUE(handle.CanAccessDataForOrigin(url::Origin::Create(url)));
1305 EXPECT_TRUE(
1306 duplicate_handle.CanAccessDataForOrigin(url::Origin::Create(url)));
Aaron Colwelldd9dce32020-06-04 21:03:521307
1308 // Verify that a new duplicate can be created after Remove().
1309 auto duplicate_handle2 = handle.Duplicate();
1310 EXPECT_TRUE(duplicate_handle2.is_valid());
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471311 EXPECT_TRUE(
1312 duplicate_handle2.CanAccessDataForOrigin(url::Origin::Create(url)));
Aaron Colwelldd9dce32020-06-04 21:03:521313
1314 // Verify that a new valid Handle cannot be created after Remove().
1315 EXPECT_FALSE(p->CreateHandle(kRendererID).is_valid());
1316
1317 // Invalidate the original Handle and verify that the duplicates still work.
1318 handle = ChildProcessSecurityPolicyImpl::Handle();
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471319 EXPECT_FALSE(handle.CanAccessDataForOrigin(url::Origin::Create(url)));
1320 EXPECT_TRUE(
1321 duplicate_handle.CanAccessDataForOrigin(url::Origin::Create(url)));
1322 EXPECT_TRUE(
1323 duplicate_handle2.CanAccessDataForOrigin(url::Origin::Create(url)));
Aaron Colwelldd9dce32020-06-04 21:03:521324}
1325
Alex Moshchuk989aa22c2024-11-06 02:09:071326TEST_P(ChildProcessSecurityPolicyTest, CanAccessDataForOrigin_URL) {
Aaron Colwell220d5022019-01-16 04:56:551327 ChildProcessSecurityPolicyImpl* p =
1328 ChildProcessSecurityPolicyImpl::GetInstance();
1329
1330 GURL file_url("file:///etc/passwd");
Aaron Colwell147926d2019-08-22 18:02:351331 GURL foo_http_url("http://foo.com/index.html");
1332 GURL foo_blob_url("blob:http://foo.com/43d75119-d7af-4471-a293-07c6b3d7e61a");
1333 GURL foo_filesystem_url("filesystem:http://foo.com/temporary/test.html");
1334 GURL bar_http_url("http://bar.com/index.html");
Aaron Colwell220d5022019-01-16 04:56:551335
Aaron Colwell4fcbe4152020-01-16 07:10:591336 const std::vector<GURL> kAllTestUrls = {file_url, foo_http_url, foo_blob_url,
1337 foo_filesystem_url, bar_http_url};
1338
1339 // Test invalid ID and invalid Handle cases.
1340 auto handle = p->CreateHandle(kRendererID);
1341 for (auto url : kAllTestUrls) {
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471342 EXPECT_FALSE(
1343 p->CanAccessDataForOrigin(kRendererID, url::Origin::Create(url)))
1344 << url;
1345 EXPECT_FALSE(
1346 handle.CanAccessDataForOrigin(url::Origin::Create(bar_http_url)))
1347 << url;
Aaron Colwell4fcbe4152020-01-16 07:10:591348 }
Aaron Colwell220d5022019-01-16 04:56:551349
1350 TestBrowserContext browser_context;
Aaron Colwellffade2a2020-09-16 20:54:411351 p->AddForTesting(kRendererID, &browser_context);
Aaron Colwell220d5022019-01-16 04:56:551352
Aaron Colwell4fcbe4152020-01-16 07:10:591353 // Replace the old invalid handle with a new valid handle.
1354 handle = p->CreateHandle(kRendererID);
1355
Aaron Colwell220d5022019-01-16 04:56:551356 // Verify unlocked origin permissions.
Aaron Colwell4fcbe4152020-01-16 07:10:591357 for (auto url : kAllTestUrls) {
Alex Moshchuk989aa22c2024-11-06 02:09:071358 if (AreAllSitesIsolatedForTesting() ||
1359 base::FeatureList::IsEnabled(features::kCommittedOriginEnforcements)) {
1360 // An unlocked process cannot access URLs below (because with
1361 // site-per-process all the URLs need to be isolated). If
1362 // CanAccessDataForOrigin enforcement uses committed origin tracking, then
1363 // these should fail even without site isolation, since the process hasn't
1364 // committed any origins at this point.
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471365 EXPECT_FALSE(
1366 p->CanAccessDataForOrigin(kRendererID, url::Origin::Create(url)))
1367 << url;
1368 EXPECT_FALSE(handle.CanAccessDataForOrigin(url::Origin::Create(url)))
1369 << url;
Aaron Colwell4fcbe4152020-01-16 07:10:591370 } else {
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471371 EXPECT_TRUE(
1372 p->CanAccessDataForOrigin(kRendererID, url::Origin::Create(url)))
1373 << url;
1374 EXPECT_TRUE(handle.CanAccessDataForOrigin(url::Origin::Create(url)))
1375 << url;
Aaron Colwell4fcbe4152020-01-16 07:10:591376 }
Lukasz Anforowicz38003582019-09-24 19:08:051377 }
Aaron Colwell220d5022019-01-16 04:56:551378
Alex Moshchuk989aa22c2024-11-06 02:09:071379 // Isolate |foo_http_url| so we can't get a default SiteInstance.
Alex Moshchukef8c2562021-03-12 06:37:451380 p->AddFutureIsolatedOrigins({url::Origin::Create(foo_http_url)},
1381 IsolatedOriginSource::TEST, &browser_context);
Aaron Colwellf45e3a852019-06-06 00:48:271382
Alex Moshchuk989aa22c2024-11-06 02:09:071383 // Lock process to |foo_http_url| origin and pretend that it's been committed.
Aaron Colwell220d5022019-01-16 04:56:551384 scoped_refptr<SiteInstanceImpl> foo_instance =
Alex Moshchuk331fa5f2021-03-10 06:16:591385 SiteInstanceImpl::CreateForTesting(&browser_context, foo_http_url);
Aaron Colwellf45e3a852019-06-06 00:48:271386 EXPECT_FALSE(foo_instance->IsDefaultSiteInstance());
Lukasz Anforowicz38003582019-09-24 19:08:051387 LockProcessIfNeeded(kRendererID, &browser_context, foo_http_url);
Alex Moshchuk989aa22c2024-11-06 02:09:071388 p->AddCommittedOrigin(kRendererID, url::Origin::Create(foo_http_url));
Aaron Colwell220d5022019-01-16 04:56:551389
1390 // Verify that file access is no longer allowed.
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471391 EXPECT_FALSE(
1392 p->CanAccessDataForOrigin(kRendererID, url::Origin::Create(file_url)));
1393 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID,
1394 url::Origin::Create(foo_http_url)));
1395 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID,
1396 url::Origin::Create(foo_blob_url)));
1397 EXPECT_TRUE(p->CanAccessDataForOrigin(
1398 kRendererID, url::Origin::Create(foo_filesystem_url)));
1399 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID,
1400 url::Origin::Create(bar_http_url)));
1401 EXPECT_FALSE(handle.CanAccessDataForOrigin(url::Origin::Create(file_url)));
1402 EXPECT_TRUE(handle.CanAccessDataForOrigin(url::Origin::Create(foo_http_url)));
1403 EXPECT_TRUE(handle.CanAccessDataForOrigin(url::Origin::Create(foo_blob_url)));
1404 EXPECT_TRUE(
1405 handle.CanAccessDataForOrigin(url::Origin::Create(foo_filesystem_url)));
1406 EXPECT_FALSE(
1407 handle.CanAccessDataForOrigin(url::Origin::Create(bar_http_url)));
Aaron Colwell4fcbe4152020-01-16 07:10:591408
1409 // Invalidate handle so it does not preserve security state beyond Remove().
1410 handle = ChildProcessSecurityPolicyImpl::Handle();
Aaron Colwell220d5022019-01-16 04:56:551411
1412 p->Remove(kRendererID);
1413
1414 // Post a task to the IO loop that then posts a task to the UI loop.
1415 // This should cause the |run_loop| to return after the removal has completed.
1416 base::RunLoop run_loop;
Gabriel Charettee7cdc5cd2020-05-27 23:35:051417 GetIOThreadTaskRunner({})->PostTaskAndReply(FROM_HERE, base::DoNothing(),
1418 run_loop.QuitClosure());
Aaron Colwell220d5022019-01-16 04:56:551419 run_loop.Run();
1420
Aaron Colwell147926d2019-08-22 18:02:351421 // Verify invalid ID is rejected now that Remove() has completed.
Aaron Colwell4fcbe4152020-01-16 07:10:591422 for (auto url : kAllTestUrls) {
Lukasz Anforowiczd0d8cdb2021-01-27 22:20:471423 EXPECT_FALSE(
1424 p->CanAccessDataForOrigin(kRendererID, url::Origin::Create(url)))
1425 << url;
1426 EXPECT_FALSE(handle.CanAccessDataForOrigin(url::Origin::Create(url)))
1427 << url;
Aaron Colwell4fcbe4152020-01-16 07:10:591428 }
Aaron Colwell147926d2019-08-22 18:02:351429}
1430
Alex Moshchuk989aa22c2024-11-06 02:09:071431TEST_P(ChildProcessSecurityPolicyTest, CanAccessDataForOrigin_Origin) {
Aaron Colwell147926d2019-08-22 18:02:351432 ChildProcessSecurityPolicyImpl* p =
1433 ChildProcessSecurityPolicyImpl::GetInstance();
1434
1435 const std::vector<const char*> foo_urls = {
1436 "http://foo.com/index.html",
1437 "blob:http://foo.com/43d75119-d7af-4471-a293-07c6b3d7e61a",
1438 "filesystem:http://foo.com/temporary/test.html",
Lukasz Anforowicz7da8b2fd2020-01-24 22:35:011439 // TODO(acolwell): data: should be in |non_foo_urls| in the long-term.
1440 "data:text/html,Hello!"};
Aaron Colwell147926d2019-08-22 18:02:351441
1442 const std::vector<const char*> non_foo_urls = {
1443 "file:///etc/passwd",
1444 "http://bar.com/index.html",
1445 "blob:http://bar.com/43d75119-d7af-4471-a293-07c6b3d7e61a",
1446 "filesystem:http://bar.com/temporary/test.html",
Aaron Colwell147926d2019-08-22 18:02:351447 // foo.com with a different scheme not considered equal.
1448 "https://foo.com/index.html",
1449 "blob:https://foo.com/43d75119-d7af-4471-a293-07c6b3d7e61a",
1450 "filesystem:https://foo.com/temporary/test.html"};
1451
Alex Moshchuk989aa22c2024-11-06 02:09:071452 const std::vector<const char*> foo_urls_with_port_mismatch = {
1453 "http://foo.com:1234/index.html",
1454 "blob:http://foo.com:1234/43d75119-d7af-4471-a293-07c6b3d7e61a",
1455 "filesystem:http://foo.com:1234/temporary/test.html"};
1456
Aaron Colwell147926d2019-08-22 18:02:351457 std::vector<url::Origin> foo_origins;
1458 std::vector<url::Origin> non_foo_origins;
1459 std::vector<url::Origin> all_origins;
1460 for (auto* url : foo_urls) {
1461 auto origin = url::Origin::Create(GURL(url));
1462 foo_origins.push_back(origin);
1463 all_origins.push_back(origin);
1464 }
1465 auto foo_origin = url::Origin::Create(GURL("http://foo.com"));
Alex Moshchuk989aa22c2024-11-06 02:09:071466
1467 // TODO(crbug.com/40148776): kCommittedOriginEnforcements should stop allowing
1468 // a non-opaque committed origin to match an opaque origin, even if the
1469 // latter's precursor matches. See TODO in
1470 // SecurityState::MatchesCommittedOrigin().
Aaron Colwell147926d2019-08-22 18:02:351471 auto opaque_with_foo_precursor = foo_origin.DeriveNewOpaqueOrigin();
1472 foo_origins.push_back(opaque_with_foo_precursor);
1473 all_origins.push_back(opaque_with_foo_precursor);
1474
Alex Moshchuk989aa22c2024-11-06 02:09:071475 // List-of-committed-origins enforcements perform stricter checks in cases
1476 // where origins differ only in port.
1477 for (auto* url : foo_urls_with_port_mismatch) {
1478 auto origin = url::Origin::Create(GURL(url));
1479 if (base::FeatureList::IsEnabled(features::kCommittedOriginEnforcements)) {
1480 non_foo_origins.push_back(origin);
1481 } else {
1482 foo_origins.push_back(origin);
1483 }
1484 all_origins.push_back(origin);
1485 }
1486
Aaron Colwell147926d2019-08-22 18:02:351487 for (auto* url : non_foo_urls) {
1488 auto origin = url::Origin::Create(GURL(url));
1489 non_foo_origins.push_back(origin);
1490 all_origins.push_back(origin);
1491 }
1492 url::Origin opaque_origin_without_precursor;
Lukasz Anforowicz7da8b2fd2020-01-24 22:35:011493 // TODO(acolwell): This should be in |non_foo_origins| in the long-term.
1494 foo_origins.push_back(opaque_origin_without_precursor);
Aaron Colwell147926d2019-08-22 18:02:351495 all_origins.push_back(opaque_origin_without_precursor);
1496
1497 auto opaque_with_bar_precursor =
1498 url::Origin::Create(GURL("http://bar.com")).DeriveNewOpaqueOrigin();
1499 non_foo_origins.push_back(opaque_with_bar_precursor);
1500 all_origins.push_back(opaque_with_bar_precursor);
1501
Lukasz Anforowicz7da8b2fd2020-01-24 22:35:011502 // Test invalid process ID for all cases.
Aaron Colwell147926d2019-08-22 18:02:351503 for (const auto& origin : all_origins)
1504 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
1505
1506 TestBrowserContext browser_context;
Aaron Colwellffade2a2020-09-16 20:54:411507 p->AddForTesting(kRendererID, &browser_context);
Aaron Colwell147926d2019-08-22 18:02:351508
1509 // Verify unlocked process permissions.
Lukasz Anforowicz38003582019-09-24 19:08:051510 for (const auto& origin : all_origins) {
Alex Moshchuk989aa22c2024-11-06 02:09:071511 if (AreAllSitesIsolatedForTesting() ||
1512 base::FeatureList::IsEnabled(features::kCommittedOriginEnforcements)) {
1513 // An unlocked process cannot access URLs below (because with
1514 // site-per-process all the URLs need to be isolated). If
1515 // CanAccessDataForOrigin enforcement uses committed origin tracking, then
1516 // these should fail even without site isolation, since the process hasn't
1517 // committed any origins at this point. The only exception is for opaque
1518 // origins with no precursor, which are currently allowed; see TODO in
1519 // ChildProcessSecurityPolicyImpl::CanAccessOrigin().
Lukasz Anforowicz38003582019-09-24 19:08:051520 if (origin.opaque() &&
Nasko Oskov55119382020-01-17 18:22:181521 !origin.GetTupleOrPrecursorTupleIfOpaque().IsValid()) {
Lukasz Anforowicz38003582019-09-24 19:08:051522 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
1523 } else {
1524 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
1525 }
1526 } else {
1527 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
1528 }
1529 }
Aaron Colwell147926d2019-08-22 18:02:351530
1531 // Isolate |foo_origin| so we can't get a default SiteInstance.
Alex Moshchukef8c2562021-03-12 06:37:451532 p->AddFutureIsolatedOrigins({foo_origin}, IsolatedOriginSource::TEST,
1533 &browser_context);
Aaron Colwell147926d2019-08-22 18:02:351534
Alex Moshchuk989aa22c2024-11-06 02:09:071535 // Lock process to |foo_origin| origin and pretend that it's been committed.
Aaron Colwell147926d2019-08-22 18:02:351536 scoped_refptr<SiteInstanceImpl> foo_instance =
Alex Moshchuk331fa5f2021-03-10 06:16:591537 SiteInstanceImpl::CreateForTesting(&browser_context, foo_origin.GetURL());
Aaron Colwell147926d2019-08-22 18:02:351538 EXPECT_FALSE(foo_instance->IsDefaultSiteInstance());
Lukasz Anforowicz38003582019-09-24 19:08:051539 LockProcessIfNeeded(kRendererID, &browser_context, foo_origin.GetURL());
Alex Moshchuk989aa22c2024-11-06 02:09:071540 p->AddCommittedOrigin(kRendererID, foo_origin);
Aaron Colwell147926d2019-08-22 18:02:351541
1542 // Verify that access is no longer allowed for origins that are not associated
1543 // with foo.com.
Alex Moshchuk989aa22c2024-11-06 02:09:071544 for (const auto& origin : foo_origins) {
Aaron Colwell147926d2019-08-22 18:02:351545 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
Alex Moshchuk989aa22c2024-11-06 02:09:071546 }
Aaron Colwell147926d2019-08-22 18:02:351547
1548 for (const auto& origin : non_foo_origins)
1549 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
1550
1551 p->Remove(kRendererID);
1552
1553 // Post a task to the IO loop that then posts a task to the UI loop.
1554 // This should cause the |run_loop| to return after the removal has completed.
1555 base::RunLoop run_loop;
Gabriel Charettee7cdc5cd2020-05-27 23:35:051556 GetIOThreadTaskRunner({})->PostTaskAndReply(FROM_HERE, base::DoNothing(),
1557 run_loop.QuitClosure());
Aaron Colwell147926d2019-08-22 18:02:351558 run_loop.Run();
1559
1560 // Verify invalid ID is rejected now that Remove() has completed.
1561 for (const auto& origin : all_origins)
1562 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, origin)) << origin;
Aaron Colwell220d5022019-01-16 04:56:551563}
1564
Alex Moshchuk989aa22c2024-11-06 02:09:071565// Exercise the basic functionality of how MatchesCommittedOrigin() matches URLs
1566// against origins that have committed in a process. This test simulates an
1567// unlocked process that may commit origins from different sites (e.g., in a
1568// default SiteInstance on Android).
1569TEST_P(ChildProcessSecurityPolicyTest, MatchesCommittedOrigin) {
1570 ChildProcessSecurityPolicyImpl* p =
1571 ChildProcessSecurityPolicyImpl::GetInstance();
1572
1573 TestBrowserContext browser_context;
1574 p->AddForTesting(kRendererID, &browser_context);
1575
1576 auto foo_origin = url::Origin::Create(GURL("http://foo.com"));
1577
1578 // Helper wrapper for checking SecurityState::MatchesCommittedOrigin().
1579 auto matches_committed_origin = [&](const std::string& url,
1580 bool url_is_for_precursor_origin) {
1581 return p->MatchesCommittedOriginForTesting(kRendererID, GURL(url),
1582 url_is_for_precursor_origin);
1583 };
1584
1585 EXPECT_FALSE(matches_committed_origin("http://foo.com/", false));
1586
1587 // Pretend that the renderer has committed http://foo.com/.
1588 p->AddCommittedOrigin(kRendererID, foo_origin);
1589
1590 // These URLs should all match the http://foo.com/ origin.
1591 EXPECT_TRUE(matches_committed_origin("http://foo.com/", false));
1592 EXPECT_TRUE(matches_committed_origin("http://foo.com/foo/bar", false));
1593 EXPECT_TRUE(matches_committed_origin("blob:http://foo.com/uuid", false));
1594 EXPECT_TRUE(
1595 matches_committed_origin("filesystem:http://foo.com/some/path", false));
1596
1597 // These URLs should not match http://foo.com/.
1598 EXPECT_FALSE(matches_committed_origin("https://foo.com/", false));
1599 EXPECT_FALSE(matches_committed_origin("http://sub.foo.com/", false));
1600 EXPECT_FALSE(matches_committed_origin("http://foo.com:1234/", false));
1601 EXPECT_FALSE(matches_committed_origin("http://bar.com/", false));
1602 EXPECT_FALSE(matches_committed_origin("about:blank", false));
1603 EXPECT_FALSE(matches_committed_origin("data:,foo", false));
1604 EXPECT_FALSE(matches_committed_origin("file:///", false));
1605
1606 // If the URL is for a precursor, ideally it should not match a non-opaque
1607 // committed origin, but this has not been implemented yet - see TODO in
1608 // SecurityState::MatchesCommittedOrigin().
1609 //
1610 // TODO(crbug.com/40148776): Flip this expectation to false after fixing the
1611 // dedicated workers case.
1612 EXPECT_TRUE(matches_committed_origin("http://foo.com/", true));
1613
1614 // Add a second committed origin. Ensure both origins are matched properly.
1615 auto bar_origin = url::Origin::Create(GURL("http://bar.com"));
1616 p->AddCommittedOrigin(kRendererID, bar_origin);
1617 EXPECT_TRUE(matches_committed_origin("http://foo.com/", false));
1618 EXPECT_TRUE(matches_committed_origin("http://bar.com/", false));
1619 // TODO(crbug.com/40148776): Flip this expectation to false after fixing the
1620 // dedicated workers case.
1621 EXPECT_TRUE(matches_committed_origin("http://bar.com/", true));
1622
1623 // Add a third committed origin, an opaque origin with the http://foo.com
1624 // precursor.
1625 auto opaque_with_foo_precursor = foo_origin.DeriveNewOpaqueOrigin();
1626 p->AddCommittedOrigin(kRendererID, opaque_with_foo_precursor);
1627 EXPECT_TRUE(matches_committed_origin("http://foo.com/", true));
1628
1629 // These should still be true since both of these non-opaque origins have been
1630 // committed.
1631 EXPECT_TRUE(matches_committed_origin("http://foo.com/", false));
1632 EXPECT_TRUE(matches_committed_origin("http://bar.com/", false));
1633
1634 // Add another committed origin for a file URL.
1635 p->AddCommittedOrigin(kRendererID,
1636 url::Origin::Create(GURL("file:///etc/passwd")));
1637 EXPECT_TRUE(matches_committed_origin("file:///", false));
1638 // TODO(alexmos): This behavior of allowing file URL origins to match
1639 // regardless of their hosts might change in the future. See note in
1640 // SecurityState::MatchesCommittedOrigin().
1641 EXPECT_TRUE(matches_committed_origin("file://localhost/", false));
1642
1643 p->Remove(kRendererID);
1644}
1645
1646TEST_P(ChildProcessSecurityPolicyTest, SandboxedProcessEnforcements) {
Alex Moshchuk31e0f3452024-03-29 20:56:101647 ChildProcessSecurityPolicyImpl* p =
1648 ChildProcessSecurityPolicyImpl::GetInstance();
1649
1650 TestBrowserContext browser_context;
1651 p->AddForTesting(kRendererID, &browser_context);
1652
1653 // Create a ProcessLock for a process-isolated sandboxed frame, and lock the
1654 // kRendererID process to it.
1655 UrlInfo sandboxed_url_info(
1656 UrlInfoInit(GURL("https://foo.com")).WithSandbox(true));
1657 scoped_refptr<SiteInstanceImpl> sandboxed_instance =
1658 SiteInstanceImpl::CreateForUrlInfo(&browser_context, sandboxed_url_info,
1659 /*is_guest=*/false,
1660 /*is_fenced=*/false,
1661 /*is_fixed_storage_partition=*/false);
1662 p->LockProcess(sandboxed_instance->GetIsolationContext(), kRendererID,
1663 /*is_process_used=*/false,
1664 ProcessLock::FromSiteInfo(sandboxed_instance->GetSiteInfo()));
1665
1666 auto foo_origin = url::Origin::Create(GURL("https://foo.com"));
1667 auto opaque_foo_origin = foo_origin.DeriveNewOpaqueOrigin();
1668 auto bar_origin = url::Origin::Create(GURL("https://bar.com"));
1669 auto opaque_bar_origin = bar_origin.DeriveNewOpaqueOrigin();
1670
1671 using AccessType = ChildProcessSecurityPolicyImpl::AccessType;
1672
1673 // A sandboxed process should be able to commit new URLs, as long as they
1674 // have an opaque origin with a matching precursor.
1675 EXPECT_TRUE(p->CanAccessOrigin(kRendererID, opaque_foo_origin,
1676 AccessType::kCanCommitNewOrigin));
1677 // TODO(crbug.com/325410297): Currently, non-opaque origins are allowed to
1678 // commit. Fix this and flip the expectation to false.
1679 EXPECT_TRUE(p->CanAccessOrigin(kRendererID, foo_origin,
1680 AccessType::kCanCommitNewOrigin));
1681 EXPECT_FALSE(p->CanAccessOrigin(kRendererID, bar_origin,
1682 AccessType::kCanCommitNewOrigin));
1683 EXPECT_FALSE(p->CanAccessOrigin(kRendererID, opaque_bar_origin,
1684 AccessType::kCanCommitNewOrigin));
1685
Alex Moshchuk989aa22c2024-11-06 02:09:071686 // A sandboxed process should not be able to access data for any origin,
1687 // including origins it has committed.
1688 p->AddCommittedOrigin(kRendererID, opaque_foo_origin);
Alex Moshchuk31e0f3452024-03-29 20:56:101689 EXPECT_FALSE(
1690 p->CanAccessOrigin(kRendererID, opaque_foo_origin,
1691 AccessType::kCanAccessDataForCommittedOrigin));
1692 EXPECT_FALSE(p->CanAccessOrigin(
1693 kRendererID, foo_origin, AccessType::kCanAccessDataForCommittedOrigin));
1694 EXPECT_FALSE(p->CanAccessOrigin(
1695 kRendererID, bar_origin, AccessType::kCanAccessDataForCommittedOrigin));
1696 EXPECT_FALSE(
1697 p->CanAccessOrigin(kRendererID, opaque_bar_origin,
1698 AccessType::kCanAccessDataForCommittedOrigin));
1699
1700 // A sandboxed process should only be able to claim that it has an opaque
1701 // origin.
1702 EXPECT_TRUE(p->CanAccessOrigin(kRendererID, opaque_foo_origin,
1703 AccessType::kHostsOrigin));
Alex Moshchuk9def4ad2024-05-03 20:06:421704 EXPECT_FALSE(
Alex Moshchuk31e0f3452024-03-29 20:56:101705 p->CanAccessOrigin(kRendererID, foo_origin, AccessType::kHostsOrigin));
1706 EXPECT_FALSE(
1707 p->CanAccessOrigin(kRendererID, bar_origin, AccessType::kHostsOrigin));
1708 EXPECT_FALSE(p->CanAccessOrigin(kRendererID, opaque_bar_origin,
1709 AccessType::kHostsOrigin));
1710
1711 p->Remove(kRendererID);
1712}
1713
Alex Moshchuk989aa22c2024-11-06 02:09:071714TEST_P(ChildProcessSecurityPolicyTest, PdfProcessEnforcements) {
Alex Moshchuk304a54b2024-06-26 15:58:541715 ChildProcessSecurityPolicyImpl* p =
1716 ChildProcessSecurityPolicyImpl::GetInstance();
1717
1718 TestBrowserContext browser_context;
1719 p->AddForTesting(kRendererID, &browser_context);
1720
1721 // Create a ProcessLock for a PDF renderer, and lock the kRendererID process
1722 // to it.
1723 UrlInfo pdf_url_info(UrlInfoInit(GURL("https://foo.com")).WithIsPdf(true));
1724 scoped_refptr<SiteInstanceImpl> pdf_instance =
1725 SiteInstanceImpl::CreateForUrlInfo(&browser_context, pdf_url_info,
1726 /*is_guest=*/false,
1727 /*is_fenced=*/false,
1728 /*is_fixed_storage_partition=*/false);
1729 p->LockProcess(pdf_instance->GetIsolationContext(), kRendererID,
1730 /*is_process_used=*/false,
1731 ProcessLock::FromSiteInfo(pdf_instance->GetSiteInfo()));
1732
1733 auto foo_origin = url::Origin::Create(GURL("https://foo.com"));
1734 auto bar_origin = url::Origin::Create(GURL("https://bar.com"));
1735
1736 using AccessType = ChildProcessSecurityPolicyImpl::AccessType;
1737
1738 // A PDF process should be able to commit new URLs that match its ProcessLock.
1739 EXPECT_TRUE(p->CanAccessOrigin(kRendererID, foo_origin,
1740 AccessType::kCanCommitNewOrigin));
1741 EXPECT_FALSE(p->CanAccessOrigin(kRendererID, bar_origin,
1742 AccessType::kCanCommitNewOrigin));
1743
Alex Moshchuk989aa22c2024-11-06 02:09:071744 // A PDF process should also be able to host an origin that matches its
1745 // ProcessLock; for example, PDF documents can still use postMessage so they
1746 // need to use this to validate the source origin.
1747 p->AddCommittedOrigin(kRendererID, foo_origin);
Alex Moshchuk304a54b2024-06-26 15:58:541748 EXPECT_TRUE(
1749 p->CanAccessOrigin(kRendererID, foo_origin, AccessType::kHostsOrigin));
1750 EXPECT_FALSE(
1751 p->CanAccessOrigin(kRendererID, bar_origin, AccessType::kHostsOrigin));
1752
Alex Moshchuk989aa22c2024-11-06 02:09:071753 // A PDF process should not be able to access data for any origin, including
1754 // an origin that it has committed.
Alex Moshchuk304a54b2024-06-26 15:58:541755 EXPECT_FALSE(p->CanAccessOrigin(
1756 kRendererID, foo_origin, AccessType::kCanAccessDataForCommittedOrigin));
1757 EXPECT_FALSE(p->CanAccessOrigin(
1758 kRendererID, bar_origin, AccessType::kCanAccessDataForCommittedOrigin));
1759
1760 p->Remove(kRendererID);
1761}
1762
paulmeyer1eefa26e2015-10-01 02:11:131763// Test the granting of origin permissions, and their interactions with
1764// granting scheme permissions.
Alex Moshchuk989aa22c2024-11-06 02:09:071765TEST_P(ChildProcessSecurityPolicyTest, OriginGranting) {
paulmeyer1eefa26e2015-10-01 02:11:131766 ChildProcessSecurityPolicyImpl* p =
1767 ChildProcessSecurityPolicyImpl::GetInstance();
1768
Matt Siembor9cb08392019-04-24 21:34:391769 GURL url_foo1(GetWebUIURL("foo/resource1"));
1770 GURL url_foo2(GetWebUIURL("foo/resource2"));
1771 GURL url_bar(GetWebUIURL("bar/resource3"));
paulmeyer1eefa26e2015-10-01 02:11:131772
Aaron Colwellffade2a2020-09-16 20:54:411773 p->AddForTesting(kRendererID, browser_context());
Lukasz Anforowicz38003582019-09-24 19:08:051774 LockProcessIfNeeded(kRendererID, browser_context(), url_foo1);
1775
paulmeyer1eefa26e2015-10-01 02:11:131776 EXPECT_FALSE(p->CanRequestURL(kRendererID, url_foo1));
1777 EXPECT_FALSE(p->CanRequestURL(kRendererID, url_foo2));
1778 EXPECT_FALSE(p->CanRequestURL(kRendererID, url_bar));
arthursonzogni98e5a232017-07-13 15:18:161779 EXPECT_TRUE(p->CanRedirectToURL(url_foo1));
1780 EXPECT_TRUE(p->CanRedirectToURL(url_foo2));
1781 EXPECT_TRUE(p->CanRedirectToURL(url_bar));
paulmeyer1eefa26e2015-10-01 02:11:131782 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_foo1));
1783 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_foo2));
1784 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_bar));
1785
Daniel Cheng4ebba552018-07-06 21:43:161786 p->GrantRequestOrigin(kRendererID, url::Origin::Create(url_foo1));
1787
1788 EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
1789 EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
1790 EXPECT_FALSE(p->CanRequestURL(kRendererID, url_bar));
1791 EXPECT_TRUE(p->CanRedirectToURL(url_foo1));
1792 EXPECT_TRUE(p->CanRedirectToURL(url_foo2));
1793 EXPECT_TRUE(p->CanRedirectToURL(url_bar));
1794 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_foo1));
1795 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_foo2));
1796 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_bar));
Daniel Cheng4ebba552018-07-06 21:43:161797
1798 p->GrantCommitOrigin(kRendererID, url::Origin::Create(url_foo1));
paulmeyer1eefa26e2015-10-01 02:11:131799
1800 EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
1801 EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
1802 EXPECT_FALSE(p->CanRequestURL(kRendererID, url_bar));
arthursonzogni98e5a232017-07-13 15:18:161803 EXPECT_TRUE(p->CanRedirectToURL(url_foo1));
1804 EXPECT_TRUE(p->CanRedirectToURL(url_foo2));
1805 EXPECT_TRUE(p->CanRedirectToURL(url_bar));
paulmeyer1eefa26e2015-10-01 02:11:131806 EXPECT_TRUE(p->CanCommitURL(kRendererID, url_foo1));
1807 EXPECT_TRUE(p->CanCommitURL(kRendererID, url_foo2));
1808 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_bar));
1809
Daniel Cheng4ebba552018-07-06 21:43:161810 // Make sure this doesn't overwrite the earlier commit grants.
1811 p->GrantRequestOrigin(kRendererID, url::Origin::Create(url_foo1));
paulmeyer1eefa26e2015-10-01 02:11:131812
1813 EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
1814 EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
Daniel Cheng4ebba552018-07-06 21:43:161815 EXPECT_FALSE(p->CanRequestURL(kRendererID, url_bar));
arthursonzogni98e5a232017-07-13 15:18:161816 EXPECT_TRUE(p->CanRedirectToURL(url_foo1));
1817 EXPECT_TRUE(p->CanRedirectToURL(url_foo2));
1818 EXPECT_TRUE(p->CanRedirectToURL(url_bar));
paulmeyer1eefa26e2015-10-01 02:11:131819 EXPECT_TRUE(p->CanCommitURL(kRendererID, url_foo1));
1820 EXPECT_TRUE(p->CanCommitURL(kRendererID, url_foo2));
Daniel Cheng4ebba552018-07-06 21:43:161821 EXPECT_FALSE(p->CanCommitURL(kRendererID, url_bar));
paulmeyer1eefa26e2015-10-01 02:11:131822
1823 p->Remove(kRendererID);
1824}
Alex Moshchuk4e19b362018-09-10 21:14:361825
Lukasz Anforowicz5e71bd42018-09-17 19:28:571826#define LOCKED_EXPECT_THAT(lock, value, matcher) \
1827 do { \
1828 base::AutoLock auto_lock(lock); \
1829 EXPECT_THAT(value, matcher); \
1830 } while (0);
1831
Alex Moshchukef8c2562021-03-12 06:37:451832// Verifies ChildProcessSecurityPolicyImpl::AddFutureIsolatedOrigins method.
Alex Moshchuk989aa22c2024-11-06 02:09:071833TEST_P(ChildProcessSecurityPolicyTest, AddFutureIsolatedOrigins) {
Lukasz Anforowicz0672f8a2017-11-30 01:07:061834 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
1835 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
1836 url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
Alex Moshchuk4e19b362018-09-10 21:14:361837 url::Origin quxfoo = url::Origin::Create(GURL("https://qux.foo.com/"));
Lukasz Anforowicz25420932018-12-18 20:59:221838 url::Origin baz_http = url::Origin::Create(GURL("http://baz.com/"));
Lukasz Anforowicz0672f8a2017-11-30 01:07:061839 url::Origin baz_http_8000 = url::Origin::Create(GURL("http://baz.com:8000/"));
1840 url::Origin baz_https_8000 =
1841 url::Origin::Create(GURL("https://baz.com:8000/"));
1842 url::Origin invalid_etld = url::Origin::Create(GURL("https://gov/"));
Andrew Stone0a177fe22019-06-26 08:12:041843
Lukasz Anforowicz0672f8a2017-11-30 01:07:061844 ChildProcessSecurityPolicyImpl* p =
1845 ChildProcessSecurityPolicyImpl::GetInstance();
paulmeyer1eefa26e2015-10-01 02:11:131846
Lukasz Anforowicz0672f8a2017-11-30 01:07:061847 // Initially there should be no isolated origins.
Alex Moshchukf01172e2019-01-16 00:54:171848 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
1849 testing::IsEmpty());
alexmos3b9ad102017-05-26 23:41:081850
Lukasz Anforowicz0672f8a2017-11-30 01:07:061851 // Verify deduplication of the argument.
Alex Moshchukef8c2562021-03-12 06:37:451852 p->AddFutureIsolatedOrigins({foo, bar, bar}, IsolatedOriginSource::TEST);
Alex Moshchuk8e5c1952019-01-15 03:39:501853 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:171854 p->isolated_origins_lock_, p->isolated_origins_,
Alex Moshchuk8e5c1952019-01-15 03:39:501855 testing::UnorderedElementsAre(GetIsolatedOriginEntry(foo),
1856 GetIsolatedOriginEntry(bar)));
alexmos3b9ad102017-05-26 23:41:081857
Lukasz Anforowicz0672f8a2017-11-30 01:07:061858 // Verify that the old set is extended (not replaced).
Alex Moshchukef8c2562021-03-12 06:37:451859 p->AddFutureIsolatedOrigins({baz}, IsolatedOriginSource::TEST);
Alex Moshchuk8e5c1952019-01-15 03:39:501860 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:171861 p->isolated_origins_lock_, p->isolated_origins_,
Alex Moshchuk8e5c1952019-01-15 03:39:501862 testing::UnorderedElementsAre(GetIsolatedOriginEntry(foo),
1863 GetIsolatedOriginEntry(bar),
1864 GetIsolatedOriginEntry(baz)));
Lukasz Anforowicz0672f8a2017-11-30 01:07:061865
1866 // Verify deduplication against the old set.
Alex Moshchukef8c2562021-03-12 06:37:451867 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST);
Alex Moshchuk8e5c1952019-01-15 03:39:501868 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:171869 p->isolated_origins_lock_, p->isolated_origins_,
Alex Moshchuk8e5c1952019-01-15 03:39:501870 testing::UnorderedElementsAre(GetIsolatedOriginEntry(foo),
1871 GetIsolatedOriginEntry(bar),
1872 GetIsolatedOriginEntry(baz)));
Lukasz Anforowicz0672f8a2017-11-30 01:07:061873
Alex Moshchuk4e19b362018-09-10 21:14:361874 // Verify deduplication considers scheme and port differences. Note that
1875 // origins that differ only in ports map to the same key.
Alex Moshchukef8c2562021-03-12 06:37:451876 p->AddFutureIsolatedOrigins({baz, baz_http_8000, baz_https_8000},
1877 IsolatedOriginSource::TEST);
Lukasz Anforowicz25420932018-12-18 20:59:221878 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:171879 p->isolated_origins_lock_, p->isolated_origins_,
Lukasz Anforowicz25420932018-12-18 20:59:221880 testing::UnorderedElementsAre(
Alex Moshchuk8e5c1952019-01-15 03:39:501881 GetIsolatedOriginEntry(foo), GetIsolatedOriginEntry(bar),
1882 GetIsolatedOriginEntry(baz), GetIsolatedOriginEntry(baz_http)));
Lukasz Anforowicz0672f8a2017-11-30 01:07:061883
1884 // Verify that adding an origin that is invalid for isolation will 1) log a
1885 // warning and 2) won't CHECK or crash the browser process, 3) will not add
1886 // the invalid origin, but will add the remaining origins passed to
Alex Moshchukef8c2562021-03-12 06:37:451887 // AddFutureIsolatedOrigins. Note that the new |quxfoo| origin should map to
1888 // the same key (i.e., the https://foo.com/ site URL) as the existing |foo|
Alex Moshchuk4e19b362018-09-10 21:14:361889 // origin.
Lukasz Anforowicz0672f8a2017-11-30 01:07:061890 {
1891 base::test::MockLog mock_log;
1892 EXPECT_CALL(mock_log,
Peter Boström9c202bb2024-01-05 05:33:061893 Log(::logging::LOGGING_ERROR, testing::_, testing::_,
1894 testing::_, testing::HasSubstr(invalid_etld.Serialize())))
Lukasz Anforowicz0672f8a2017-11-30 01:07:061895 .Times(1);
1896
1897 mock_log.StartCapturingLogs();
Alex Moshchukef8c2562021-03-12 06:37:451898 p->AddFutureIsolatedOrigins({quxfoo, invalid_etld},
1899 IsolatedOriginSource::TEST);
Lukasz Anforowicz5e71bd42018-09-17 19:28:571900 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:171901 p->isolated_origins_lock_, p->isolated_origins_,
Lukasz Anforowicz25420932018-12-18 20:59:221902 testing::UnorderedElementsAre(
Alex Moshchuk8e5c1952019-01-15 03:39:501903 GetIsolatedOriginEntry(foo, quxfoo), GetIsolatedOriginEntry(bar),
1904 GetIsolatedOriginEntry(baz), GetIsolatedOriginEntry(baz_http)));
Lukasz Anforowicz0672f8a2017-11-30 01:07:061905 }
Alex Moshchuk8e5c1952019-01-15 03:39:501906
Andrew Stone0a177fe22019-06-26 08:12:041907 // Verify that adding invalid origins via the string variant of
Alex Moshchukef8c2562021-03-12 06:37:451908 // AddFutureIsolatedOrigins() logs a warning.
Andrew Stone0a177fe22019-06-26 08:12:041909 {
1910 base::test::MockLog mock_log;
Peter Boström9c202bb2024-01-05 05:33:061911 EXPECT_CALL(mock_log, Log(::logging::LOGGING_ERROR, testing::_, testing::_,
Andrew Stone0a177fe22019-06-26 08:12:041912 testing::_, testing::HasSubstr("about:blank")))
1913 .Times(1);
1914
1915 mock_log.StartCapturingLogs();
Alex Moshchukef8c2562021-03-12 06:37:451916 p->AddFutureIsolatedOrigins("about:blank", IsolatedOriginSource::TEST);
Andrew Stone0a177fe22019-06-26 08:12:041917 }
1918
Alex Moshchuk8e5c1952019-01-15 03:39:501919 p->RemoveIsolatedOriginForTesting(foo);
1920 p->RemoveIsolatedOriginForTesting(quxfoo);
1921 p->RemoveIsolatedOriginForTesting(bar);
1922 p->RemoveIsolatedOriginForTesting(baz);
1923 p->RemoveIsolatedOriginForTesting(baz_http);
Andrew Stone6ed99b22019-06-07 06:14:391924
1925 // We should have removed all isolated origins at this point.
1926 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
1927 testing::IsEmpty());
1928}
1929
Alex Moshchuk989aa22c2024-11-06 02:09:071930TEST_P(ChildProcessSecurityPolicyTest, IsolateAllSuborigins) {
Andrew Stone6ed99b22019-06-07 06:14:391931 url::Origin qux = url::Origin::Create(GURL("https://qux.com/"));
Andrew Stone404880d2019-07-10 02:23:311932 IsolatedOriginPattern etld1_wild("https://[*.]foo.com");
1933 IsolatedOriginPattern etld2_wild("https://[*.]bar.foo.com");
Andrew Stone6ed99b22019-06-07 06:14:391934 url::Origin etld1 = url::Origin::Create(GURL("https://foo.com"));
1935 url::Origin etld2 = url::Origin::Create(GURL("https://bar.foo.com"));
1936
1937 ChildProcessSecurityPolicyImpl* p =
1938 ChildProcessSecurityPolicyImpl::GetInstance();
1939
1940 // Check we can add a single wildcard origin.
Alex Moshchukef8c2562021-03-12 06:37:451941 p->AddFutureIsolatedOrigins({etld1_wild}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:391942
1943 LOCKED_EXPECT_THAT(
1944 p->isolated_origins_lock_, p->isolated_origins_,
1945 testing::UnorderedElementsAre(GetIsolatedOriginEntry(etld1, true)));
1946
1947 // Add a conventional origin and check they can live side by side.
Alex Moshchukef8c2562021-03-12 06:37:451948 p->AddFutureIsolatedOrigins({qux}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:391949 LOCKED_EXPECT_THAT(
1950 p->isolated_origins_lock_, p->isolated_origins_,
1951 testing::UnorderedElementsAre(GetIsolatedOriginEntry(etld1, true),
1952 GetIsolatedOriginEntry(qux, false)));
1953
1954 // Check that a wildcard domain within another wildcard domain can be added.
Alex Moshchukef8c2562021-03-12 06:37:451955 p->AddFutureIsolatedOrigins({etld2_wild}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:391956 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
1957 testing::UnorderedElementsAre(
1958 GetIsolatedOriginEntry(etld1, etld2, true, true),
1959 GetIsolatedOriginEntry(qux, false)));
1960
1961 // Check that removing a single wildcard domain, that contains another
1962 // wildcard domain, doesn't affect the isolating behavior of the original
1963 // wildcard domain.
1964 p->RemoveIsolatedOriginForTesting(etld1);
1965 LOCKED_EXPECT_THAT(
1966 p->isolated_origins_lock_, p->isolated_origins_,
1967 testing::UnorderedElementsAre(GetIsolatedOriginEntry(etld2, true),
1968 GetIsolatedOriginEntry(qux, false)));
1969
1970 // Removing remaining domains.
1971 p->RemoveIsolatedOriginForTesting(qux);
1972 p->RemoveIsolatedOriginForTesting(etld2);
1973
1974 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
1975 testing::IsEmpty());
1976}
1977
1978// Verify that the isolation behavior for wildcard and non-wildcard origins,
1979// singly or in concert, behaves correctly via calls to GetSiteForURL().
Alex Moshchuk989aa22c2024-11-06 02:09:071980TEST_P(ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
W. James MacLean5eaf0bd2024-06-26 21:15:321981 WildcardAndNonWildcardOrigins) {
Andrew Stone6ed99b22019-06-07 06:14:391982 ChildProcessSecurityPolicyImpl* p =
1983 ChildProcessSecurityPolicyImpl::GetInstance();
1984
1985 // There should be no isolated origins before this test starts.
1986 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
1987 testing::IsEmpty());
1988
1989 // Construct a simple case, a single isolated origin.
1990 // IsolatedOriginPattern isolated("https://isolated.com");
1991 IsolatedOriginPattern inner_isolated("https://inner.isolated.com");
Andrew Stone404880d2019-07-10 02:23:311992 IsolatedOriginPattern wildcard("https://[*.]wildcard.com");
1993 IsolatedOriginPattern inner_wildcard("https://[*.]inner.wildcard.com");
Andrew Stone6ed99b22019-06-07 06:14:391994
1995 GURL isolated_url("https://isolated.com");
1996 GURL inner_isolated_url("https://inner.isolated.com");
1997 GURL host_inner_isolated_url("https://host.inner.isolated.com");
1998 GURL wildcard_url("https://wildcard.com");
1999 GURL inner_wildcard_url("https://inner.wildcard.com");
2000 GURL host_inner_wildcard_url("https://host.inner.wildcard.com");
2001 GURL unrelated_url("https://unrelated.com");
2002
2003 // Verify the isolation behavior of the test patterns before isolating any
2004 // domains.
2005 std::map<GURL, GURL> origins_site_test_map{
2006 {isolated_url, isolated_url},
2007 {inner_isolated_url, isolated_url},
2008 {host_inner_isolated_url, isolated_url},
2009 {wildcard_url, wildcard_url},
2010 {inner_wildcard_url, wildcard_url},
2011 {host_inner_wildcard_url, wildcard_url},
2012 {unrelated_url, unrelated_url},
2013 };
2014 CheckGetSiteForURL(browser_context(), origins_site_test_map);
2015
2016 // Add |wildcard|, a wildcard origin from a different domain, then verify that
2017 // the existing behavior of |isolated_url| and |inner_isolated_url| remains
2018 // unaffected, while all subdomains of wildcard.com are returned as unique
2019 // sites.
Alex Moshchukef8c2562021-03-12 06:37:452020 p->AddFutureIsolatedOrigins({wildcard}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392021 origins_site_test_map[inner_wildcard_url] = inner_wildcard_url;
2022 origins_site_test_map[host_inner_wildcard_url] = host_inner_wildcard_url;
2023 CheckGetSiteForURL(browser_context(), origins_site_test_map);
2024
2025 // Add |inner_isolated|, then verify that querying for |inner_isolated_url|
2026 // returns |inner_isolated_url| while leaving the wildcard origins unaffected.
Alex Moshchukef8c2562021-03-12 06:37:452027 p->AddFutureIsolatedOrigins({inner_isolated}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392028 origins_site_test_map[inner_isolated_url] = inner_isolated_url;
2029 origins_site_test_map[host_inner_isolated_url] = inner_isolated_url;
2030 CheckGetSiteForURL(browser_context(), origins_site_test_map);
2031
2032 // Add |inner_wildcard|. This should not change the behavior of the test
2033 // above as all subdomains of |inner_wildcard| are contained within
2034 // |wildcard|.
Alex Moshchukef8c2562021-03-12 06:37:452035 p->AddFutureIsolatedOrigins({inner_wildcard}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392036 CheckGetSiteForURL(browser_context(), origins_site_test_map);
2037
2038 p->RemoveIsolatedOriginForTesting(wildcard.origin());
2039 p->RemoveIsolatedOriginForTesting(inner_isolated.origin());
2040 p->RemoveIsolatedOriginForTesting(inner_wildcard.origin());
2041
2042 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2043 testing::IsEmpty());
2044}
2045
Alex Moshchuk989aa22c2024-11-06 02:09:072046TEST_P(ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
W. James MacLean5eaf0bd2024-06-26 21:15:322047 WildcardAndNonWildcardEmbedded) {
Andrew Stone6ed99b22019-06-07 06:14:392048 ChildProcessSecurityPolicyImpl* p =
2049 ChildProcessSecurityPolicyImpl::GetInstance();
2050
2051 // There should be no isolated origins before this test starts.
2052 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2053 testing::IsEmpty());
2054
2055 {
2056 // Test the behavior of a wildcard origin contained within a single
2057 // isolated origin. Removing the isolated origin should have no effect on
2058 // the wildcard origin.
2059 IsolatedOriginPattern isolated("https://isolated.com");
Andrew Stone404880d2019-07-10 02:23:312060 IsolatedOriginPattern wildcard_isolated(
2061 "https://[*.]wildcard.isolated.com");
Andrew Stone6ed99b22019-06-07 06:14:392062
2063 GURL isolated_url("https://isolated.com");
2064 GURL a_isolated_url("https://a.isolated.com");
2065 GURL wildcard_isolated_url("https://wildcard.isolated.com");
2066 GURL a_wildcard_isolated_url("https://a.wildcard.isolated.com");
2067
Alex Moshchukef8c2562021-03-12 06:37:452068 p->AddFutureIsolatedOrigins({isolated, wildcard_isolated},
2069 IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392070 std::map<GURL, GURL> origin_site_map{
2071 {isolated_url, isolated_url},
2072 {a_isolated_url, isolated_url},
2073 {wildcard_isolated_url, wildcard_isolated_url},
2074 {a_wildcard_isolated_url, a_wildcard_isolated_url},
2075 };
2076
2077 CheckGetSiteForURL(browser_context(), origin_site_map);
2078
2079 p->RemoveIsolatedOriginForTesting(isolated.origin());
2080 p->RemoveIsolatedOriginForTesting(wildcard_isolated.origin());
2081 }
2082
2083 // No isolated origins should persist between tests.
2084 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2085 testing::IsEmpty());
2086
2087 {
2088 // A single isolated origin is nested within a wildcard origin. In this
2089 // scenario the wildcard origin supersedes isolated origins.
Andrew Stone404880d2019-07-10 02:23:312090 IsolatedOriginPattern wildcard("https://[*.]wildcard.com");
Andrew Stone6ed99b22019-06-07 06:14:392091 IsolatedOriginPattern isolated_wildcard("https://isolated.wildcard.com");
2092
2093 GURL wildcard_url("https://wildcard.com");
2094 GURL a_wildcard_url("https://a.wildcard.com");
2095 GURL isolated_wildcard_url("https://isolated.wildcard.com");
2096 GURL a_isolated_wildcard_url("https://a.isolated.wildcard.com");
2097
Alex Moshchukef8c2562021-03-12 06:37:452098 p->AddFutureIsolatedOrigins({wildcard, isolated_wildcard},
2099 IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392100 std::map<GURL, GURL> origin_site_map{
2101 {wildcard_url, wildcard_url},
2102 {a_wildcard_url, a_wildcard_url},
2103 {isolated_wildcard_url, isolated_wildcard_url},
2104 {a_isolated_wildcard_url, a_isolated_wildcard_url},
2105 };
2106
2107 CheckGetSiteForURL(browser_context(), origin_site_map);
2108
2109 p->RemoveIsolatedOriginForTesting(wildcard.origin());
2110 p->RemoveIsolatedOriginForTesting(isolated_wildcard.origin());
2111 }
2112
2113 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2114 testing::IsEmpty());
2115
2116 {
2117 // Nest wildcard isolated origins within each other. Verify that removing
2118 // the outer wildcard origin doesn't affect the inner one.
Andrew Stone404880d2019-07-10 02:23:312119 IsolatedOriginPattern outer("https://[*.]outer.com");
2120 IsolatedOriginPattern inner("https://[*.]inner.outer.com");
Andrew Stone6ed99b22019-06-07 06:14:392121
2122 GURL outer_url("https://outer.com");
2123 GURL a_outer_url("https://a.outer.com");
2124 GURL inner_url("https://inner.outer.com");
2125 GURL a_inner_url("https://a.inner.outer.com");
2126
Alex Moshchukef8c2562021-03-12 06:37:452127 p->AddFutureIsolatedOrigins({inner, outer}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392128
2129 std::map<GURL, GURL> origin_site_map{
2130 {outer_url, outer_url},
2131 {a_outer_url, a_outer_url},
2132 {inner_url, inner_url},
2133 {a_inner_url, a_inner_url},
2134 };
2135
2136 CheckGetSiteForURL(browser_context(), origin_site_map);
2137 p->RemoveIsolatedOriginForTesting(outer.origin());
2138 p->RemoveIsolatedOriginForTesting(inner.origin());
2139 }
2140
2141 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2142 testing::IsEmpty());
2143
2144 // Verify that adding a wildcard domain then a then a conventional domain
2145 // doesn't affect the isolating behavior of the wildcard, i.e. whichever
2146 // isolated domain is added entered 'wins'.
2147 {
Andrew Stone404880d2019-07-10 02:23:312148 IsolatedOriginPattern wild("https://[*.]bar.foo.com");
Andrew Stone6ed99b22019-06-07 06:14:392149 IsolatedOriginPattern single("https://bar.foo.com");
2150
2151 GURL host_url("https://host.bar.foo.com");
2152
Alex Moshchukef8c2562021-03-12 06:37:452153 p->AddFutureIsolatedOrigins({wild}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392154 std::map<GURL, GURL> origin_site_map{
2155 {host_url, host_url},
2156 };
2157
2158 CheckGetSiteForURL(browser_context(), origin_site_map);
2159
Alex Moshchukef8c2562021-03-12 06:37:452160 p->AddFutureIsolatedOrigins({single}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392161
2162 CheckGetSiteForURL(browser_context(), origin_site_map);
2163
2164 p->RemoveIsolatedOriginForTesting(wild.origin());
2165 p->RemoveIsolatedOriginForTesting(single.origin());
2166 }
2167
2168 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2169 testing::IsEmpty());
2170
2171 // Verify the first domain added remains dominant in the case of differing
2172 // wildcard and non-wildcard statuses.
2173 {
Andrew Stone404880d2019-07-10 02:23:312174 IsolatedOriginPattern wild("https://[*.]bar.foo.com");
Andrew Stone6ed99b22019-06-07 06:14:392175 IsolatedOriginPattern single("https://bar.foo.com");
2176
2177 GURL host_url("https://host.bar.foo.com");
2178 GURL domain_url("https://bar.foo.com");
2179
Alex Moshchukef8c2562021-03-12 06:37:452180 p->AddFutureIsolatedOrigins({single}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392181 std::map<GURL, GURL> origin_site_map{
2182 {host_url, domain_url},
2183 };
2184
2185 CheckGetSiteForURL(browser_context(), origin_site_map);
2186
Alex Moshchukef8c2562021-03-12 06:37:452187 p->AddFutureIsolatedOrigins({wild}, IsolatedOriginSource::TEST);
Andrew Stone6ed99b22019-06-07 06:14:392188
2189 CheckGetSiteForURL(browser_context(), origin_site_map);
2190
2191 p->RemoveIsolatedOriginForTesting(wild.origin());
2192 p->RemoveIsolatedOriginForTesting(single.origin());
2193 }
2194
2195 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2196 testing::IsEmpty());
Alex Moshchuk8e5c1952019-01-15 03:39:502197}
2198
2199// Verifies that isolated origins only apply to future BrowsingInstances.
Alex Moshchuk989aa22c2024-11-06 02:09:072200TEST_P(ChildProcessSecurityPolicyTest, DynamicIsolatedOrigins) {
Alex Moshchuk8e5c1952019-01-15 03:39:502201 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
2202 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
2203 url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
2204 url::Origin qux = url::Origin::Create(GURL("https://qux.com/"));
2205 ChildProcessSecurityPolicyImpl* p =
2206 ChildProcessSecurityPolicyImpl::GetInstance();
2207
2208 // Initially there should be no isolated origins.
Alex Moshchukf01172e2019-01-16 00:54:172209 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2210 testing::IsEmpty());
Alex Moshchuk8e5c1952019-01-15 03:39:502211
Alex Moshchuk67bc0732019-01-18 21:23:332212 // Save the next BrowsingInstance ID to be created. Because unit tests run
2213 // in batches, this isn't guaranteed to always be 1, for example if a
2214 // previous test in the same batch had already created a SiteInstance and
2215 // BrowsingInstance.
Lukasz Anforowicz15ba43e2021-07-21 22:50:092216 BrowsingInstanceId initial_id(SiteInstanceImpl::NextBrowsingInstanceId());
Alex Moshchuk8e5c1952019-01-15 03:39:502217
2218 // Isolate foo.com and bar.com.
Alex Moshchukef8c2562021-03-12 06:37:452219 p->AddFutureIsolatedOrigins({foo, bar}, IsolatedOriginSource::TEST);
Alex Moshchuk8e5c1952019-01-15 03:39:502220 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:172221 p->isolated_origins_lock_, p->isolated_origins_,
Alex Moshchuk67bc0732019-01-18 21:23:332222 testing::UnorderedElementsAre(GetIsolatedOriginEntry(initial_id, foo),
2223 GetIsolatedOriginEntry(initial_id, bar)));
Alex Moshchuk8e5c1952019-01-15 03:39:502224
2225 // Isolating bar.com again should have no effect.
Alex Moshchukef8c2562021-03-12 06:37:452226 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST);
Alex Moshchuk8e5c1952019-01-15 03:39:502227 LOCKED_EXPECT_THAT(
Alex Moshchukf01172e2019-01-16 00:54:172228 p->isolated_origins_lock_, p->isolated_origins_,
Alex Moshchuk67bc0732019-01-18 21:23:332229 testing::UnorderedElementsAre(GetIsolatedOriginEntry(initial_id, foo),
2230 GetIsolatedOriginEntry(initial_id, bar)));
Alex Moshchuk8e5c1952019-01-15 03:39:502231
Alex Moshchuk67bc0732019-01-18 21:23:332232 // Create a new BrowsingInstance. Its ID will be |initial_id|.
Alex Moshchuk99b795422019-03-07 00:27:322233 TestBrowserContext context;
2234 scoped_refptr<SiteInstanceImpl> foo_instance =
Alex Moshchuk331fa5f2021-03-10 06:16:592235 SiteInstanceImpl::CreateForTesting(&context, GURL("https://foo.com/"));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092236 EXPECT_EQ(initial_id,
Alex Moshchuk8e5c1952019-01-15 03:39:502237 foo_instance->GetIsolationContext().browsing_instance_id());
Lukasz Anforowicz15ba43e2021-07-21 22:50:092238 EXPECT_EQ(BrowsingInstanceId::FromUnsafeValue(initial_id.value() + 1),
Alex Moshchuk8e5c1952019-01-15 03:39:502239 SiteInstanceImpl::NextBrowsingInstanceId());
2240
Alex Moshchuk67bc0732019-01-18 21:23:332241 // Isolate baz.com. This will apply to BrowsingInstances with IDs
2242 // |initial_id + 1| and above.
Alex Moshchukef8c2562021-03-12 06:37:452243 p->AddFutureIsolatedOrigins({baz}, IsolatedOriginSource::TEST);
Alex Moshchuk67bc0732019-01-18 21:23:332244 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2245 testing::UnorderedElementsAre(
2246 GetIsolatedOriginEntry(initial_id, foo),
2247 GetIsolatedOriginEntry(initial_id, bar),
Lukasz Anforowicz15ba43e2021-07-21 22:50:092248 GetIsolatedOriginEntry(initial_id.value() + 1, baz)));
Alex Moshchuk8e5c1952019-01-15 03:39:502249
2250 // Isolating bar.com again should not update the old BrowsingInstance ID.
Alex Moshchukef8c2562021-03-12 06:37:452251 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST);
Alex Moshchuk67bc0732019-01-18 21:23:332252 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2253 testing::UnorderedElementsAre(
2254 GetIsolatedOriginEntry(initial_id, foo),
2255 GetIsolatedOriginEntry(initial_id, bar),
Lukasz Anforowicz15ba43e2021-07-21 22:50:092256 GetIsolatedOriginEntry(initial_id.value() + 1, baz)));
Alex Moshchuk8e5c1952019-01-15 03:39:502257
2258 // Create another BrowsingInstance.
Alex Moshchuk99b795422019-03-07 00:27:322259 scoped_refptr<SiteInstanceImpl> bar_instance =
Alex Moshchuk331fa5f2021-03-10 06:16:592260 SiteInstanceImpl::CreateForTesting(&context, GURL("https://bar.com/"));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092261 EXPECT_EQ(BrowsingInstanceId::FromUnsafeValue(initial_id.value() + 1),
Alex Moshchuk8e5c1952019-01-15 03:39:502262 bar_instance->GetIsolationContext().browsing_instance_id());
Lukasz Anforowicz15ba43e2021-07-21 22:50:092263 EXPECT_EQ(BrowsingInstanceId::FromUnsafeValue(initial_id.value() + 2),
Alex Moshchuk8e5c1952019-01-15 03:39:502264 SiteInstanceImpl::NextBrowsingInstanceId());
2265
2266 // Isolate qux.com.
Alex Moshchukef8c2562021-03-12 06:37:452267 p->AddFutureIsolatedOrigins({qux}, IsolatedOriginSource::TEST);
Alex Moshchuk67bc0732019-01-18 21:23:332268 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2269 testing::UnorderedElementsAre(
2270 GetIsolatedOriginEntry(initial_id, foo),
2271 GetIsolatedOriginEntry(initial_id, bar),
Lukasz Anforowicz15ba43e2021-07-21 22:50:092272 GetIsolatedOriginEntry(initial_id.value() + 1, baz),
2273 GetIsolatedOriginEntry(initial_id.value() + 2, qux)));
Alex Moshchuk8e5c1952019-01-15 03:39:502274
2275 // Check IsIsolatedOrigin() only returns isolated origins if they apply to
2276 // the provided BrowsingInstance. foo and bar should apply in
Alex Moshchuk67bc0732019-01-18 21:23:332277 // BrowsingInstance ID |initial_id| and above, baz in IDs |initial_id + 1|
2278 // and above, and qux in |initial_id + 2| and above.
Alex Moshchuk99b795422019-03-07 00:27:322279 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id, foo));
2280 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id, bar));
2281 EXPECT_FALSE(IsIsolatedOrigin(&context, initial_id, baz));
2282 EXPECT_FALSE(IsIsolatedOrigin(&context, initial_id, qux));
Alex Moshchuk8e5c1952019-01-15 03:39:502283
Lukasz Anforowicz15ba43e2021-07-21 22:50:092284 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 1, foo));
2285 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 1, bar));
2286 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 1, baz));
2287 EXPECT_FALSE(IsIsolatedOrigin(&context, initial_id.value() + 1, qux));
Alex Moshchuk8e5c1952019-01-15 03:39:502288
Lukasz Anforowicz15ba43e2021-07-21 22:50:092289 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 2, foo));
2290 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 2, bar));
2291 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 2, baz));
2292 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 2, qux));
Alex Moshchuk8e5c1952019-01-15 03:39:502293
Lukasz Anforowicz15ba43e2021-07-21 22:50:092294 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 42, foo));
2295 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 42, bar));
2296 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 42, baz));
2297 EXPECT_TRUE(IsIsolatedOrigin(&context, initial_id.value() + 42, qux));
Alex Moshchuk8e5c1952019-01-15 03:39:502298
Alex Moshchuk99b795422019-03-07 00:27:322299 // An IsolationContext constructed without a BrowsingInstance ID should
2300 // return the latest available isolated origins.
W. James MacLean46cf26212020-10-01 16:43:372301 EXPECT_TRUE(p->IsIsolatedOrigin(IsolationContext(&context), foo,
2302 false /* origin_requests_isolation */));
2303 EXPECT_TRUE(p->IsIsolatedOrigin(IsolationContext(&context), bar,
2304 false /* origin_requests_isolation */));
2305 EXPECT_TRUE(p->IsIsolatedOrigin(IsolationContext(&context), baz,
2306 false /* origin_requests_isolation */));
2307 EXPECT_TRUE(p->IsIsolatedOrigin(IsolationContext(&context), qux,
2308 false /* origin_requests_isolation */));
Alex Moshchuk8e5c1952019-01-15 03:39:502309
2310 p->RemoveIsolatedOriginForTesting(foo);
2311 p->RemoveIsolatedOriginForTesting(bar);
2312 p->RemoveIsolatedOriginForTesting(baz);
2313 p->RemoveIsolatedOriginForTesting(qux);
alexmos3b9ad102017-05-26 23:41:082314}
2315
Alex Moshchuk526ce872018-09-11 18:19:362316// Check that an unsuccessful isolated origin lookup for a URL with an empty
2317// host doesn't crash. See https://crbug.com/882686.
Alex Moshchuk989aa22c2024-11-06 02:09:072318TEST_P(ChildProcessSecurityPolicyTest, IsIsolatedOriginWithEmptyHost) {
Alex Moshchuk526ce872018-09-11 18:19:362319 ChildProcessSecurityPolicyImpl* p =
2320 ChildProcessSecurityPolicyImpl::GetInstance();
Alex Moshchuk99b795422019-03-07 00:27:322321 TestBrowserContext context;
2322 EXPECT_FALSE(p->IsIsolatedOrigin(IsolationContext(&context),
W. James MacLean46cf26212020-10-01 16:43:372323 url::Origin::Create(GURL()),
2324 false /* origin_requests_isolation */));
Alex Moshchuk99b795422019-03-07 00:27:322325 EXPECT_FALSE(p->IsIsolatedOrigin(IsolationContext(&context),
W. James MacLean46cf26212020-10-01 16:43:372326 url::Origin::Create(GURL("file:///foo")),
2327 false /* origin_requests_isolation */));
Alex Moshchuk526ce872018-09-11 18:19:362328}
2329
Alex Moshchuk99b795422019-03-07 00:27:322330// Verifies the API for restricting isolated origins to a specific
2331// BrowserContext (profile). Namely, the same origin may be added for
2332// different BrowserContexts, possibly with different BrowsingInstanceId
2333// cutoffs. Attempts to re-add an origin for the same profile should be
2334// ignored. Also, once an isolated origin is added globally for all profiles,
2335// future attempts to re-add it (for any profile) should also be ignored.
Alex Moshchuk989aa22c2024-11-06 02:09:072336TEST_P(ChildProcessSecurityPolicyTest,
Alex Moshchuk99b795422019-03-07 00:27:322337 IsolatedOriginsForSpecificBrowserContexts) {
2338 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
2339 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
2340 ChildProcessSecurityPolicyImpl* p =
2341 ChildProcessSecurityPolicyImpl::GetInstance();
2342
2343 // Initially there should be no isolated origins.
2344 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2345 testing::IsEmpty());
2346
2347 // Save the next BrowsingInstance ID to be created. Because unit tests run
2348 // in batches, this isn't guaranteed to always be 1, for example if a
2349 // previous test in the same batch had already created a SiteInstance and
2350 // BrowsingInstance.
Lukasz Anforowicz15ba43e2021-07-21 22:50:092351 BrowsingInstanceId initial_id(SiteInstanceImpl::NextBrowsingInstanceId());
Alex Moshchuk99b795422019-03-07 00:27:322352
2353 // Isolate foo.com globally (for all BrowserContexts).
Alex Moshchukef8c2562021-03-12 06:37:452354 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST);
Alex Moshchuk99b795422019-03-07 00:27:322355
2356 TestBrowserContext context1, context2;
2357
2358 // Isolate bar.com in |context1|.
Alex Moshchukef8c2562021-03-12 06:37:452359 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST, &context1);
Alex Moshchuk99b795422019-03-07 00:27:322360
2361 // bar.com should be isolated for |context1|, but not |context2|. foo.com
2362 // should be isolated for all contexts.
2363 EXPECT_TRUE(IsIsolatedOrigin(&context1, initial_id, foo));
2364 EXPECT_TRUE(IsIsolatedOrigin(&context2, initial_id, foo));
2365 EXPECT_TRUE(IsIsolatedOrigin(&context1, initial_id, bar));
2366 EXPECT_FALSE(IsIsolatedOrigin(&context2, initial_id, bar));
2367
2368 // Create a new BrowsingInstance. Its ID will be |initial_id|.
2369 scoped_refptr<SiteInstanceImpl> foo_instance =
Alex Moshchuk331fa5f2021-03-10 06:16:592370 SiteInstanceImpl::CreateForTesting(&context1, GURL("https://foo.com/"));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092371 EXPECT_EQ(initial_id,
Alex Moshchuk99b795422019-03-07 00:27:322372 foo_instance->GetIsolationContext().browsing_instance_id());
Lukasz Anforowicz15ba43e2021-07-21 22:50:092373 EXPECT_EQ(BrowsingInstanceId::FromUnsafeValue(initial_id.value() + 1),
Alex Moshchuk99b795422019-03-07 00:27:322374 SiteInstanceImpl::NextBrowsingInstanceId());
2375 EXPECT_EQ(&context1, foo_instance->GetIsolationContext()
2376 .browser_or_resource_context()
2377 .ToBrowserContext());
2378
2379 // Isolating foo.com in |context1| is allowed and should add a new
2380 // IsolatedOriginEntry. This wouldn't introduce any additional isolation,
2381 // since foo.com is already isolated globally, but the new entry is
2382 // important, e.g. for persisting profile-specific isolated origins across
2383 // restarts.
2384 EXPECT_EQ(1, GetIsolatedOriginEntryCount(foo));
Alex Moshchukef8c2562021-03-12 06:37:452385 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST, &context1);
Alex Moshchuk99b795422019-03-07 00:27:322386 EXPECT_EQ(2, GetIsolatedOriginEntryCount(foo));
2387 EXPECT_TRUE(IsIsolatedOrigin(&context1, initial_id, foo));
2388 EXPECT_TRUE(IsIsolatedOrigin(&context2, initial_id, foo));
2389
2390 // Isolating bar.com in |context1| again should have no effect.
2391 EXPECT_EQ(1, GetIsolatedOriginEntryCount(bar));
Alex Moshchukef8c2562021-03-12 06:37:452392 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST, &context1);
Alex Moshchuk99b795422019-03-07 00:27:322393 EXPECT_EQ(1, GetIsolatedOriginEntryCount(bar));
2394 EXPECT_TRUE(IsIsolatedOrigin(&context1, initial_id, bar));
2395 EXPECT_FALSE(IsIsolatedOrigin(&context2, initial_id, bar));
2396
2397 // Isolate bar.com for |context2|, which should add a new
2398 // IsolatedOriginEntry. Verify that the isolation took effect for
2399 // |initial_id + 1| (the current BrowsingInstance ID cutoff) only.
Alex Moshchukef8c2562021-03-12 06:37:452400 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST, &context2);
Alex Moshchuk99b795422019-03-07 00:27:322401 EXPECT_EQ(2, GetIsolatedOriginEntryCount(bar));
2402 EXPECT_FALSE(IsIsolatedOrigin(&context2, initial_id, bar));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092403 EXPECT_TRUE(IsIsolatedOrigin(&context2, initial_id.value() + 1, bar));
Alex Moshchuk99b795422019-03-07 00:27:322404
2405 // Verify the bar.com is still isolated in |context1| starting with
2406 // |initial_id|.
2407 EXPECT_TRUE(IsIsolatedOrigin(&context1, initial_id, bar));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092408 EXPECT_TRUE(IsIsolatedOrigin(&context1, initial_id.value() + 1, bar));
Alex Moshchuk99b795422019-03-07 00:27:322409
2410 // Create another BrowserContext; only foo.com should be isolated there.
2411 TestBrowserContext context3;
2412 EXPECT_TRUE(IsIsolatedOrigin(&context3, initial_id, foo));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092413 EXPECT_TRUE(IsIsolatedOrigin(&context3, initial_id.value() + 1, foo));
Alex Moshchuk99b795422019-03-07 00:27:322414 EXPECT_FALSE(IsIsolatedOrigin(&context3, initial_id, bar));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092415 EXPECT_FALSE(IsIsolatedOrigin(&context3, initial_id.value() + 1, bar));
Alex Moshchuk99b795422019-03-07 00:27:322416
2417 // Now, add bar.com as a globally isolated origin. This should make it apply
2418 // to context3 as well, but only in initial_id + 1 (the current
2419 // BrowsingInstance ID cutoff).
Alex Moshchukef8c2562021-03-12 06:37:452420 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST);
Alex Moshchuk99b795422019-03-07 00:27:322421 EXPECT_EQ(3, GetIsolatedOriginEntryCount(bar));
2422 EXPECT_FALSE(IsIsolatedOrigin(&context3, initial_id, bar));
Lukasz Anforowicz15ba43e2021-07-21 22:50:092423 EXPECT_TRUE(IsIsolatedOrigin(&context3, initial_id.value() + 1, bar));
Alex Moshchuk99b795422019-03-07 00:27:322424
2425 // An attempt to re-add bar.com for a new profile should create a new
2426 // IsolatedOriginEntry, though it wouldn't provide any additional isolation,
2427 // since bar.com is already isolated globally.
2428 TestBrowserContext context4;
Alex Moshchukef8c2562021-03-12 06:37:452429 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::TEST, &context4);
Alex Moshchuk99b795422019-03-07 00:27:322430 EXPECT_EQ(4, GetIsolatedOriginEntryCount(bar));
2431
2432 p->RemoveIsolatedOriginForTesting(foo);
2433 p->RemoveIsolatedOriginForTesting(bar);
2434}
2435
2436// This test ensures that isolated origins associated with a specific
2437// BrowserContext are removed when that BrowserContext is destroyed.
Alex Moshchuk989aa22c2024-11-06 02:09:072438TEST_P(ChildProcessSecurityPolicyTest,
Alex Moshchuk99b795422019-03-07 00:27:322439 IsolatedOriginsRemovedWhenBrowserContextDestroyed) {
2440 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
2441 url::Origin sub_foo = url::Origin::Create(GURL("https://sub.foo.com/"));
2442 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
2443 url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
2444 ChildProcessSecurityPolicyImpl* p =
2445 ChildProcessSecurityPolicyImpl::GetInstance();
2446
2447 // Initially there should be no isolated origins.
2448 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2449 testing::IsEmpty());
2450
2451 // Save the next BrowsingInstance ID to be created. Because unit tests run
2452 // in batches, this isn't guaranteed to always be 1, for example if a
2453 // previous test in the same batch had already created a SiteInstance and
2454 // BrowsingInstance.
Lukasz Anforowicz15ba43e2021-07-21 22:50:092455 BrowsingInstanceId initial_id(SiteInstanceImpl::NextBrowsingInstanceId());
Alex Moshchuk99b795422019-03-07 00:27:322456
2457 std::unique_ptr<TestBrowserContext> context1(new TestBrowserContext());
2458 std::unique_ptr<TestBrowserContext> context2(new TestBrowserContext());
2459
2460 // Isolate foo.com in |context1|. Note that sub.foo.com should also be
2461 // considered isolated in |context1|, since it's a subdomain of foo.com.
Alex Moshchukef8c2562021-03-12 06:37:452462 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST,
2463 context1.get());
Alex Moshchuk99b795422019-03-07 00:27:322464 EXPECT_EQ(1, GetIsolatedOriginEntryCount(foo));
2465 EXPECT_TRUE(IsIsolatedOrigin(context1.get(), initial_id, foo));
2466 EXPECT_TRUE(IsIsolatedOrigin(context1.get(), initial_id, sub_foo));
2467 EXPECT_FALSE(IsIsolatedOrigin(context2.get(), initial_id, foo));
2468 EXPECT_FALSE(IsIsolatedOrigin(context2.get(), initial_id, sub_foo));
2469
2470 // Isolate sub.foo.com and bar.com in |context2|.
Alex Moshchukef8c2562021-03-12 06:37:452471 p->AddFutureIsolatedOrigins({sub_foo, bar}, IsolatedOriginSource::TEST,
2472 context2.get());
Alex Moshchuk99b795422019-03-07 00:27:322473 EXPECT_EQ(1, GetIsolatedOriginEntryCount(sub_foo));
2474 EXPECT_EQ(1, GetIsolatedOriginEntryCount(bar));
2475 EXPECT_TRUE(IsIsolatedOrigin(context2.get(), initial_id, sub_foo));
2476 EXPECT_TRUE(IsIsolatedOrigin(context2.get(), initial_id, bar));
2477 EXPECT_FALSE(IsIsolatedOrigin(context2.get(), initial_id, foo));
2478
2479 // Isolate baz.com in both BrowserContexts.
Alex Moshchukef8c2562021-03-12 06:37:452480 p->AddFutureIsolatedOrigins({baz}, IsolatedOriginSource::TEST,
2481 context1.get());
2482 p->AddFutureIsolatedOrigins({baz}, IsolatedOriginSource::TEST,
2483 context2.get());
Alex Moshchuk99b795422019-03-07 00:27:322484
2485 EXPECT_EQ(2, GetIsolatedOriginEntryCount(baz));
2486 EXPECT_TRUE(IsIsolatedOrigin(context1.get(), initial_id, baz));
2487 EXPECT_TRUE(IsIsolatedOrigin(context2.get(), initial_id, baz));
2488
2489 // Remove |context1|. foo.com should no longer be in the isolated_origins_
2490 // map, and the other origins should be isolated only in |context2|.
2491 context1.reset();
2492
2493 EXPECT_EQ(0, GetIsolatedOriginEntryCount(foo));
2494 EXPECT_EQ(1, GetIsolatedOriginEntryCount(sub_foo));
2495 EXPECT_EQ(1, GetIsolatedOriginEntryCount(bar));
2496 EXPECT_EQ(1, GetIsolatedOriginEntryCount(baz));
2497 EXPECT_TRUE(IsIsolatedOrigin(context2.get(), initial_id, sub_foo));
2498 EXPECT_TRUE(IsIsolatedOrigin(context2.get(), initial_id, bar));
2499 EXPECT_TRUE(IsIsolatedOrigin(context2.get(), initial_id, baz));
2500
2501 // Remove |context2| and ensure the remaining entries are removed.
2502 context2.reset();
2503 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2504 testing::IsEmpty());
2505}
2506
Alex Moshchuk989aa22c2024-11-06 02:09:072507TEST_P(ChildProcessSecurityPolicyTest, IsolatedOriginPattern) {
Md Hasibul Hasana963a9342024-04-03 10:15:142508 const std::string_view etld1_wild("https://[*.]foo.com");
Andrew Stone6ed99b22019-06-07 06:14:392509 url::Origin etld1_wild_origin = url::Origin::Create(GURL("https://foo.com"));
2510 IsolatedOriginPattern p(etld1_wild);
2511 EXPECT_TRUE(p.isolate_all_subdomains());
2512 EXPECT_TRUE(p.is_valid());
2513 EXPECT_EQ(p.origin(), etld1_wild_origin);
2514
Md Hasibul Hasana963a9342024-04-03 10:15:142515 const std::string_view etld2_wild("https://[*.]bar.foo.com");
Andrew Stone6ed99b22019-06-07 06:14:392516 url::Origin etld2_wild_origin =
2517 url::Origin::Create(GURL("https://bar.foo.com"));
2518 bool result = p.Parse(etld2_wild);
2519 EXPECT_TRUE(result);
2520 EXPECT_TRUE(p.isolate_all_subdomains());
2521 EXPECT_TRUE(p.is_valid());
2522 EXPECT_EQ(p.origin(), etld2_wild_origin);
2523 EXPECT_FALSE(p.origin().opaque());
2524
Md Hasibul Hasana963a9342024-04-03 10:15:142525 const std::string_view etld1("https://baz.com");
Andrew Stone6ed99b22019-06-07 06:14:392526 url::Origin etld1_origin = url::Origin::Create(GURL("https://baz.com"));
2527 result = p.Parse(etld1);
2528 EXPECT_TRUE(result);
2529 EXPECT_FALSE(p.isolate_all_subdomains());
2530 EXPECT_TRUE(p.is_valid());
2531 EXPECT_EQ(p.origin(), etld1_origin);
2532 EXPECT_FALSE(p.origin().opaque());
2533
Md Hasibul Hasana963a9342024-04-03 10:15:142534 const std::string_view bad_scheme("ftp://foo.com");
Andrew Stone6ed99b22019-06-07 06:14:392535 result = p.Parse(bad_scheme);
2536 EXPECT_FALSE(result);
2537 EXPECT_FALSE(p.isolate_all_subdomains());
2538 EXPECT_FALSE(p.is_valid());
2539 EXPECT_TRUE(p.origin().opaque());
2540
Md Hasibul Hasana963a9342024-04-03 10:15:142541 const std::string_view no_scheme_sep("httpsfoo.com");
Andrew Stone6ed99b22019-06-07 06:14:392542 result = p.Parse(no_scheme_sep);
2543 EXPECT_FALSE(result);
2544 EXPECT_FALSE(p.isolate_all_subdomains());
2545 EXPECT_FALSE(p.is_valid());
2546 EXPECT_TRUE(p.origin().opaque());
2547
Md Hasibul Hasana963a9342024-04-03 10:15:142548 const std::string_view bad_registry("https://co.uk");
Andrew Stone6ed99b22019-06-07 06:14:392549 result = p.Parse(bad_registry);
2550 EXPECT_FALSE(result);
2551 EXPECT_FALSE(p.isolate_all_subdomains());
2552 EXPECT_FALSE(p.is_valid());
2553 EXPECT_TRUE(p.origin().opaque());
2554
Md Hasibul Hasana963a9342024-04-03 10:15:142555 const std::string_view trailing_dot("https://bar.com.");
Andrew Stone6ed99b22019-06-07 06:14:392556 result = p.Parse(trailing_dot);
2557 EXPECT_FALSE(result);
2558 EXPECT_FALSE(p.isolate_all_subdomains());
2559 EXPECT_FALSE(p.is_valid());
2560 EXPECT_TRUE(p.origin().opaque());
2561
Md Hasibul Hasana963a9342024-04-03 10:15:142562 const std::string_view ip_addr("https://10.20.30.40");
Andrew Stone6ed99b22019-06-07 06:14:392563 url::Origin ip_origin = url::Origin::Create(GURL("https://10.20.30.40"));
2564 result = p.Parse(ip_addr);
2565 EXPECT_TRUE(result);
2566 EXPECT_FALSE(p.isolate_all_subdomains());
2567 EXPECT_FALSE(p.origin().opaque());
2568 EXPECT_TRUE(p.is_valid());
2569 EXPECT_EQ(p.origin(), ip_origin);
2570
Md Hasibul Hasana963a9342024-04-03 10:15:142571 const std::string_view wild_ip_addr("https://[*.]10.20.30.40");
Andrew Stone6ed99b22019-06-07 06:14:392572 result = p.Parse(wild_ip_addr);
2573 EXPECT_FALSE(result);
2574 EXPECT_FALSE(p.isolate_all_subdomains());
2575 EXPECT_FALSE(p.is_valid());
2576
2577 const url::Origin bad_origin;
2578 IsolatedOriginPattern bad_pattern(bad_origin);
2579 EXPECT_FALSE(bad_pattern.isolate_all_subdomains());
2580 EXPECT_TRUE(bad_pattern.origin().opaque());
2581 EXPECT_FALSE(p.is_valid());
2582}
2583
Alex Moshchukc4679422019-06-11 17:04:482584// This test adds isolated origins from various sources and verifies that
2585// GetIsolatedOrigins() properly restricts lookups by source.
Alex Moshchuk989aa22c2024-11-06 02:09:072586TEST_P(ChildProcessSecurityPolicyTest, GetIsolatedOrigins) {
Alex Moshchukc4679422019-06-11 17:04:482587 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
2588 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
2589 url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
2590 url::Origin qux = url::Origin::Create(GURL("https://qux.com/"));
2591 ChildProcessSecurityPolicyImpl* p =
2592 ChildProcessSecurityPolicyImpl::GetInstance();
2593
2594 // Initially there should be no isolated origins.
2595 EXPECT_THAT(p->GetIsolatedOrigins(), testing::IsEmpty());
2596
2597 // Add isolated origins from various sources, and verify that
2598 // GetIsolatedOrigins properly restricts lookups by source.
Alex Moshchukef8c2562021-03-12 06:37:452599 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST);
2600 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::FIELD_TRIAL);
Alex Moshchukc4679422019-06-11 17:04:482601
2602 EXPECT_THAT(p->GetIsolatedOrigins(), testing::UnorderedElementsAre(foo, bar));
2603 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::TEST),
2604 testing::UnorderedElementsAre(foo));
2605 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::FIELD_TRIAL),
2606 testing::UnorderedElementsAre(bar));
2607
Alex Moshchukef8c2562021-03-12 06:37:452608 p->AddFutureIsolatedOrigins({baz}, IsolatedOriginSource::POLICY);
2609 p->AddFutureIsolatedOrigins({qux}, IsolatedOriginSource::COMMAND_LINE);
Alex Moshchukc4679422019-06-11 17:04:482610
2611 EXPECT_THAT(p->GetIsolatedOrigins(),
2612 testing::UnorderedElementsAre(foo, bar, baz, qux));
2613 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::TEST),
2614 testing::UnorderedElementsAre(foo));
2615 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::FIELD_TRIAL),
2616 testing::UnorderedElementsAre(bar));
2617 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::POLICY),
2618 testing::UnorderedElementsAre(baz));
2619 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::COMMAND_LINE),
2620 testing::UnorderedElementsAre(qux));
2621
2622 p->RemoveIsolatedOriginForTesting(foo);
2623 p->RemoveIsolatedOriginForTesting(bar);
2624 p->RemoveIsolatedOriginForTesting(baz);
2625 p->RemoveIsolatedOriginForTesting(qux);
2626 EXPECT_THAT(p->GetIsolatedOrigins(), testing::IsEmpty());
2627}
2628
2629// This test adds isolated origins from various sources as well as restricted
2630// to particular profiles, and verifies that GetIsolatedOrigins() properly
2631// restricts lookups by both source and profile.
Alex Moshchuk989aa22c2024-11-06 02:09:072632TEST_P(ChildProcessSecurityPolicyTest, GetIsolatedOriginsWithProfile) {
Alex Moshchukc4679422019-06-11 17:04:482633 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
2634 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
2635 url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
2636 url::Origin qux = url::Origin::Create(GURL("https://qux.com/"));
2637 ChildProcessSecurityPolicyImpl* p =
2638 ChildProcessSecurityPolicyImpl::GetInstance();
2639 TestBrowserContext context1, context2;
2640
2641 // Initially there should be no isolated origins.
2642 EXPECT_THAT(p->GetIsolatedOrigins(), testing::IsEmpty());
2643
2644 // Add a global isolated origin. Note that since it applies to all profiles,
2645 // GetIsolatedOrigins() should return it for any passed-in profile.
Alex Moshchukef8c2562021-03-12 06:37:452646 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST);
Alex Moshchukc4679422019-06-11 17:04:482647
2648 // Add some per-profile isolated origins.
Alex Moshchukef8c2562021-03-12 06:37:452649 p->AddFutureIsolatedOrigins({bar}, IsolatedOriginSource::USER_TRIGGERED,
2650 &context1);
2651 p->AddFutureIsolatedOrigins({baz}, IsolatedOriginSource::POLICY, &context2);
2652 p->AddFutureIsolatedOrigins({qux}, IsolatedOriginSource::USER_TRIGGERED,
2653 &context1);
2654 p->AddFutureIsolatedOrigins({qux}, IsolatedOriginSource::USER_TRIGGERED,
2655 &context2);
Alex Moshchukc4679422019-06-11 17:04:482656
2657 EXPECT_THAT(p->GetIsolatedOrigins(), testing::UnorderedElementsAre(foo));
2658
2659 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::TEST),
2660 testing::UnorderedElementsAre(foo));
2661 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::TEST, &context1),
2662 testing::UnorderedElementsAre(foo));
2663 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::TEST, &context2),
2664 testing::UnorderedElementsAre(foo));
2665
2666 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::USER_TRIGGERED),
2667 testing::IsEmpty());
2668 EXPECT_THAT(
2669 p->GetIsolatedOrigins(IsolatedOriginSource::USER_TRIGGERED, &context1),
2670 testing::UnorderedElementsAre(bar, qux));
2671 EXPECT_THAT(
2672 p->GetIsolatedOrigins(IsolatedOriginSource::USER_TRIGGERED, &context2),
2673 testing::UnorderedElementsAre(qux));
2674
2675 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::POLICY),
2676 testing::IsEmpty());
2677 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::POLICY, &context1),
2678 testing::IsEmpty());
2679 EXPECT_THAT(p->GetIsolatedOrigins(IsolatedOriginSource::POLICY, &context2),
2680 testing::UnorderedElementsAre(baz));
2681
2682 p->RemoveIsolatedOriginForTesting(foo);
2683 p->RemoveIsolatedOriginForTesting(bar);
2684 p->RemoveIsolatedOriginForTesting(baz);
2685 p->RemoveIsolatedOriginForTesting(qux);
2686 EXPECT_THAT(p->GetIsolatedOrigins(), testing::IsEmpty());
2687}
2688
Alex Moshchuk989aa22c2024-11-06 02:09:072689TEST_P(ChildProcessSecurityPolicyTest, IsolatedOriginPatternEquality) {
Andrew Stone0a177fe22019-06-26 08:12:042690 std::string foo("https://foo.com");
2691 std::string foo_port("https://foo.com:8000");
2692 std::string foo_path("https://foo.com/some/path");
2693
2694 EXPECT_EQ(IsolatedOriginPattern(foo), IsolatedOriginPattern(foo_port));
2695 EXPECT_EQ(IsolatedOriginPattern(foo), IsolatedOriginPattern(foo_path));
2696
Andrew Stone404880d2019-07-10 02:23:312697 std::string wild_foo("https://[*.]foo.com");
2698 std::string wild_foo_port("https://[*.]foo.com:8000");
2699 std::string wild_foo_path("https://[*.]foo.com/some/path");
Andrew Stone0a177fe22019-06-26 08:12:042700
2701 EXPECT_EQ(IsolatedOriginPattern(wild_foo),
2702 IsolatedOriginPattern(wild_foo_port));
2703 EXPECT_EQ(IsolatedOriginPattern(wild_foo),
2704 IsolatedOriginPattern(wild_foo_path));
2705
2706 EXPECT_FALSE(IsolatedOriginPattern(foo) == IsolatedOriginPattern(wild_foo));
2707}
2708
2709// Verifies parsing logic in SiteIsolationPolicy::ParseIsolatedOrigins.
Alex Moshchuk989aa22c2024-11-06 02:09:072710TEST_P(ChildProcessSecurityPolicyTest, ParseIsolatedOrigins) {
Andrew Stone0a177fe22019-06-26 08:12:042711 EXPECT_THAT(ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(""),
2712 testing::IsEmpty());
2713
2714 // Single simple, valid origin.
2715 EXPECT_THAT(
2716 ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(
2717 "http://isolated.foo.com"),
2718 testing::ElementsAre(IsolatedOriginPattern("http://isolated.foo.com")));
2719
2720 // Multiple comma-separated origins.
2721 EXPECT_THAT(
2722 ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(
2723 "http://a.com,https://b.com,,https://c.com:8000"),
2724 testing::ElementsAre(IsolatedOriginPattern("http://a.com"),
2725 IsolatedOriginPattern("https://b.com"),
2726 IsolatedOriginPattern("https://c.com:8000")));
2727
2728 // ParseIsolatedOrigins should not do any deduplication (that is the job of
Alex Moshchukef8c2562021-03-12 06:37:452729 // ChildProcessSecurityPolicyImpl::AddFutureIsolatedOrigins).
Andrew Stone0a177fe22019-06-26 08:12:042730 EXPECT_THAT(
2731 ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(
2732 "https://b.com,https://b.com,https://b.com:1234"),
2733 testing::ElementsAre(IsolatedOriginPattern("https://b.com"),
2734 IsolatedOriginPattern("https://b.com"),
2735 IsolatedOriginPattern("https://b.com:1234")));
2736
2737 // A single wildcard origin.
2738 EXPECT_THAT(
2739 ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(
Andrew Stone404880d2019-07-10 02:23:312740 "https://[*.]wild.foo.com"),
2741 testing::ElementsAre(IsolatedOriginPattern("https://[*.]wild.foo.com")));
Andrew Stone0a177fe22019-06-26 08:12:042742
2743 // A mixture of wildcard and non-wildcard origins.
2744 EXPECT_THAT(
2745 ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(
Andrew Stone404880d2019-07-10 02:23:312746 "https://[*.]wild.foo.com,https://isolated.foo.com"),
2747 testing::ElementsAre(IsolatedOriginPattern("https://[*.]wild.foo.com"),
Andrew Stone0a177fe22019-06-26 08:12:042748 IsolatedOriginPattern("https://isolated.foo.com")));
2749}
2750
2751// Verify that the default port for an isolated origin's scheme is returned
2752// during a lookup, not the port of the origin requested.
Alex Moshchuk989aa22c2024-11-06 02:09:072753TEST_P(ChildProcessSecurityPolicyTest, WildcardDefaultPort) {
Andrew Stone0a177fe22019-06-26 08:12:042754 ChildProcessSecurityPolicyImpl* p =
2755 ChildProcessSecurityPolicyImpl::GetInstance();
2756 EXPECT_THAT(p->GetIsolatedOrigins(), testing::IsEmpty());
2757
2758 url::Origin isolated_origin_with_port =
2759 url::Origin::Create(GURL("https://isolated.com:1234"));
2760 url::Origin isolated_origin =
2761 url::Origin::Create(GURL("https://isolated.com"));
2762
2763 url::Origin wild_with_port =
2764 url::Origin::Create(GURL("https://a.wild.com:5678"));
2765 url::Origin wild_origin = url::Origin::Create(GURL("https://a.wild.com"));
Andrew Stone404880d2019-07-10 02:23:312766 IsolatedOriginPattern wild_pattern("https://[*.]wild.com:5678");
Andrew Stone0a177fe22019-06-26 08:12:042767
Alex Moshchukef8c2562021-03-12 06:37:452768 p->AddFutureIsolatedOrigins({isolated_origin_with_port},
2769 IsolatedOriginSource::TEST);
2770 p->AddFutureIsolatedOrigins({wild_pattern}, IsolatedOriginSource::TEST);
Andrew Stone0a177fe22019-06-26 08:12:042771
2772 IsolationContext isolation_context(browser_context());
2773 url::Origin lookup_origin;
2774
2775 // Requesting isolated_origin_with_port should return the same origin but with
2776 // the default port for the scheme.
W. James MacLean46cf26212020-10-01 16:43:372777 const bool kOriginRequestsIsolation = false;
W. James MacLean92e39c82021-02-25 23:27:342778 EXPECT_TRUE(p->GetMatchingProcessIsolatedOrigin(
2779 isolation_context, isolated_origin_with_port, kOriginRequestsIsolation,
2780 &lookup_origin));
Scott Violeta02c94b142024-08-28 03:29:182781 EXPECT_EQ(url::DefaultPortForScheme(lookup_origin.scheme()),
Andrew Stone0a177fe22019-06-26 08:12:042782 lookup_origin.port());
2783 EXPECT_EQ(isolated_origin, lookup_origin);
2784
2785 p->RemoveIsolatedOriginForTesting(isolated_origin);
2786
2787 // Similarly, looking up matching isolated origins for wildcard origins must
2788 // also return the default port for the origin's scheme, not the report of the
2789 // requested origin.
W. James MacLean92e39c82021-02-25 23:27:342790 EXPECT_TRUE(p->GetMatchingProcessIsolatedOrigin(
2791 isolation_context, wild_with_port, kOriginRequestsIsolation,
2792 &lookup_origin));
Scott Violeta02c94b142024-08-28 03:29:182793 EXPECT_EQ(url::DefaultPortForScheme(lookup_origin.scheme()),
Andrew Stone0a177fe22019-06-26 08:12:042794 lookup_origin.port());
2795 EXPECT_EQ(wild_origin, lookup_origin);
2796
2797 p->RemoveIsolatedOriginForTesting(wild_pattern.origin());
2798
2799 EXPECT_THAT(p->GetIsolatedOrigins(), testing::IsEmpty());
2800}
2801
Alex Moshchuk989aa22c2024-11-06 02:09:072802TEST_P(ChildProcessSecurityPolicyTest, ProcessLockMatching) {
Aaron Colwell9d0f9392021-02-11 21:51:522803 GURL nonapp_url("https://bar.com/");
2804 GURL app_url("https://some.app.foo.com/");
2805 GURL app_effective_url("https://app.com/");
2806 EffectiveURLContentBrowserClient modified_client(
2807 app_url, app_effective_url, /* requires_dedicated_process */ true);
2808 ContentBrowserClient* original_client =
2809 SetBrowserClientForTesting(&modified_client);
2810
2811 IsolationContext isolation_context(browser_context());
Aaron Colwell9d0f9392021-02-11 21:51:522812
Robbie McElrath7d4bd852021-07-24 04:02:192813 auto nonapp_urlinfo = UrlInfo::CreateForTesting(
2814 nonapp_url, CreateStoragePartitionConfigForTesting());
2815 auto ui_nonapp_url_siteinfo =
Arthur Hemery821fa5d2021-08-30 13:32:422816 SiteInfo::Create(isolation_context, nonapp_urlinfo);
Robbie McElrath7d4bd852021-07-24 04:02:192817 auto ui_nonapp_url_lock =
Arthur Hemery821fa5d2021-08-30 13:32:422818 ProcessLock::Create(isolation_context, nonapp_urlinfo);
Aaron Colwell9d0f9392021-02-11 21:51:522819
Robbie McElrath7d4bd852021-07-24 04:02:192820 auto app_urlinfo = UrlInfo::CreateForTesting(
2821 app_url, CreateStoragePartitionConfigForTesting());
Arthur Hemery821fa5d2021-08-30 13:32:422822 auto ui_app_url_lock = ProcessLock::Create(isolation_context, app_urlinfo);
2823 auto ui_app_url_siteinfo = SiteInfo::Create(isolation_context, app_urlinfo);
Aaron Colwell9d0f9392021-02-11 21:51:522824
Robbie McElrath7d4bd852021-07-24 04:02:192825 SiteInfo io_nonapp_url_siteinfo(browser_context());
Aaron Colwell9d0f9392021-02-11 21:51:522826 ProcessLock io_nonapp_url_lock;
Robbie McElrath7d4bd852021-07-24 04:02:192827 SiteInfo io_app_url_siteinfo(browser_context());
Aaron Colwell9d0f9392021-02-11 21:51:522828 ProcessLock io_app_url_lock;
2829
2830 base::WaitableEvent io_locks_set_event;
2831
2832 // Post a task that will compute ProcessLocks for the same URLs in the
2833 // IO thread.
2834 GetIOThreadTaskRunner({})->PostTask(
2835 FROM_HERE, base::BindLambdaForTesting([&]() {
Arthur Hemery821fa5d2021-08-30 13:32:422836 io_nonapp_url_siteinfo =
2837 SiteInfo::CreateOnIOThread(isolation_context, nonapp_urlinfo);
Robbie McElrath7d4bd852021-07-24 04:02:192838 io_nonapp_url_lock =
Arthur Hemery821fa5d2021-08-30 13:32:422839 ProcessLock::Create(isolation_context, nonapp_urlinfo);
Aaron Colwell9d0f9392021-02-11 21:51:522840
Arthur Hemery821fa5d2021-08-30 13:32:422841 io_app_url_siteinfo =
2842 SiteInfo::CreateOnIOThread(isolation_context, app_urlinfo);
2843 io_app_url_lock = ProcessLock::Create(isolation_context, app_urlinfo);
Aaron Colwell9d0f9392021-02-11 21:51:522844
2845 // Tell the UI thread have computed the locks.
2846 io_locks_set_event.Signal();
2847 }));
2848
2849 io_locks_set_event.Wait();
2850
2851 // Expect URLs with effective URLs that match the original URL to have
2852 // matching SiteInfos and matching ProcessLocks.
2853 EXPECT_EQ(ui_nonapp_url_siteinfo, io_nonapp_url_siteinfo);
2854 EXPECT_EQ(ui_nonapp_url_lock, io_nonapp_url_lock);
2855
2856 // Expect hosted app URLs where the effective URL does not match the original
2857 // URL to have different SiteInfos but matching process locks. The SiteInfos,
2858 // are expected to be different because the effective URL cannot be computed
2859 // from the IO thread. This means the site_url fields will differ.
2860 EXPECT_NE(ui_app_url_siteinfo, io_app_url_siteinfo);
2861 EXPECT_NE(ui_app_url_siteinfo.site_url(), io_app_url_siteinfo.site_url());
2862 EXPECT_EQ(ui_app_url_siteinfo.process_lock_url(),
2863 io_app_url_siteinfo.process_lock_url());
2864 EXPECT_EQ(ui_app_url_lock, io_app_url_lock);
2865
2866 SetBrowserClientForTesting(original_client);
2867}
Alex Moshchuk331fa5f2021-03-10 06:16:592868
2869// Verify the mechanism that allows non-origin-keyed isolated origins to be
2870// associated with a single BrowsingInstance.
Alex Moshchuk989aa22c2024-11-06 02:09:072871TEST_P(ChildProcessSecurityPolicyTest,
Alex Moshchuk331fa5f2021-03-10 06:16:592872 IsolatedOriginsForSpecificBrowsingInstances) {
2873 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
2874 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
2875 url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
2876 ChildProcessSecurityPolicyImpl* p =
2877 ChildProcessSecurityPolicyImpl::GetInstance();
2878
2879 // Initially there should be no isolated origins.
2880 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
2881 testing::IsEmpty());
2882
2883 // Create SiteInstances for foo.com, bar.com, and baz.com, with each
2884 // SiteInstance in a new BrowsingInstance.
2885 TestBrowserContext context;
2886 scoped_refptr<SiteInstanceImpl> foo_instance =
2887 SiteInstanceImpl::CreateForTesting(&context, GURL("https://foo.com/"));
2888 auto foo_browsing_instance_id =
2889 foo_instance->GetIsolationContext().browsing_instance_id();
2890 scoped_refptr<SiteInstanceImpl> bar_instance =
2891 SiteInstanceImpl::CreateForTesting(&context, GURL("https://bar.com/"));
2892 auto bar_browsing_instance_id =
2893 bar_instance->GetIsolationContext().browsing_instance_id();
2894 scoped_refptr<SiteInstanceImpl> baz_instance =
2895 SiteInstanceImpl::CreateForTesting(&context, GURL("https://baz.com/"));
2896 auto baz_browsing_instance_id =
2897 baz_instance->GetIsolationContext().browsing_instance_id();
2898
2899 // Isolate foo.com for `foo_instance`'s BrowsingInstance only.
W. James MacLeanc07dc41b2022-07-25 18:52:162900 p->AddCoopIsolatedOriginForBrowsingInstance(
2901 foo_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:592902 LOCKED_EXPECT_THAT(
2903 p->isolated_origins_lock_, p->isolated_origins_,
2904 testing::UnorderedElementsAre(GetIsolatedOriginEntry(
2905 &context, false /* applies_to_future_browsing_instances */,
Lukasz Anforowicz15ba43e2021-07-21 22:50:092906 foo_browsing_instance_id, foo)));
Alex Moshchuk331fa5f2021-03-10 06:16:592907
2908 // Verify that foo.com is isolated only in the `foo_instance`'s
2909 // BrowsingInstance, and no other origins are isolated in any other
2910 // BrowsingInstances.
2911 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
2912 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, bar));
2913 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, baz));
2914 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
2915 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, bar));
2916 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, baz));
2917 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, foo));
2918 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, bar));
2919 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, baz));
2920
2921 // Verify that subdomains of foo.com are part of the foo.com
2922 // isolated origin (i.e., that foo.com is not origin-keyed).
2923 EXPECT_TRUE(
2924 IsIsolatedOrigin(&context, foo_browsing_instance_id,
2925 url::Origin::Create(GURL("https://sub.foo.com"))));
2926 EXPECT_TRUE(
2927 IsIsolatedOrigin(&context, foo_browsing_instance_id,
2928 url::Origin::Create(GURL("https://sub2.sub.foo.com"))));
2929
2930 // Isolating foo.com again in the same BrowsingInstance should have no
2931 // effect.
W. James MacLeanc07dc41b2022-07-25 18:52:162932 p->AddCoopIsolatedOriginForBrowsingInstance(
2933 foo_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:592934 EXPECT_EQ(1, GetIsolatedOriginEntryCount(foo));
2935 LOCKED_EXPECT_THAT(
2936 p->isolated_origins_lock_, p->isolated_origins_,
2937 testing::UnorderedElementsAre(GetIsolatedOriginEntry(
2938 &context, false /* applies_to_future_browsing_instances */,
Lukasz Anforowicz15ba43e2021-07-21 22:50:092939 foo_browsing_instance_id, foo)));
Alex Moshchuk331fa5f2021-03-10 06:16:592940
2941 // Isolate baz.com in `baz_browsing_instance`'s BrowsingInstance.
W. James MacLeanc07dc41b2022-07-25 18:52:162942 p->AddCoopIsolatedOriginForBrowsingInstance(
2943 baz_instance->GetIsolationContext(), baz, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:592944 LOCKED_EXPECT_THAT(
2945 p->isolated_origins_lock_, p->isolated_origins_,
2946 testing::UnorderedElementsAre(
2947 GetIsolatedOriginEntry(
2948 &context, false /* applies_to_future_browsing_instances */,
Lukasz Anforowicz15ba43e2021-07-21 22:50:092949 foo_browsing_instance_id, foo),
Alex Moshchuk331fa5f2021-03-10 06:16:592950 GetIsolatedOriginEntry(
2951 &context, false /* applies_to_future_browsing_instances */,
Lukasz Anforowicz15ba43e2021-07-21 22:50:092952 baz_browsing_instance_id, baz)));
Alex Moshchuk331fa5f2021-03-10 06:16:592953
2954 // Verify that foo.com is isolated in the `foo_instance`'s BrowsingInstance,
2955 // and baz.com is isolated in `baz_instance`'s BrowsingInstance.
2956 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
2957 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, bar));
2958 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, baz));
2959 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
2960 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, bar));
2961 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, baz));
2962 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, foo));
2963 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, bar));
2964 EXPECT_TRUE(IsIsolatedOrigin(&context, baz_browsing_instance_id, baz));
2965
2966 // Isolate bar.com in foo.com (not bar.com)'s BrowsingInstance.
W. James MacLeanc07dc41b2022-07-25 18:52:162967 p->AddCoopIsolatedOriginForBrowsingInstance(
2968 foo_instance->GetIsolationContext(), bar, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:592969
2970 // Verify that foo.com and bar.com are both isolated in `foo_instance`'s
2971 // BrowsingInstance, nothing is isolated in bar_instance's BrowsingInstance,
2972 // and baz.com is isolated in `baz_instance`'s BrowsingInstance.
2973 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
2974 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, bar));
2975 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, baz));
2976 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
2977 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, bar));
2978 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, baz));
2979 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, foo));
2980 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, bar));
2981 EXPECT_TRUE(IsIsolatedOrigin(&context, baz_browsing_instance_id, baz));
2982
2983 // Isolate foo.com in `bar_instance` and `baz_instance`'s BrowsingInstances
2984 // and verify that this takes effect. This should result in having three
2985 // entries for foo.com, one for each BrowsingInstance.
W. James MacLeanc07dc41b2022-07-25 18:52:162986 p->AddCoopIsolatedOriginForBrowsingInstance(
2987 bar_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
2988 p->AddCoopIsolatedOriginForBrowsingInstance(
2989 baz_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:592990 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
2991 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, bar));
2992 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, baz));
2993 EXPECT_TRUE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
2994 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, bar));
2995 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, baz));
2996 EXPECT_TRUE(IsIsolatedOrigin(&context, baz_browsing_instance_id, foo));
2997 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, bar));
2998 EXPECT_TRUE(IsIsolatedOrigin(&context, baz_browsing_instance_id, baz));
2999 EXPECT_EQ(3, GetIsolatedOriginEntryCount(foo));
3000
3001 // Simulate foo_instance and its BrowsingInstance going away. This should
3002 // remove the corresponding BrowsingInstance-specific entries in
3003 // ChildProcessSecurityPolicy, since they are no longer needed.
3004 p->SetBrowsingInstanceCleanupDelayForTesting(0);
3005 foo_instance.reset();
3006 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
3007 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, bar));
3008 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, baz));
3009
3010 // Other BrowsingInstances shouldn't be affected.
3011 EXPECT_TRUE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
3012 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, bar));
3013 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, baz));
3014 EXPECT_TRUE(IsIsolatedOrigin(&context, baz_browsing_instance_id, foo));
3015 EXPECT_FALSE(IsIsolatedOrigin(&context, baz_browsing_instance_id, bar));
3016 EXPECT_TRUE(IsIsolatedOrigin(&context, baz_browsing_instance_id, baz));
3017
3018 p->ClearIsolatedOriginsForTesting();
3019}
3020
3021// Verify isolated origins associated with a single BrowsingInstance can be
3022// combined with isolated origins that apply to future BrowsingInstances.
Alex Moshchuk989aa22c2024-11-06 02:09:073023TEST_P(ChildProcessSecurityPolicyTest,
Alex Moshchuk331fa5f2021-03-10 06:16:593024 IsolatedOriginsForCurrentAndFutureBrowsingInstances) {
3025 url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
3026 url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
3027 ChildProcessSecurityPolicyImpl* p =
3028 ChildProcessSecurityPolicyImpl::GetInstance();
3029
3030 // Initially there should be no isolated origins.
3031 LOCKED_EXPECT_THAT(p->isolated_origins_lock_, p->isolated_origins_,
3032 testing::IsEmpty());
3033
3034 // Create a SiteInstance for foo.com in a new BrowsingInstance.
3035 TestBrowserContext context;
3036 scoped_refptr<SiteInstanceImpl> foo_instance =
3037 SiteInstanceImpl::CreateForTesting(&context, GURL("https://foo.com/"));
3038 auto foo_browsing_instance_id =
3039 foo_instance->GetIsolationContext().browsing_instance_id();
3040
3041 // Isolate foo.com for `foo_instance`'s BrowsingInstance only.
W. James MacLeanc07dc41b2022-07-25 18:52:163042 p->AddCoopIsolatedOriginForBrowsingInstance(
3043 foo_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:593044 EXPECT_EQ(1, GetIsolatedOriginEntryCount(foo));
3045
3046 // Create a SiteInstance for bar.com in a new BrowsingInstance.
3047 scoped_refptr<SiteInstanceImpl> bar_instance =
3048 SiteInstanceImpl::CreateForTesting(&context, GURL("https://bar.com/"));
3049 auto bar_browsing_instance_id =
3050 bar_instance->GetIsolationContext().browsing_instance_id();
3051
3052 // Isolate foo.com for all future BrowsingInstances (with IDs `future_id` or
3053 // above). Note that this shouldn't apply to the existing BrowsingInstances
3054 // for foo_instance and bar_instance.
Lukasz Anforowicz15ba43e2021-07-21 22:50:093055 BrowsingInstanceId future_id(SiteInstanceImpl::NextBrowsingInstanceId());
Alex Moshchukef8c2562021-03-12 06:37:453056 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST, &context);
Alex Moshchuk331fa5f2021-03-10 06:16:593057
3058 // We should now have two entries for foo.com, one for
3059 // foo_browsing_instance_id, and one for future_id.
3060 EXPECT_EQ(2, GetIsolatedOriginEntryCount(foo));
3061
3062 // Verify that foo.com is isolated in the `foo_instance`'s BrowsingInstance,
3063 // as well as future BrowsingInstance IDs.
3064 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
3065 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
3066 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id, foo));
Lukasz Anforowicz15ba43e2021-07-21 22:50:093067 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id.value() + 42, foo));
Alex Moshchuk331fa5f2021-03-10 06:16:593068
3069 // Other origins shouldn't be isolated.
3070 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, bar));
3071 EXPECT_FALSE(IsIsolatedOrigin(&context, bar_browsing_instance_id, bar));
3072 EXPECT_FALSE(IsIsolatedOrigin(&context, future_id, bar));
3073
3074 // An attempt to add foo.com for a specific BrowsingInstance which has ID
3075 // greater than `future_id` should be ignored, since that's already covered
3076 // by the second foo.com entry that applies to future BrowsingInstances.
3077 scoped_refptr<SiteInstanceImpl> future_instance =
3078 SiteInstanceImpl::CreateForTesting(&context, GURL("https://foo.com/"));
Lukasz Anforowicz15ba43e2021-07-21 22:50:093079 EXPECT_EQ(future_id,
3080 future_instance->GetIsolationContext().browsing_instance_id());
W. James MacLeanc07dc41b2022-07-25 18:52:163081 p->AddCoopIsolatedOriginForBrowsingInstance(
3082 future_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:593083 EXPECT_EQ(2, GetIsolatedOriginEntryCount(foo));
3084
3085 // Likewise, an attempt to re-add foo.com for future BrowsingInstances should
3086 // be ignored.
Alex Moshchukef8c2562021-03-12 06:37:453087 p->AddFutureIsolatedOrigins({foo}, IsolatedOriginSource::TEST, &context);
Alex Moshchuk331fa5f2021-03-10 06:16:593088 EXPECT_EQ(2, GetIsolatedOriginEntryCount(foo));
3089
3090 // However, we can still add foo.com isolation to a BrowsingInstance that
3091 // precedes `future_id` and doesn't match `foo_browsing_instance_id`. Check
3092 // this with `bar_instance`'s BrowsingInstance.
Lukasz Anforowicz15ba43e2021-07-21 22:50:093093 EXPECT_LT(bar_browsing_instance_id, future_id);
W. James MacLeanc07dc41b2022-07-25 18:52:163094 p->AddCoopIsolatedOriginForBrowsingInstance(
3095 bar_instance->GetIsolationContext(), foo, IsolatedOriginSource::TEST);
Alex Moshchuk331fa5f2021-03-10 06:16:593096 EXPECT_EQ(3, GetIsolatedOriginEntryCount(foo));
3097 EXPECT_TRUE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
3098 EXPECT_TRUE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
3099 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id, foo));
Lukasz Anforowicz15ba43e2021-07-21 22:50:093100 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id.value() + 42, foo));
Alex Moshchuk331fa5f2021-03-10 06:16:593101
3102 // When foo_instance and its BrowsingInstance goes away, the corresponding
3103 // entry just for that BrowsingInstance entry should be destroyed, but other
3104 // entries should remain.
3105 p->SetBrowsingInstanceCleanupDelayForTesting(0);
3106 foo_instance.reset();
3107 EXPECT_EQ(2, GetIsolatedOriginEntryCount(foo));
3108 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
3109 EXPECT_TRUE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
3110 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id, foo));
Lukasz Anforowicz15ba43e2021-07-21 22:50:093111 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id.value() + 42, foo));
Alex Moshchuk331fa5f2021-03-10 06:16:593112
3113 // Destroying a BrowsingInstance with ID `future_id` shouldn't affect the
3114 // entry that applies to future BrowsingInstances.
3115 future_instance.reset();
3116 EXPECT_EQ(2, GetIsolatedOriginEntryCount(foo));
3117 EXPECT_FALSE(IsIsolatedOrigin(&context, foo_browsing_instance_id, foo));
3118 EXPECT_TRUE(IsIsolatedOrigin(&context, bar_browsing_instance_id, foo));
3119 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id, foo));
Lukasz Anforowicz15ba43e2021-07-21 22:50:093120 EXPECT_TRUE(IsIsolatedOrigin(&context, future_id.value() + 42, foo));
Alex Moshchuk331fa5f2021-03-10 06:16:593121
3122 p->ClearIsolatedOriginsForTesting();
3123}
3124
W. James MacLean24d534b2021-11-22 18:51:353125// This test verifies that CanAccessDataForOrigin returns true for a process id
3126// even if all BrowsingInstanceIDs for that process have been deleted, so long
3127// as the request matches the process' lock. This test sets an origin-keyed
3128// lock.
Alex Moshchuk989aa22c2024-11-06 02:09:073129TEST_P(ChildProcessSecurityPolicyTest, NoBrowsingInstanceIDs_OriginKeyed) {
W. James MacLean24d534b2021-11-22 18:51:353130 url::Origin foo = url::Origin::Create(GURL("https://sub.foo.com/"));
3131 ChildProcessSecurityPolicyImpl* p =
3132 ChildProcessSecurityPolicyImpl::GetInstance();
3133 p->SetBrowsingInstanceCleanupDelayForTesting(0);
3134
3135 // Create a SiteInstance for sub.foo.com in a new BrowsingInstance.
3136 TestBrowserContext context;
3137 {
Camille Lamy5ce9b962025-08-08 12:10:453138 auto oac_header_request =
3139 OriginAgentClusterIsolationState::CreateForOriginAgentCluster(
3140 /*had_oac_request=*/true,
3141 /*requires_origin_keyed_process=*/true);
3142 UrlInfo url_info(
3143 UrlInfoInit(foo.GetURL()).WithOACHeaderRequest(oac_header_request));
W. James MacLean24d534b2021-11-22 18:51:353144 scoped_refptr<SiteInstanceImpl> foo_instance =
Jason Lin218737052023-11-21 08:11:393145 SiteInstanceImpl::CreateForUrlInfo(
3146 &context, url_info,
3147 /*is_guest=*/false,
3148 /*is_fenced=*/false,
3149 /*is_fixed_storage_partition=*/false);
W. James MacLean24d534b2021-11-22 18:51:353150
3151 p->Add(kRendererID, &context);
3152 p->LockProcess(foo_instance->GetIsolationContext(), kRendererID,
Charlie Reis47457a62022-05-18 21:57:373153 /*is_process_used=*/false,
Sharon Yang2c077a72021-11-30 02:27:583154 ProcessLock::FromSiteInfo(foo_instance->GetSiteInfo()));
Alex Moshchuk989aa22c2024-11-06 02:09:073155 p->AddCommittedOrigin(kRendererID, foo);
W. James MacLean24d534b2021-11-22 18:51:353156
3157 EXPECT_TRUE(p->GetProcessLock(kRendererID).is_locked_to_site());
3158 EXPECT_TRUE(p->GetProcessLock(kRendererID).is_origin_keyed_process());
3159 EXPECT_EQ(foo.GetURL(), p->GetProcessLock(kRendererID).lock_url());
3160
Sharon Yang2c077a72021-11-30 02:27:583161 EXPECT_TRUE(ProcessLock::FromSiteInfo(foo_instance->GetSiteInfo())
3162 .is_origin_keyed_process());
Camille Lamy5ce9b962025-08-08 12:10:453163 EXPECT_TRUE(
3164 p->DetermineOriginAgentClusterIsolation(
3165 foo_instance->GetIsolationContext(), foo,
3166 OriginAgentClusterIsolationState::CreateNonIsolatedByDefault())
3167 .requires_origin_keyed_process());
W. James MacLean24d534b2021-11-22 18:51:353168 }
3169 // At this point foo_instance has gone away, and all BrowsingInstanceIDs
3170 // associated with kRendererID have been cleaned up.
3171 EXPECT_EQ(static_cast<size_t>(0),
3172 p->BrowsingInstanceIdCountForTesting(kRendererID));
3173
3174 // Because the ProcessLock is origin-keyed, we expect sub.foo.com to match but
3175 // not foo.com.
3176 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo));
3177 EXPECT_FALSE(p->CanAccessDataForOrigin(
3178 kRendererID, url::Origin::Create(GURL("https://foo.com/"))));
3179 EXPECT_FALSE(p->CanAccessDataForOrigin(
3180 kRendererID, url::Origin::Create(GURL("https://bar.com/"))));
3181
3182 // We need to remove it otherwise other tests may fail.
3183 p->Remove(kRendererID);
3184}
3185
3186// This test verifies that CanAccessDataForOrigin returns true for a process id
3187// even if all BrowsingInstanceIDs for that process have been deleted, so long
3188// as the request matches the process' lock. This test sets a site-keyed lock.
Alex Moshchuk989aa22c2024-11-06 02:09:073189TEST_P(ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
W. James MacLean5eaf0bd2024-06-26 21:15:323190 NoBrowsingInstanceIDs_SiteKeyed) {
Alex Moshchuk989aa22c2024-11-06 02:09:073191 url::Origin sub_foo_origin =
3192 url::Origin::Create(GURL("https://sub.foo.com/"));
W. James MacLean24d534b2021-11-22 18:51:353193 ChildProcessSecurityPolicyImpl* p =
3194 ChildProcessSecurityPolicyImpl::GetInstance();
3195 p->SetBrowsingInstanceCleanupDelayForTesting(0);
3196
3197 // Create a SiteInstance for sub.foo.com in a new BrowsingInstance.
3198 TestBrowserContext context;
3199 {
3200 p->Add(kRendererID, &context);
3201 // Isolate foo.com so we can't get a default SiteInstance. This will mean
3202 // that https://sub.foo.com will end up in a site-keyed SiteInstance, which
3203 // is what we need.
3204 p->AddFutureIsolatedOrigins({url::Origin::Create(GURL("https://foo.com"))},
3205 IsolatedOriginSource::TEST, &context);
3206
Alex Moshchuk989aa22c2024-11-06 02:09:073207 UrlInfo url_info(UrlInfoInit(sub_foo_origin.GetURL()));
W. James MacLean24d534b2021-11-22 18:51:353208 scoped_refptr<SiteInstanceImpl> foo_instance =
Jason Lin218737052023-11-21 08:11:393209 SiteInstanceImpl::CreateForUrlInfo(
3210 &context, url_info,
3211 /*is_guest=*/false,
3212 /*is_fenced=*/false,
3213 /*is_fixed_storage_partition=*/false);
W. James MacLean24d534b2021-11-22 18:51:353214 p->LockProcess(foo_instance->GetIsolationContext(), kRendererID,
Charlie Reis47457a62022-05-18 21:57:373215 /*is_process_used=*/false,
Sharon Yang2c077a72021-11-30 02:27:583216 ProcessLock::FromSiteInfo(foo_instance->GetSiteInfo()));
Alex Moshchuk989aa22c2024-11-06 02:09:073217 p->AddCommittedOrigin(kRendererID, sub_foo_origin);
W. James MacLean24d534b2021-11-22 18:51:353218
3219 EXPECT_TRUE(p->GetProcessLock(kRendererID).is_locked_to_site());
3220 EXPECT_FALSE(p->GetProcessLock(kRendererID).is_origin_keyed_process());
Alex Moshchuk989aa22c2024-11-06 02:09:073221 EXPECT_EQ(SiteInfo::GetSiteForOrigin(sub_foo_origin),
W. James MacLean24d534b2021-11-22 18:51:353222 p->GetProcessLock(kRendererID).lock_url());
3223
Sharon Yang2c077a72021-11-30 02:27:583224 EXPECT_FALSE(ProcessLock::FromSiteInfo(foo_instance->GetSiteInfo())
3225 .is_origin_keyed_process());
Camille Lamy5ce9b962025-08-08 12:10:453226 EXPECT_FALSE(
3227 p->DetermineOriginAgentClusterIsolation(
3228 foo_instance->GetIsolationContext(), sub_foo_origin,
3229 OriginAgentClusterIsolationState::CreateNonIsolatedByDefault())
3230 .requires_origin_keyed_process());
W. James MacLean24d534b2021-11-22 18:51:353231 }
3232 // At this point foo_instance has gone away, and all BrowsingInstanceIDs
3233 // associated with kRendererID have been cleaned up.
3234 EXPECT_EQ(static_cast<size_t>(0),
3235 p->BrowsingInstanceIdCountForTesting(kRendererID));
3236
3237 // Because the ProcessLock is site-keyed, it should match foo.com and all
Alex Moshchuk989aa22c2024-11-06 02:09:073238 // sub-origins. However, if we're in the new enforcement mode based on a list
3239 // of committed origins, then only the specific origin we've committed
3240 // (sub.foo.com) will be allowed access. The other origin (foo.com) would need
3241 // to also be committed to get access.
3242 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, sub_foo_origin));
3243 url::Origin foo_origin(url::Origin::Create(GURL("https://foo.com/")));
3244 if (base::FeatureList::IsEnabled(features::kCommittedOriginEnforcements)) {
3245 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo_origin));
3246 p->AddCommittedOrigin(kRendererID, foo_origin);
3247 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_origin));
3248 } else {
3249 EXPECT_TRUE(p->CanAccessDataForOrigin(kRendererID, foo_origin));
3250 }
W. James MacLean24d534b2021-11-22 18:51:353251 EXPECT_FALSE(p->CanAccessDataForOrigin(
3252 kRendererID, url::Origin::Create(GURL("https://bar.com/"))));
3253
3254 // We need to remove it otherwise other tests may fail.
3255 p->Remove(kRendererID);
3256}
3257
3258// This test verifies that CanAccessDataForOrigin returns false for a process id
3259// when all BrowsingInstanceIDs for that process have been deleted, and the
3260// ProcessLock has is_locked_to_site() = false, regardless of the url requested.
Alex Moshchuk989aa22c2024-11-06 02:09:073261TEST_P(ChildProcessSecurityPolicyTest, NoBrowsingInstanceIDs_UnlockedProcess) {
W. James MacLean24d534b2021-11-22 18:51:353262 GURL foo_url = GURL("https://foo.com/");
3263 url::Origin foo = url::Origin::Create(foo_url);
3264
3265 ChildProcessSecurityPolicyImpl* p =
3266 ChildProcessSecurityPolicyImpl::GetInstance();
3267 p->SetBrowsingInstanceCleanupDelayForTesting(0);
3268
W. James MacLean24d534b2021-11-22 18:51:353269 base::test::ScopedCommandLine scoped_command_line;
3270 // Disable site isolation so we can get default SiteInstances on all
3271 // platforms.
3272 scoped_command_line.GetProcessCommandLine()->AppendSwitch(
3273 switches::kDisableSiteIsolation);
3274 // If --site-per-process was manually appended, remove it; this interferes
3275 // with default SiteInstances.
3276 scoped_command_line.GetProcessCommandLine()->RemoveSwitch(
3277 switches::kSitePerProcess);
3278
3279 EXPECT_FALSE(SiteIsolationPolicy::UseDedicatedProcessesForAllSites());
3280 EXPECT_EQ(static_cast<size_t>(0),
3281 p->BrowsingInstanceIdCountForTesting(kRendererID));
3282
3283 TestBrowserContext context;
3284 {
3285 scoped_refptr<SiteInstanceImpl> foo_instance =
Alex Moshchukdf15d8e2022-02-01 04:43:493286 SiteInstanceImpl::CreateForTesting(&context, foo_url);
W. James MacLean24d534b2021-11-22 18:51:353287 // Adds the process with an "allow_any_site" lock.
3288 // The next two statements are basically AddForTesting(...), but with a
3289 // BrowsingInstanceId based on `foo_instance` and not pinned to '1'.
3290 // This is important when this test is run with other tests, as then
3291 // BrowsingInstanceId will not be '1' in general.
3292 p->Add(kRendererID, &context);
3293 p->LockProcess(foo_instance->GetIsolationContext(), kRendererID,
Charlie Reis47457a62022-05-18 21:57:373294 /*is_process_used=*/false,
W. James MacLean24d534b2021-11-22 18:51:353295 ProcessLock::CreateAllowAnySite(
3296 StoragePartitionConfig::CreateDefault(&context),
Camille Lamy52a51202025-07-29 14:16:123297 WebExposedIsolationInfo::CreateNonIsolated(),
3298 /*cross_origin_isolation_key=*/std::nullopt));
W. James MacLean24d534b2021-11-22 18:51:353299
W. James MacLean24d534b2021-11-22 18:51:353300 EXPECT_TRUE(foo_instance->HasSite());
Sharon Yang6c216e22025-05-13 07:49:263301 if (ShouldUseDefaultSiteInstanceGroup()) {
3302 EXPECT_EQ(foo_instance->group(),
3303 foo_instance->DefaultSiteInstanceGroupForBrowsingInstance());
3304 EXPECT_EQ(foo_instance->GetSiteURL(), foo_url);
3305 } else {
3306 EXPECT_TRUE(foo_instance->IsDefaultSiteInstance());
3307 EXPECT_EQ(foo_instance->GetSiteInfo(),
3308 SiteInfo::CreateForDefaultSiteInstance(
3309 foo_instance->GetIsolationContext(),
3310 StoragePartitionConfig::CreateDefault(&context),
Camille Lamy52a51202025-07-29 14:16:123311 WebExposedIsolationInfo::CreateNonIsolated(),
3312 /*cross_origin_isolation_key=*/std::nullopt));
Sharon Yang6c216e22025-05-13 07:49:263313 }
W. James MacLean24d534b2021-11-22 18:51:353314 EXPECT_FALSE(foo_instance->RequiresDedicatedProcess());
3315 }
3316 // At this point foo_instance has gone away, and all BrowsingInstanceIDs
3317 // associated with kRendererID have been cleaned up.
3318 EXPECT_EQ(static_cast<size_t>(0),
3319 p->BrowsingInstanceIdCountForTesting(kRendererID));
3320
3321 EXPECT_FALSE(p->GetProcessLock(kRendererID).is_locked_to_site());
3322 // Ensure that we don't allow the process to keep accessing data for foo after
3323 // all of the BrowsingInstances are gone, since that would require checking
3324 // whether foo itself requires a dedicated process.
3325 EXPECT_FALSE(p->CanAccessDataForOrigin(kRendererID, foo));
3326
3327 // We need to remove it otherwise other tests may fail.
3328 p->Remove(kRendererID);
3329}
3330
Charlie Reis47457a62022-05-18 21:57:373331// Regression test for https://crbug.com/1324407.
Alex Moshchuk989aa22c2024-11-06 02:09:073332TEST_P(ChildProcessSecurityPolicyTest, CannotLockUsedProcessToSite) {
Charlie Reis47457a62022-05-18 21:57:373333 ChildProcessSecurityPolicyImpl* p =
3334 ChildProcessSecurityPolicyImpl::GetInstance();
3335 TestBrowserContext context;
3336
3337 scoped_refptr<SiteInstanceImpl> foo_instance =
3338 SiteInstanceImpl::CreateForTesting(&context, GURL("https://foo.com"));
3339 scoped_refptr<SiteInstanceImpl> bar_instance =
3340 SiteInstanceImpl::CreateForTesting(&context, GURL("https://bar.com"));
3341
3342 // Start by putting foo.com into an allows-any-site process.
3343 p->Add(kRendererID, &context);
3344 p->LockProcess(foo_instance->GetIsolationContext(), kRendererID,
3345 /*is_process_used=*/false,
3346 ProcessLock::CreateAllowAnySite(
3347 StoragePartitionConfig::CreateDefault(&context),
Camille Lamy52a51202025-07-29 14:16:123348 WebExposedIsolationInfo::CreateNonIsolated(),
3349 /*cross_origin_isolation_key=*/std::nullopt));
Charlie Reis47457a62022-05-18 21:57:373350 EXPECT_TRUE(p->GetProcessLock(kRendererID).allows_any_site());
3351 EXPECT_FALSE(p->GetProcessLock(kRendererID).is_locked_to_site());
3352
3353 // If the process is then considered used (e.g., by loading content), it
3354 // should not be possible to lock it to another site.
Arthur Sonzogni4b818ae2022-10-25 22:09:523355 EXPECT_CHECK_DEATH_WITH(
Charlie Reis47457a62022-05-18 21:57:373356 {
3357 p->LockProcess(bar_instance->GetIsolationContext(), kRendererID,
3358 /*is_process_used=*/true,
3359 ProcessLock::FromSiteInfo(bar_instance->GetSiteInfo()));
3360 },
Arthur Sonzogni4b818ae2022-10-25 22:09:523361 "Cannot lock an already used process to .*bar\\.com");
Sharon Yang320a77f2022-12-14 23:01:273362
3363 // We need to remove it otherwise other tests may fail.
3364 p->Remove(kRendererID);
Charlie Reis47457a62022-05-18 21:57:373365}
Charlie Reis47457a62022-05-18 21:57:373366
Peter KHa027bf62025-07-29 15:22:523367// Test that
3368// ChildProcessSecurityPolicyImpl::AddV8OptimizationDisabledStateForOrigin()
3369// ignores opaque origins.
3370TEST_P(ChildProcessSecurityPolicyTest,
3371 AddV8OptimizationDisabledStateForOpaqueOrigin) {
3372 ChildProcessSecurityPolicyImpl* p =
3373 ChildProcessSecurityPolicyImpl::GetInstance();
3374 BrowsingInstanceId browsing_instance_id =
3375 SiteInstanceImpl::NextBrowsingInstanceId();
3376 url::Origin opaque_origin;
3377
3378 p->AddV8OptimizationDisabledStateForOrigin(
3379 browsing_instance_id, opaque_origin,
3380 /*are_v8_optimizations_disabled=*/false);
3381 std::optional<bool> are_v8_optimizations_disabled_result =
3382 p->LookupAreV8OptimizationsDisabled(browsing_instance_id, opaque_origin);
3383 EXPECT_FALSE(are_v8_optimizations_disabled_result.has_value());
3384}
3385
3386// Test the behavior of
3387// ChildProcessSecurityPolicyImpl::AddV8OptimizationDisabledStateForOrigin()
3388// for non-opaque origins.
3389TEST_P(ChildProcessSecurityPolicyTest,
3390 AddV8OptimizationDisabledStateForNonOpaqueOrigin) {
3391 ChildProcessSecurityPolicyImpl* p =
3392 ChildProcessSecurityPolicyImpl::GetInstance();
3393 BrowsingInstanceId browsing_instance_id =
3394 BrowsingInstanceId::FromUnsafeValue(1);
3395 url::Origin origin = url::Origin::Create(GURL("https://foo.com"));
3396
3397 p->AddV8OptimizationDisabledStateForOrigin(
3398 browsing_instance_id, origin, /*are_v8_optimizations_disabled=*/false);
3399 EXPECT_EQ(std::optional<bool>(false),
3400 p->LookupAreV8OptimizationsDisabled(browsing_instance_id, origin));
3401
3402 EXPECT_FALSE(
3403 p->LookupAreV8OptimizationsDisabled(
3404 browsing_instance_id, url::Origin::Create(GURL("https://bar.com")))
3405 .has_value());
3406 EXPECT_FALSE(p->LookupAreV8OptimizationsDisabled(
3407 browsing_instance_id,
3408 url::Origin::Create(GURL("https://subdomain.foo.com")))
3409 .has_value());
3410
3411 EXPECT_FALSE(p->LookupAreV8OptimizationsDisabled(
3412 BrowsingInstanceId::FromUnsafeValue(2), origin)
3413 .has_value());
3414}
3415
Alex Moshchuk989aa22c2024-11-06 02:09:073416INSTANTIATE_TEST_SUITE_P(
3417 ,
3418 ChildProcessSecurityPolicyTest,
3419 ::testing::Values(ChildProcessSecurityPolicyTestCase::
3420 kCommittedOriginEnforcementsDisabled,
3421 ChildProcessSecurityPolicyTestCase::
3422 kCommittedOriginEnforcementsEnabled),
3423 &ChildProcessSecurityPolicyTest::DescribeParams);
3424
3425INSTANTIATE_TEST_SUITE_P(
3426 ,
3427 ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
3428 ::testing::Values(ChildProcessSecurityPolicyTestCase::
3429 kCommittedOriginEnforcementsDisabled,
3430 ChildProcessSecurityPolicyTestCase::
3431 kCommittedOriginEnforcementsEnabled),
3432 &ChildProcessSecurityPolicyTest::DescribeParams);
3433
[email protected]46488322012-10-30 03:22:203434} // namespace content