1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/basictypes.h"
9 #include "base/files/file_path.h"
10 #include "content/browser/child_process_security_policy_impl.h"
11 #include "content/public/common/url_constants.h"
12 #include "content/test/test_content_browser_client.h"
13 #include "storage/browser/fileapi/file_permission_policy.h"
14 #include "storage/browser/fileapi/file_system_url.h"
15 #include "storage/browser/fileapi/isolated_context.h"
16 #include "storage/common/fileapi/file_system_types.h"
17 #include "testing/gtest/include/gtest/gtest.h"
23 const int kRendererID
= 42;
24 const int kWorkerRendererID
= kRendererID
+ 1;
26 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
27 #define TEST_PATH(x) FILE_PATH_LITERAL("c:") FILE_PATH_LITERAL(x)
29 #define TEST_PATH(x) FILE_PATH_LITERAL(x)
32 class ChildProcessSecurityPolicyTestBrowserClient
33 : public TestContentBrowserClient
{
35 ChildProcessSecurityPolicyTestBrowserClient() {}
37 bool IsHandledURL(const GURL
& url
) override
{
38 return schemes_
.find(url
.scheme()) != schemes_
.end();
45 void AddScheme(const std::string
& scheme
) {
46 schemes_
.insert(scheme
);
50 std::set
<std::string
> schemes_
;
55 class ChildProcessSecurityPolicyTest
: public testing::Test
{
57 ChildProcessSecurityPolicyTest() : old_browser_client_(NULL
) {
60 void SetUp() override
{
61 old_browser_client_
= SetBrowserClientForTesting(&test_browser_client_
);
63 // Claim to always handle chrome:// URLs because the CPSP's notion of
64 // allowing WebUI bindings is hard-wired to this particular scheme.
65 test_browser_client_
.AddScheme(kChromeUIScheme
);
67 // Claim to always handle file:// URLs like the browser would.
68 // net::URLRequest::IsHandledURL() no longer claims support for default
69 // protocols as this is the responsibility of the browser (which is
70 // responsible for adding the appropriate ProtocolHandler).
71 test_browser_client_
.AddScheme(url::kFileScheme
);
74 void TearDown() override
{
75 test_browser_client_
.ClearSchemes();
76 SetBrowserClientForTesting(old_browser_client_
);
80 void RegisterTestScheme(const std::string
& scheme
) {
81 test_browser_client_
.AddScheme(scheme
);
84 void GrantPermissionsForFile(ChildProcessSecurityPolicyImpl
* p
,
86 const base::FilePath
& file
,
88 p
->GrantPermissionsForFile(child_id
, file
, permissions
);
91 void CheckHasNoFileSystemPermission(ChildProcessSecurityPolicyImpl
* p
,
92 const std::string
& child_id
) {
93 EXPECT_FALSE(p
->CanReadFileSystem(kRendererID
, child_id
));
94 EXPECT_FALSE(p
->CanReadWriteFileSystem(kRendererID
, child_id
));
95 EXPECT_FALSE(p
->CanCopyIntoFileSystem(kRendererID
, child_id
));
96 EXPECT_FALSE(p
->CanDeleteFromFileSystem(kRendererID
, child_id
));
99 void CheckHasNoFileSystemFilePermission(ChildProcessSecurityPolicyImpl
* p
,
100 const base::FilePath
& file
,
101 const storage::FileSystemURL
& url
) {
102 EXPECT_FALSE(p
->CanReadFile(kRendererID
, file
));
103 EXPECT_FALSE(p
->CanCreateReadWriteFile(kRendererID
, file
));
104 EXPECT_FALSE(p
->CanReadFileSystemFile(kRendererID
, url
));
105 EXPECT_FALSE(p
->CanWriteFileSystemFile(kRendererID
, url
));
106 EXPECT_FALSE(p
->CanCreateFileSystemFile(kRendererID
, url
));
107 EXPECT_FALSE(p
->CanCreateReadWriteFileSystemFile(kRendererID
, url
));
108 EXPECT_FALSE(p
->CanCopyIntoFileSystemFile(kRendererID
, url
));
109 EXPECT_FALSE(p
->CanDeleteFileSystemFile(kRendererID
, url
));
113 ChildProcessSecurityPolicyTestBrowserClient test_browser_client_
;
114 ContentBrowserClient
* old_browser_client_
;
118 TEST_F(ChildProcessSecurityPolicyTest
, IsWebSafeSchemeTest
) {
119 ChildProcessSecurityPolicyImpl
* p
=
120 ChildProcessSecurityPolicyImpl::GetInstance();
122 EXPECT_TRUE(p
->IsWebSafeScheme(url::kHttpScheme
));
123 EXPECT_TRUE(p
->IsWebSafeScheme(url::kHttpsScheme
));
124 EXPECT_TRUE(p
->IsWebSafeScheme(url::kFtpScheme
));
125 EXPECT_TRUE(p
->IsWebSafeScheme(url::kDataScheme
));
126 EXPECT_TRUE(p
->IsWebSafeScheme("feed"));
127 EXPECT_TRUE(p
->IsWebSafeScheme(url::kBlobScheme
));
128 EXPECT_TRUE(p
->IsWebSafeScheme(url::kFileSystemScheme
));
130 EXPECT_FALSE(p
->IsWebSafeScheme("registered-web-safe-scheme"));
131 p
->RegisterWebSafeScheme("registered-web-safe-scheme");
132 EXPECT_TRUE(p
->IsWebSafeScheme("registered-web-safe-scheme"));
134 EXPECT_FALSE(p
->IsWebSafeScheme(kChromeUIScheme
));
137 TEST_F(ChildProcessSecurityPolicyTest
, IsPseudoSchemeTest
) {
138 ChildProcessSecurityPolicyImpl
* p
=
139 ChildProcessSecurityPolicyImpl::GetInstance();
141 EXPECT_TRUE(p
->IsPseudoScheme(url::kAboutScheme
));
142 EXPECT_TRUE(p
->IsPseudoScheme(url::kJavaScriptScheme
));
143 EXPECT_TRUE(p
->IsPseudoScheme(kViewSourceScheme
));
145 EXPECT_FALSE(p
->IsPseudoScheme("registered-pseudo-scheme"));
146 p
->RegisterPseudoScheme("registered-pseudo-scheme");
147 EXPECT_TRUE(p
->IsPseudoScheme("registered-pseudo-scheme"));
149 EXPECT_FALSE(p
->IsPseudoScheme(kChromeUIScheme
));
152 TEST_F(ChildProcessSecurityPolicyTest
, StandardSchemesTest
) {
153 ChildProcessSecurityPolicyImpl
* p
=
154 ChildProcessSecurityPolicyImpl::GetInstance();
158 // Safe to request or commit.
159 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("http://www.google.com/")));
160 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("https://www.paypal.com/")));
161 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("ftp://ftp.gnu.org/")));
162 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("data:text/html,<b>Hi</b>")));
163 EXPECT_TRUE(p
->CanRequestURL(
164 kRendererID
, GURL("filesystem:http://localhost/temporary/a.gif")));
165 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("http://www.google.com/")));
166 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("https://www.paypal.com/")));
167 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("ftp://ftp.gnu.org/")));
168 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("data:text/html,<b>Hi</b>")));
169 EXPECT_TRUE(p
->CanCommitURL(
170 kRendererID
, GURL("filesystem:http://localhost/temporary/a.gif")));
172 // Safe to request but not commit.
173 EXPECT_TRUE(p
->CanRequestURL(kRendererID
,
174 GURL("view-source:http://www.google.com/")));
175 EXPECT_FALSE(p
->CanCommitURL(kRendererID
,
176 GURL("view-source:http://www.google.com/")));
178 // Dangerous to request or commit.
179 EXPECT_FALSE(p
->CanRequestURL(kRendererID
,
180 GURL("file:///etc/passwd")));
181 EXPECT_FALSE(p
->CanRequestURL(kRendererID
,
182 GURL("chrome://foo/bar")));
183 EXPECT_FALSE(p
->CanCommitURL(kRendererID
,
184 GURL("file:///etc/passwd")));
185 EXPECT_FALSE(p
->CanCommitURL(kRendererID
,
186 GURL("chrome://foo/bar")));
188 p
->Remove(kRendererID
);
191 TEST_F(ChildProcessSecurityPolicyTest
, AboutTest
) {
192 ChildProcessSecurityPolicyImpl
* p
=
193 ChildProcessSecurityPolicyImpl::GetInstance();
197 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("about:blank")));
198 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("about:BlAnK")));
199 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("aBouT:BlAnK")));
200 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("aBouT:blank")));
201 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("about:blank")));
202 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("about:BlAnK")));
203 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("aBouT:BlAnK")));
204 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("aBouT:blank")));
206 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("about:memory")));
207 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("about:crash")));
208 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("about:cache")));
209 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("about:hang")));
210 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("about:memory")));
211 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("about:crash")));
212 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("about:cache")));
213 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("about:hang")));
215 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("aBoUt:memory")));
216 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("about:CrASh")));
217 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("abOuT:cAChe")));
218 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("aBoUt:memory")));
219 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("about:CrASh")));
220 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("abOuT:cAChe")));
222 // Requests for about: pages should be denied.
223 p
->GrantRequestURL(kRendererID
, GURL("about:crash"));
224 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("about:crash")));
225 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("about:crash")));
227 // These requests for chrome:// pages should be granted.
228 GURL
chrome_url("chrome://foo");
229 p
->GrantRequestURL(kRendererID
, chrome_url
);
230 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, chrome_url
));
231 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, chrome_url
));
233 p
->Remove(kRendererID
);
236 TEST_F(ChildProcessSecurityPolicyTest
, JavaScriptTest
) {
237 ChildProcessSecurityPolicyImpl
* p
=
238 ChildProcessSecurityPolicyImpl::GetInstance();
242 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("javascript:alert('xss')")));
243 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("javascript:alert('xss')")));
244 p
->GrantRequestURL(kRendererID
, GURL("javascript:alert('xss')"));
245 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("javascript:alert('xss')")));
246 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("javascript:alert('xss')")));
248 p
->Remove(kRendererID
);
251 TEST_F(ChildProcessSecurityPolicyTest
, RegisterWebSafeSchemeTest
) {
252 ChildProcessSecurityPolicyImpl
* p
=
253 ChildProcessSecurityPolicyImpl::GetInstance();
257 // Currently, "asdf" is destined for ShellExecute, so it is allowed to be
258 // requested but not committed.
259 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("asdf:rockers")));
260 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("asdf:rockers")));
262 // Once we register "asdf", we default to deny.
263 RegisterTestScheme("asdf");
264 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("asdf:rockers")));
265 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("asdf:rockers")));
267 // We can allow new schemes by adding them to the whitelist.
268 p
->RegisterWebSafeScheme("asdf");
269 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("asdf:rockers")));
270 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("asdf:rockers")));
273 p
->Remove(kRendererID
);
276 TEST_F(ChildProcessSecurityPolicyTest
, CanServiceCommandsTest
) {
277 ChildProcessSecurityPolicyImpl
* p
=
278 ChildProcessSecurityPolicyImpl::GetInstance();
282 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("file:///etc/passwd")));
283 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("file:///etc/passwd")));
284 p
->GrantRequestURL(kRendererID
, GURL("file:///etc/passwd"));
285 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("file:///etc/passwd")));
286 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("file:///etc/passwd")));
288 // We should forget our state if we repeat a renderer id.
289 p
->Remove(kRendererID
);
291 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("file:///etc/passwd")));
292 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("file:///etc/passwd")));
293 p
->Remove(kRendererID
);
296 TEST_F(ChildProcessSecurityPolicyTest
, ViewSource
) {
297 ChildProcessSecurityPolicyImpl
* p
=
298 ChildProcessSecurityPolicyImpl::GetInstance();
302 // View source is determined by the embedded scheme.
303 EXPECT_TRUE(p
->CanRequestURL(kRendererID
,
304 GURL("view-source:http://www.google.com/")));
305 EXPECT_FALSE(p
->CanRequestURL(kRendererID
,
306 GURL("view-source:file:///etc/passwd")));
307 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, GURL("file:///etc/passwd")));
308 EXPECT_FALSE(p
->CanRequestURL(
309 kRendererID
, GURL("view-source:view-source:http://www.google.com/")));
311 // View source URLs don't actually commit; the renderer is put into view
312 // source mode, and the inner URL commits.
313 EXPECT_FALSE(p
->CanCommitURL(kRendererID
,
314 GURL("view-source:http://www.google.com/")));
315 EXPECT_FALSE(p
->CanCommitURL(kRendererID
,
316 GURL("view-source:file:///etc/passwd")));
317 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, GURL("file:///etc/passwd")));
318 EXPECT_FALSE(p
->CanCommitURL(
319 kRendererID
, GURL("view-source:view-source:http://www.google.com/")));
322 p
->GrantRequestURL(kRendererID
, GURL("view-source:file:///etc/passwd"));
323 // View source needs to be able to request the embedded scheme.
324 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, GURL("file:///etc/passwd")));
325 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, GURL("file:///etc/passwd")));
326 EXPECT_TRUE(p
->CanRequestURL(kRendererID
,
327 GURL("view-source:file:///etc/passwd")));
328 EXPECT_FALSE(p
->CanCommitURL(kRendererID
,
329 GURL("view-source:file:///etc/passwd")));
331 p
->Remove(kRendererID
);
334 TEST_F(ChildProcessSecurityPolicyTest
, SpecificFile
) {
335 ChildProcessSecurityPolicyImpl
* p
=
336 ChildProcessSecurityPolicyImpl::GetInstance();
340 GURL
icon_url("file:///tmp/foo.png");
341 GURL
sensitive_url("file:///etc/passwd");
342 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, icon_url
));
343 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, sensitive_url
));
344 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, icon_url
));
345 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, sensitive_url
));
347 p
->GrantRequestSpecificFileURL(kRendererID
, icon_url
);
348 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, icon_url
));
349 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, sensitive_url
));
350 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, icon_url
));
351 EXPECT_FALSE(p
->CanCommitURL(kRendererID
, sensitive_url
));
353 p
->GrantRequestURL(kRendererID
, icon_url
);
354 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, icon_url
));
355 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, sensitive_url
));
356 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, icon_url
));
357 EXPECT_TRUE(p
->CanCommitURL(kRendererID
, sensitive_url
));
359 p
->Remove(kRendererID
);
362 TEST_F(ChildProcessSecurityPolicyTest
, FileSystemGrantsTest
) {
363 ChildProcessSecurityPolicyImpl
* p
=
364 ChildProcessSecurityPolicyImpl::GetInstance();
367 std::string read_id
=
368 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
369 storage::kFileSystemTypeTest
, "read_filesystem", base::FilePath());
370 std::string read_write_id
=
371 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
372 storage::kFileSystemTypeTest
,
373 "read_write_filesystem",
375 std::string copy_into_id
=
376 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
377 storage::kFileSystemTypeTest
,
378 "copy_into_filesystem",
380 std::string delete_from_id
=
381 storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
382 storage::kFileSystemTypeTest
,
383 "delete_from_filesystem",
386 // Test initially having no permissions.
387 CheckHasNoFileSystemPermission(p
, read_id
);
388 CheckHasNoFileSystemPermission(p
, read_write_id
);
389 CheckHasNoFileSystemPermission(p
, copy_into_id
);
390 CheckHasNoFileSystemPermission(p
, delete_from_id
);
392 // Testing varying combinations of grants and checks.
393 p
->GrantReadFileSystem(kRendererID
, read_id
);
394 EXPECT_TRUE(p
->CanReadFileSystem(kRendererID
, read_id
));
395 EXPECT_FALSE(p
->CanReadWriteFileSystem(kRendererID
, read_id
));
396 EXPECT_FALSE(p
->CanCopyIntoFileSystem(kRendererID
, read_id
));
397 EXPECT_FALSE(p
->CanDeleteFromFileSystem(kRendererID
, read_id
));
399 p
->GrantReadFileSystem(kRendererID
, read_write_id
);
400 p
->GrantWriteFileSystem(kRendererID
, read_write_id
);
401 EXPECT_TRUE(p
->CanReadFileSystem(kRendererID
, read_write_id
));
402 EXPECT_TRUE(p
->CanReadWriteFileSystem(kRendererID
, read_write_id
));
403 EXPECT_FALSE(p
->CanCopyIntoFileSystem(kRendererID
, read_write_id
));
404 EXPECT_FALSE(p
->CanDeleteFromFileSystem(kRendererID
, read_write_id
));
406 p
->GrantCopyIntoFileSystem(kRendererID
, copy_into_id
);
407 EXPECT_FALSE(p
->CanReadFileSystem(kRendererID
, copy_into_id
));
408 EXPECT_FALSE(p
->CanReadWriteFileSystem(kRendererID
, copy_into_id
));
409 EXPECT_TRUE(p
->CanCopyIntoFileSystem(kRendererID
, copy_into_id
));
410 EXPECT_FALSE(p
->CanDeleteFromFileSystem(kRendererID
, copy_into_id
));
412 p
->GrantDeleteFromFileSystem(kRendererID
, delete_from_id
);
413 EXPECT_FALSE(p
->CanReadFileSystem(kRendererID
, delete_from_id
));
414 EXPECT_FALSE(p
->CanReadWriteFileSystem(kRendererID
, delete_from_id
));
415 EXPECT_FALSE(p
->CanCopyIntoFileSystem(kRendererID
, delete_from_id
));
416 EXPECT_TRUE(p
->CanDeleteFromFileSystem(kRendererID
, delete_from_id
));
418 // Test revoke permissions on renderer ID removal.
419 p
->Remove(kRendererID
);
420 CheckHasNoFileSystemPermission(p
, read_id
);
421 CheckHasNoFileSystemPermission(p
, read_write_id
);
422 CheckHasNoFileSystemPermission(p
, copy_into_id
);
423 CheckHasNoFileSystemPermission(p
, delete_from_id
);
425 // Test having no permissions upon re-adding same renderer ID.
427 CheckHasNoFileSystemPermission(p
, read_id
);
428 CheckHasNoFileSystemPermission(p
, read_write_id
);
429 CheckHasNoFileSystemPermission(p
, copy_into_id
);
430 CheckHasNoFileSystemPermission(p
, delete_from_id
);
433 p
->Remove(kRendererID
);
434 storage::IsolatedContext::GetInstance()->RevokeFileSystem(read_id
);
435 storage::IsolatedContext::GetInstance()->RevokeFileSystem(read_write_id
);
436 storage::IsolatedContext::GetInstance()->RevokeFileSystem(copy_into_id
);
437 storage::IsolatedContext::GetInstance()->RevokeFileSystem(delete_from_id
);
440 TEST_F(ChildProcessSecurityPolicyTest
, FilePermissionGrantingAndRevoking
) {
441 ChildProcessSecurityPolicyImpl
* p
=
442 ChildProcessSecurityPolicyImpl::GetInstance();
444 p
->RegisterFileSystemPermissionPolicy(
445 storage::kFileSystemTypeTest
,
446 storage::FILE_PERMISSION_USE_FILE_PERMISSION
);
449 base::FilePath
file(TEST_PATH("/dir/testfile"));
450 file
= file
.NormalizePathSeparators();
451 storage::FileSystemURL url
= storage::FileSystemURL::CreateForTest(
452 GURL("http://foo/"), storage::kFileSystemTypeTest
, file
);
454 // Test initially having no permissions.
455 CheckHasNoFileSystemFilePermission(p
, file
, url
);
457 // Testing every combination of permissions granting and revoking.
458 p
->GrantReadFile(kRendererID
, file
);
459 EXPECT_TRUE(p
->CanReadFile(kRendererID
, file
));
460 EXPECT_FALSE(p
->CanCreateReadWriteFile(kRendererID
, file
));
461 EXPECT_TRUE(p
->CanReadFileSystemFile(kRendererID
, url
));
462 EXPECT_FALSE(p
->CanWriteFileSystemFile(kRendererID
, url
));
463 EXPECT_FALSE(p
->CanCreateFileSystemFile(kRendererID
, url
));
464 EXPECT_FALSE(p
->CanCreateReadWriteFileSystemFile(kRendererID
, url
));
465 EXPECT_FALSE(p
->CanCopyIntoFileSystemFile(kRendererID
, url
));
466 EXPECT_FALSE(p
->CanDeleteFileSystemFile(kRendererID
, url
));
467 p
->RevokeAllPermissionsForFile(kRendererID
, file
);
468 CheckHasNoFileSystemFilePermission(p
, file
, url
);
470 p
->GrantCreateReadWriteFile(kRendererID
, file
);
471 EXPECT_TRUE(p
->CanReadFile(kRendererID
, file
));
472 EXPECT_TRUE(p
->CanCreateReadWriteFile(kRendererID
, file
));
473 EXPECT_TRUE(p
->CanReadFileSystemFile(kRendererID
, url
));
474 EXPECT_TRUE(p
->CanWriteFileSystemFile(kRendererID
, url
));
475 EXPECT_TRUE(p
->CanCreateFileSystemFile(kRendererID
, url
));
476 EXPECT_TRUE(p
->CanCreateReadWriteFileSystemFile(kRendererID
, url
));
477 EXPECT_TRUE(p
->CanCopyIntoFileSystemFile(kRendererID
, url
));
478 EXPECT_TRUE(p
->CanDeleteFileSystemFile(kRendererID
, url
));
479 p
->RevokeAllPermissionsForFile(kRendererID
, file
);
480 CheckHasNoFileSystemFilePermission(p
, file
, url
);
482 // Test revoke permissions on renderer ID removal.
483 p
->GrantCreateReadWriteFile(kRendererID
, file
);
484 EXPECT_TRUE(p
->CanReadFile(kRendererID
, file
));
485 EXPECT_TRUE(p
->CanCreateReadWriteFile(kRendererID
, file
));
486 EXPECT_TRUE(p
->CanReadFileSystemFile(kRendererID
, url
));
487 EXPECT_TRUE(p
->CanWriteFileSystemFile(kRendererID
, url
));
488 EXPECT_TRUE(p
->CanCreateFileSystemFile(kRendererID
, url
));
489 EXPECT_TRUE(p
->CanCreateReadWriteFileSystemFile(kRendererID
, url
));
490 EXPECT_TRUE(p
->CanCopyIntoFileSystemFile(kRendererID
, url
));
491 EXPECT_TRUE(p
->CanDeleteFileSystemFile(kRendererID
, url
));
492 p
->Remove(kRendererID
);
493 CheckHasNoFileSystemFilePermission(p
, file
, url
);
495 // Test having no permissions upon re-adding same renderer ID.
497 CheckHasNoFileSystemFilePermission(p
, file
, url
);
500 p
->Remove(kRendererID
);
503 TEST_F(ChildProcessSecurityPolicyTest
, FilePermissions
) {
504 base::FilePath granted_file
= base::FilePath(TEST_PATH("/home/joe"));
505 base::FilePath sibling_file
= base::FilePath(TEST_PATH("/home/bob"));
506 base::FilePath child_file
= base::FilePath(TEST_PATH("/home/joe/file"));
507 base::FilePath parent_file
= base::FilePath(TEST_PATH("/home"));
508 base::FilePath parent_slash_file
= base::FilePath(TEST_PATH("/home/"));
509 base::FilePath child_traversal1
=
510 base::FilePath(TEST_PATH("/home/joe/././file"));
511 base::FilePath child_traversal2
= base::FilePath(
512 TEST_PATH("/home/joe/file/../otherfile"));
513 base::FilePath evil_traversal1
=
514 base::FilePath(TEST_PATH("/home/joe/../../etc/passwd"));
515 base::FilePath evil_traversal2
= base::FilePath(
516 TEST_PATH("/home/joe/./.././../etc/passwd"));
517 base::FilePath self_traversal
=
518 base::FilePath(TEST_PATH("/home/joe/../joe/file"));
519 base::FilePath relative_file
= base::FilePath(FILE_PATH_LITERAL("home/joe"));
521 ChildProcessSecurityPolicyImpl
* p
=
522 ChildProcessSecurityPolicyImpl::GetInstance();
524 // Grant permissions for a file.
526 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
527 base::File::FLAG_OPEN
));
529 GrantPermissionsForFile(p
, kRendererID
, granted_file
,
530 base::File::FLAG_OPEN
|
531 base::File::FLAG_OPEN_TRUNCATED
|
532 base::File::FLAG_READ
|
533 base::File::FLAG_WRITE
);
534 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
535 base::File::FLAG_OPEN
|
536 base::File::FLAG_OPEN_TRUNCATED
|
537 base::File::FLAG_READ
|
538 base::File::FLAG_WRITE
));
539 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
540 base::File::FLAG_OPEN
|
541 base::File::FLAG_READ
));
542 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
543 base::File::FLAG_CREATE
));
544 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
, 0));
545 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
546 base::File::FLAG_CREATE
|
547 base::File::FLAG_OPEN_TRUNCATED
|
548 base::File::FLAG_READ
|
549 base::File::FLAG_WRITE
));
550 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, sibling_file
,
551 base::File::FLAG_OPEN
|
552 base::File::FLAG_READ
));
553 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, parent_file
,
554 base::File::FLAG_OPEN
|
555 base::File::FLAG_READ
));
556 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, child_file
,
557 base::File::FLAG_OPEN
|
558 base::File::FLAG_READ
));
559 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, child_traversal1
,
560 base::File::FLAG_OPEN
|
561 base::File::FLAG_READ
));
562 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, child_traversal2
,
563 base::File::FLAG_OPEN
|
564 base::File::FLAG_READ
));
565 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, evil_traversal1
,
566 base::File::FLAG_OPEN
|
567 base::File::FLAG_READ
));
568 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, evil_traversal2
,
569 base::File::FLAG_OPEN
|
570 base::File::FLAG_READ
));
571 // CPSP doesn't allow this case for the sake of simplicity.
572 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, self_traversal
,
573 base::File::FLAG_OPEN
|
574 base::File::FLAG_READ
));
575 p
->Remove(kRendererID
);
577 // Grant permissions for the directory the file is in.
579 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
580 base::File::FLAG_OPEN
));
581 GrantPermissionsForFile(p
, kRendererID
, parent_file
,
582 base::File::FLAG_OPEN
|
583 base::File::FLAG_READ
);
584 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
585 base::File::FLAG_OPEN
));
586 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
587 base::File::FLAG_READ
|
588 base::File::FLAG_WRITE
));
589 p
->Remove(kRendererID
);
591 // Grant permissions for the directory the file is in (with trailing '/').
593 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
594 base::File::FLAG_OPEN
));
595 GrantPermissionsForFile(p
, kRendererID
, parent_slash_file
,
596 base::File::FLAG_OPEN
|
597 base::File::FLAG_READ
);
598 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
599 base::File::FLAG_OPEN
));
600 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
601 base::File::FLAG_READ
|
602 base::File::FLAG_WRITE
));
604 // Grant permissions for the file (should overwrite the permissions granted
605 // for the directory).
606 GrantPermissionsForFile(p
, kRendererID
, granted_file
,
607 base::File::FLAG_TEMPORARY
);
608 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
609 base::File::FLAG_OPEN
));
610 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
611 base::File::FLAG_TEMPORARY
));
613 // Revoke all permissions for the file (it should inherit its permissions
614 // from the directory again).
615 p
->RevokeAllPermissionsForFile(kRendererID
, granted_file
);
616 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
617 base::File::FLAG_OPEN
|
618 base::File::FLAG_READ
));
619 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
620 base::File::FLAG_TEMPORARY
));
621 p
->Remove(kRendererID
);
623 // Grant file permissions for the file to main thread renderer process,
624 // make sure its worker thread renderer process inherits those.
626 GrantPermissionsForFile(p
, kRendererID
, granted_file
,
627 base::File::FLAG_OPEN
|
628 base::File::FLAG_READ
);
629 EXPECT_TRUE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
630 base::File::FLAG_OPEN
|
631 base::File::FLAG_READ
));
632 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, granted_file
,
633 base::File::FLAG_WRITE
));
634 p
->AddWorker(kWorkerRendererID
, kRendererID
);
635 EXPECT_TRUE(p
->HasPermissionsForFile(kWorkerRendererID
, granted_file
,
636 base::File::FLAG_OPEN
|
637 base::File::FLAG_READ
));
638 EXPECT_FALSE(p
->HasPermissionsForFile(kWorkerRendererID
, granted_file
,
639 base::File::FLAG_WRITE
));
640 p
->Remove(kRendererID
);
641 EXPECT_FALSE(p
->HasPermissionsForFile(kWorkerRendererID
, granted_file
,
642 base::File::FLAG_OPEN
|
643 base::File::FLAG_READ
));
644 p
->Remove(kWorkerRendererID
);
647 GrantPermissionsForFile(p
, kRendererID
, relative_file
,
648 base::File::FLAG_OPEN
);
649 EXPECT_FALSE(p
->HasPermissionsForFile(kRendererID
, relative_file
,
650 base::File::FLAG_OPEN
));
651 p
->Remove(kRendererID
);
654 TEST_F(ChildProcessSecurityPolicyTest
, CanServiceWebUIBindings
) {
655 ChildProcessSecurityPolicyImpl
* p
=
656 ChildProcessSecurityPolicyImpl::GetInstance();
658 GURL
url("chrome://thumb/http://www.google.com/");
662 EXPECT_FALSE(p
->HasWebUIBindings(kRendererID
));
663 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, url
));
664 p
->GrantWebUIBindings(kRendererID
);
665 EXPECT_TRUE(p
->HasWebUIBindings(kRendererID
));
666 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, url
));
668 p
->Remove(kRendererID
);
671 TEST_F(ChildProcessSecurityPolicyTest
, RemoveRace
) {
672 ChildProcessSecurityPolicyImpl
* p
=
673 ChildProcessSecurityPolicyImpl::GetInstance();
675 GURL
url("file:///etc/passwd");
676 base::FilePath
file(TEST_PATH("/etc/passwd"));
680 p
->GrantRequestURL(kRendererID
, url
);
681 p
->GrantReadFile(kRendererID
, file
);
682 p
->GrantWebUIBindings(kRendererID
);
684 EXPECT_TRUE(p
->CanRequestURL(kRendererID
, url
));
685 EXPECT_TRUE(p
->CanReadFile(kRendererID
, file
));
686 EXPECT_TRUE(p
->HasWebUIBindings(kRendererID
));
688 p
->Remove(kRendererID
);
690 // Renderers are added and removed on the UI thread, but the policy can be
691 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be
692 // prepared to answer policy questions about renderers who no longer exist.
694 // In this case, we default to secure behavior.
695 EXPECT_FALSE(p
->CanRequestURL(kRendererID
, url
));
696 EXPECT_FALSE(p
->CanReadFile(kRendererID
, file
));
697 EXPECT_FALSE(p
->HasWebUIBindings(kRendererID
));
700 } // namespace content