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. 4 5 #include <set> 6 #include <string> 7 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 "testing/gtest/include/gtest/gtest.h" 14 #include "url/gurl.h" 15 #include "webkit/browser/fileapi/file_permission_policy.h" 16 #include "webkit/browser/fileapi/file_system_url.h" 17 #include "webkit/browser/fileapi/isolated_context.h" 18 #include "webkit/common/fileapi/file_system_types.h" 19 20 namespace content { 21 namespace { 22 23 const int kRendererID = 42; 24 const int kWorkerRendererID = kRendererID + 1; 25 26 #if defined(FILE_PATH_USES_DRIVE_LETTERS) 27 #define TEST_PATH(x) FILE_PATH_LITERAL("c:") FILE_PATH_LITERAL(x) 28 #else 29 #define TEST_PATH(x) FILE_PATH_LITERAL(x) 30 #endif 31 32 class ChildProcessSecurityPolicyTestBrowserClient 33 : public TestContentBrowserClient { 34 public: 35 ChildProcessSecurityPolicyTestBrowserClient() {} 36 37 virtual bool IsHandledURL(const GURL& url) OVERRIDE { 38 return schemes_.find(url.scheme()) != schemes_.end(); 39 } 40 41 void ClearSchemes() { 42 schemes_.clear(); 43 } 44 45 void AddScheme(const std::string& scheme) { 46 schemes_.insert(scheme); 47 } 48 49 private: 50 std::set<std::string> schemes_; 51 }; 52 53 } // namespace 54 55 class ChildProcessSecurityPolicyTest : public testing::Test { 56 public: 57 ChildProcessSecurityPolicyTest() : old_browser_client_(NULL) { 58 } 59 60 virtual void SetUp() { 61 old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_); 62 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); 66 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); 72 } 73 74 virtual void TearDown() { 75 test_browser_client_.ClearSchemes(); 76 SetBrowserClientForTesting(old_browser_client_); 77 } 78 79 protected: 80 void RegisterTestScheme(const std::string& scheme) { 81 test_browser_client_.AddScheme(scheme); 82 } 83 84 void GrantPermissionsForFile(ChildProcessSecurityPolicyImpl* p, 85 int child_id, 86 const base::FilePath& file, 87 int permissions) { 88 p->GrantPermissionsForFile(child_id, file, permissions); 89 } 90 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)); 97 } 98 99 void CheckHasNoFileSystemFilePermission(ChildProcessSecurityPolicyImpl* p, 100 const base::FilePath& file, 101 const fileapi::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)); 110 } 111 112 private: 113 ChildProcessSecurityPolicyTestBrowserClient test_browser_client_; 114 ContentBrowserClient* old_browser_client_; 115 }; 116 117 118 TEST_F(ChildProcessSecurityPolicyTest, IsWebSafeSchemeTest) { 119 ChildProcessSecurityPolicyImpl* p = 120 ChildProcessSecurityPolicyImpl::GetInstance(); 121 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)); 129 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")); 133 134 EXPECT_FALSE(p->IsWebSafeScheme(kChromeUIScheme)); 135 } 136 137 TEST_F(ChildProcessSecurityPolicyTest, IsPseudoSchemeTest) { 138 ChildProcessSecurityPolicyImpl* p = 139 ChildProcessSecurityPolicyImpl::GetInstance(); 140 141 EXPECT_TRUE(p->IsPseudoScheme(url::kAboutScheme)); 142 EXPECT_TRUE(p->IsPseudoScheme(url::kJavaScriptScheme)); 143 EXPECT_TRUE(p->IsPseudoScheme(kViewSourceScheme)); 144 145 EXPECT_FALSE(p->IsPseudoScheme("registered-pseudo-scheme")); 146 p->RegisterPseudoScheme("registered-pseudo-scheme"); 147 EXPECT_TRUE(p->IsPseudoScheme("registered-pseudo-scheme")); 148 149 EXPECT_FALSE(p->IsPseudoScheme(kChromeUIScheme)); 150 } 151 152 TEST_F(ChildProcessSecurityPolicyTest, StandardSchemesTest) { 153 ChildProcessSecurityPolicyImpl* p = 154 ChildProcessSecurityPolicyImpl::GetInstance(); 155 156 p->Add(kRendererID); 157 158 // Safe 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(kRendererID, 164 GURL("view-source:http://www.google.com/"))); 165 EXPECT_TRUE(p->CanRequestURL( 166 kRendererID, GURL("filesystem:http://localhost/temporary/a.gif"))); 167 168 // Dangerous 169 EXPECT_FALSE(p->CanRequestURL(kRendererID, 170 GURL("file:///etc/passwd"))); 171 EXPECT_FALSE(p->CanRequestURL(kRendererID, 172 GURL("chrome://foo/bar"))); 173 174 p->Remove(kRendererID); 175 } 176 177 TEST_F(ChildProcessSecurityPolicyTest, AboutTest) { 178 ChildProcessSecurityPolicyImpl* p = 179 ChildProcessSecurityPolicyImpl::GetInstance(); 180 181 p->Add(kRendererID); 182 183 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank"))); 184 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK"))); 185 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK"))); 186 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank"))); 187 188 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory"))); 189 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); 190 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache"))); 191 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang"))); 192 193 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory"))); 194 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh"))); 195 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe"))); 196 197 // Requests for about: pages should be denied. 198 p->GrantRequestURL(kRendererID, GURL("about:crash")); 199 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); 200 201 // These requests for chrome:// pages should be granted. 202 GURL chrome_url("chrome://foo"); 203 p->GrantRequestURL(kRendererID, chrome_url); 204 EXPECT_TRUE(p->CanRequestURL(kRendererID, chrome_url)); 205 206 p->Remove(kRendererID); 207 } 208 209 TEST_F(ChildProcessSecurityPolicyTest, JavaScriptTest) { 210 ChildProcessSecurityPolicyImpl* p = 211 ChildProcessSecurityPolicyImpl::GetInstance(); 212 213 p->Add(kRendererID); 214 215 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); 216 p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')")); 217 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); 218 219 p->Remove(kRendererID); 220 } 221 222 TEST_F(ChildProcessSecurityPolicyTest, RegisterWebSafeSchemeTest) { 223 ChildProcessSecurityPolicyImpl* p = 224 ChildProcessSecurityPolicyImpl::GetInstance(); 225 226 p->Add(kRendererID); 227 228 // Currently, "asdf" is destined for ShellExecute, so it is allowed. 229 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); 230 231 // Once we register "asdf", we default to deny. 232 RegisterTestScheme("asdf"); 233 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); 234 235 // We can allow new schemes by adding them to the whitelist. 236 p->RegisterWebSafeScheme("asdf"); 237 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); 238 239 // Cleanup. 240 p->Remove(kRendererID); 241 } 242 243 TEST_F(ChildProcessSecurityPolicyTest, CanServiceCommandsTest) { 244 ChildProcessSecurityPolicyImpl* p = 245 ChildProcessSecurityPolicyImpl::GetInstance(); 246 247 p->Add(kRendererID); 248 249 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 250 p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd")); 251 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 252 253 // We should forget our state if we repeat a renderer id. 254 p->Remove(kRendererID); 255 p->Add(kRendererID); 256 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 257 p->Remove(kRendererID); 258 } 259 260 TEST_F(ChildProcessSecurityPolicyTest, ViewSource) { 261 ChildProcessSecurityPolicyImpl* p = 262 ChildProcessSecurityPolicyImpl::GetInstance(); 263 264 p->Add(kRendererID); 265 266 // View source is determined by the embedded scheme. 267 EXPECT_TRUE(p->CanRequestURL(kRendererID, 268 GURL("view-source:http://www.google.com/"))); 269 EXPECT_FALSE(p->CanRequestURL(kRendererID, 270 GURL("view-source:file:///etc/passwd"))); 271 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 272 EXPECT_FALSE(p->CanRequestURL( 273 kRendererID, GURL("view-source:view-source:http://www.google.com/"))); 274 275 p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd")); 276 // View source needs to be able to request the embedded scheme. 277 EXPECT_TRUE(p->CanRequestURL(kRendererID, 278 GURL("view-source:file:///etc/passwd"))); 279 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 280 281 p->Remove(kRendererID); 282 } 283 284 TEST_F(ChildProcessSecurityPolicyTest, SpecificFile) { 285 ChildProcessSecurityPolicyImpl* p = 286 ChildProcessSecurityPolicyImpl::GetInstance(); 287 288 p->Add(kRendererID); 289 290 GURL icon_url("file:///tmp/foo.png"); 291 GURL sensitive_url("file:///etc/passwd"); 292 EXPECT_FALSE(p->CanRequestURL(kRendererID, icon_url)); 293 EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url)); 294 295 p->GrantRequestSpecificFileURL(kRendererID, icon_url); 296 EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url)); 297 EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url)); 298 299 p->GrantRequestURL(kRendererID, icon_url); 300 EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url)); 301 EXPECT_TRUE(p->CanRequestURL(kRendererID, sensitive_url)); 302 303 p->Remove(kRendererID); 304 } 305 306 TEST_F(ChildProcessSecurityPolicyTest, FileSystemGrantsTest) { 307 ChildProcessSecurityPolicyImpl* p = 308 ChildProcessSecurityPolicyImpl::GetInstance(); 309 310 p->Add(kRendererID); 311 std::string read_id = fileapi::IsolatedContext::GetInstance()-> 312 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 313 "read_filesystem", 314 base::FilePath()); 315 std::string read_write_id = fileapi::IsolatedContext::GetInstance()-> 316 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 317 "read_write_filesystem", 318 base::FilePath()); 319 std::string copy_into_id = fileapi::IsolatedContext::GetInstance()-> 320 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 321 "copy_into_filesystem", 322 base::FilePath()); 323 std::string delete_from_id = fileapi::IsolatedContext::GetInstance()-> 324 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 325 "delete_from_filesystem", 326 base::FilePath()); 327 328 // Test initially having no permissions. 329 CheckHasNoFileSystemPermission(p, read_id); 330 CheckHasNoFileSystemPermission(p, read_write_id); 331 CheckHasNoFileSystemPermission(p, copy_into_id); 332 CheckHasNoFileSystemPermission(p, delete_from_id); 333 334 // Testing varying combinations of grants and checks. 335 p->GrantReadFileSystem(kRendererID, read_id); 336 EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_id)); 337 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id)); 338 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id)); 339 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, read_id)); 340 341 p->GrantReadFileSystem(kRendererID, read_write_id); 342 p->GrantWriteFileSystem(kRendererID, read_write_id); 343 EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_write_id)); 344 EXPECT_TRUE(p->CanReadWriteFileSystem(kRendererID, read_write_id)); 345 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id)); 346 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, read_write_id)); 347 348 p->GrantCopyIntoFileSystem(kRendererID, copy_into_id); 349 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id)); 350 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id)); 351 EXPECT_TRUE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id)); 352 EXPECT_FALSE(p->CanDeleteFromFileSystem(kRendererID, copy_into_id)); 353 354 p->GrantDeleteFromFileSystem(kRendererID, delete_from_id); 355 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, delete_from_id)); 356 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, delete_from_id)); 357 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, delete_from_id)); 358 EXPECT_TRUE(p->CanDeleteFromFileSystem(kRendererID, delete_from_id)); 359 360 // Test revoke permissions on renderer ID removal. 361 p->Remove(kRendererID); 362 CheckHasNoFileSystemPermission(p, read_id); 363 CheckHasNoFileSystemPermission(p, read_write_id); 364 CheckHasNoFileSystemPermission(p, copy_into_id); 365 CheckHasNoFileSystemPermission(p, delete_from_id); 366 367 // Test having no permissions upon re-adding same renderer ID. 368 p->Add(kRendererID); 369 CheckHasNoFileSystemPermission(p, read_id); 370 CheckHasNoFileSystemPermission(p, read_write_id); 371 CheckHasNoFileSystemPermission(p, copy_into_id); 372 CheckHasNoFileSystemPermission(p, delete_from_id); 373 374 // Cleanup. 375 p->Remove(kRendererID); 376 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(read_id); 377 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(read_write_id); 378 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(copy_into_id); 379 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(delete_from_id); 380 } 381 382 TEST_F(ChildProcessSecurityPolicyTest, FilePermissionGrantingAndRevoking) { 383 ChildProcessSecurityPolicyImpl* p = 384 ChildProcessSecurityPolicyImpl::GetInstance(); 385 386 p->RegisterFileSystemPermissionPolicy( 387 fileapi::kFileSystemTypeTest, 388 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION); 389 390 p->Add(kRendererID); 391 base::FilePath file(TEST_PATH("/dir/testfile")); 392 file = file.NormalizePathSeparators(); 393 fileapi::FileSystemURL url = fileapi::FileSystemURL::CreateForTest( 394 GURL("http://foo/"), fileapi::kFileSystemTypeTest, file); 395 396 // Test initially having no permissions. 397 CheckHasNoFileSystemFilePermission(p, file, url); 398 399 // Testing every combination of permissions granting and revoking. 400 p->GrantReadFile(kRendererID, file); 401 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 402 EXPECT_FALSE(p->CanCreateReadWriteFile(kRendererID, file)); 403 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url)); 404 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 405 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 406 EXPECT_FALSE(p->CanCreateReadWriteFileSystemFile(kRendererID, url)); 407 EXPECT_FALSE(p->CanCopyIntoFileSystemFile(kRendererID, url)); 408 EXPECT_FALSE(p->CanDeleteFileSystemFile(kRendererID, url)); 409 p->RevokeAllPermissionsForFile(kRendererID, file); 410 CheckHasNoFileSystemFilePermission(p, file, url); 411 412 p->GrantCreateReadWriteFile(kRendererID, file); 413 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 414 EXPECT_TRUE(p->CanCreateReadWriteFile(kRendererID, file)); 415 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url)); 416 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url)); 417 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url)); 418 EXPECT_TRUE(p->CanCreateReadWriteFileSystemFile(kRendererID, url)); 419 EXPECT_TRUE(p->CanCopyIntoFileSystemFile(kRendererID, url)); 420 EXPECT_TRUE(p->CanDeleteFileSystemFile(kRendererID, url)); 421 p->RevokeAllPermissionsForFile(kRendererID, file); 422 CheckHasNoFileSystemFilePermission(p, file, url); 423 424 // Test revoke permissions on renderer ID removal. 425 p->GrantCreateReadWriteFile(kRendererID, file); 426 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 427 EXPECT_TRUE(p->CanCreateReadWriteFile(kRendererID, file)); 428 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url)); 429 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url)); 430 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url)); 431 EXPECT_TRUE(p->CanCreateReadWriteFileSystemFile(kRendererID, url)); 432 EXPECT_TRUE(p->CanCopyIntoFileSystemFile(kRendererID, url)); 433 EXPECT_TRUE(p->CanDeleteFileSystemFile(kRendererID, url)); 434 p->Remove(kRendererID); 435 CheckHasNoFileSystemFilePermission(p, file, url); 436 437 // Test having no permissions upon re-adding same renderer ID. 438 p->Add(kRendererID); 439 CheckHasNoFileSystemFilePermission(p, file, url); 440 441 // Cleanup. 442 p->Remove(kRendererID); 443 } 444 445 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) { 446 base::FilePath granted_file = base::FilePath(TEST_PATH("/home/joe")); 447 base::FilePath sibling_file = base::FilePath(TEST_PATH("/home/bob")); 448 base::FilePath child_file = base::FilePath(TEST_PATH("/home/joe/file")); 449 base::FilePath parent_file = base::FilePath(TEST_PATH("/home")); 450 base::FilePath parent_slash_file = base::FilePath(TEST_PATH("/home/")); 451 base::FilePath child_traversal1 = 452 base::FilePath(TEST_PATH("/home/joe/././file")); 453 base::FilePath child_traversal2 = base::FilePath( 454 TEST_PATH("/home/joe/file/../otherfile")); 455 base::FilePath evil_traversal1 = 456 base::FilePath(TEST_PATH("/home/joe/../../etc/passwd")); 457 base::FilePath evil_traversal2 = base::FilePath( 458 TEST_PATH("/home/joe/./.././../etc/passwd")); 459 base::FilePath self_traversal = 460 base::FilePath(TEST_PATH("/home/joe/../joe/file")); 461 base::FilePath relative_file = base::FilePath(FILE_PATH_LITERAL("home/joe")); 462 463 ChildProcessSecurityPolicyImpl* p = 464 ChildProcessSecurityPolicyImpl::GetInstance(); 465 466 // Grant permissions for a file. 467 p->Add(kRendererID); 468 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 469 base::File::FLAG_OPEN)); 470 471 GrantPermissionsForFile(p, kRendererID, granted_file, 472 base::File::FLAG_OPEN | 473 base::File::FLAG_OPEN_TRUNCATED | 474 base::File::FLAG_READ | 475 base::File::FLAG_WRITE); 476 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 477 base::File::FLAG_OPEN | 478 base::File::FLAG_OPEN_TRUNCATED | 479 base::File::FLAG_READ | 480 base::File::FLAG_WRITE)); 481 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 482 base::File::FLAG_OPEN | 483 base::File::FLAG_READ)); 484 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 485 base::File::FLAG_CREATE)); 486 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 0)); 487 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 488 base::File::FLAG_CREATE | 489 base::File::FLAG_OPEN_TRUNCATED | 490 base::File::FLAG_READ | 491 base::File::FLAG_WRITE)); 492 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file, 493 base::File::FLAG_OPEN | 494 base::File::FLAG_READ)); 495 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file, 496 base::File::FLAG_OPEN | 497 base::File::FLAG_READ)); 498 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_file, 499 base::File::FLAG_OPEN | 500 base::File::FLAG_READ)); 501 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal1, 502 base::File::FLAG_OPEN | 503 base::File::FLAG_READ)); 504 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal2, 505 base::File::FLAG_OPEN | 506 base::File::FLAG_READ)); 507 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal1, 508 base::File::FLAG_OPEN | 509 base::File::FLAG_READ)); 510 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal2, 511 base::File::FLAG_OPEN | 512 base::File::FLAG_READ)); 513 // CPSP doesn't allow this case for the sake of simplicity. 514 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, self_traversal, 515 base::File::FLAG_OPEN | 516 base::File::FLAG_READ)); 517 p->Remove(kRendererID); 518 519 // Grant permissions for the directory the file is in. 520 p->Add(kRendererID); 521 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 522 base::File::FLAG_OPEN)); 523 GrantPermissionsForFile(p, kRendererID, parent_file, 524 base::File::FLAG_OPEN | 525 base::File::FLAG_READ); 526 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 527 base::File::FLAG_OPEN)); 528 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 529 base::File::FLAG_READ | 530 base::File::FLAG_WRITE)); 531 p->Remove(kRendererID); 532 533 // Grant permissions for the directory the file is in (with trailing '/'). 534 p->Add(kRendererID); 535 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 536 base::File::FLAG_OPEN)); 537 GrantPermissionsForFile(p, kRendererID, parent_slash_file, 538 base::File::FLAG_OPEN | 539 base::File::FLAG_READ); 540 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 541 base::File::FLAG_OPEN)); 542 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 543 base::File::FLAG_READ | 544 base::File::FLAG_WRITE)); 545 546 // Grant permissions for the file (should overwrite the permissions granted 547 // for the directory). 548 GrantPermissionsForFile(p, kRendererID, granted_file, 549 base::File::FLAG_TEMPORARY); 550 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 551 base::File::FLAG_OPEN)); 552 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 553 base::File::FLAG_TEMPORARY)); 554 555 // Revoke all permissions for the file (it should inherit its permissions 556 // from the directory again). 557 p->RevokeAllPermissionsForFile(kRendererID, granted_file); 558 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 559 base::File::FLAG_OPEN | 560 base::File::FLAG_READ)); 561 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 562 base::File::FLAG_TEMPORARY)); 563 p->Remove(kRendererID); 564 565 // Grant file permissions for the file to main thread renderer process, 566 // make sure its worker thread renderer process inherits those. 567 p->Add(kRendererID); 568 GrantPermissionsForFile(p, kRendererID, granted_file, 569 base::File::FLAG_OPEN | 570 base::File::FLAG_READ); 571 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 572 base::File::FLAG_OPEN | 573 base::File::FLAG_READ)); 574 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 575 base::File::FLAG_WRITE)); 576 p->AddWorker(kWorkerRendererID, kRendererID); 577 EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, 578 base::File::FLAG_OPEN | 579 base::File::FLAG_READ)); 580 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, 581 base::File::FLAG_WRITE)); 582 p->Remove(kRendererID); 583 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, 584 base::File::FLAG_OPEN | 585 base::File::FLAG_READ)); 586 p->Remove(kWorkerRendererID); 587 588 p->Add(kRendererID); 589 GrantPermissionsForFile(p, kRendererID, relative_file, 590 base::File::FLAG_OPEN); 591 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, relative_file, 592 base::File::FLAG_OPEN)); 593 p->Remove(kRendererID); 594 } 595 596 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) { 597 ChildProcessSecurityPolicyImpl* p = 598 ChildProcessSecurityPolicyImpl::GetInstance(); 599 600 GURL url("chrome://thumb/http://www.google.com/"); 601 602 p->Add(kRendererID); 603 604 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); 605 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); 606 p->GrantWebUIBindings(kRendererID); 607 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); 608 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); 609 610 p->Remove(kRendererID); 611 } 612 613 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) { 614 ChildProcessSecurityPolicyImpl* p = 615 ChildProcessSecurityPolicyImpl::GetInstance(); 616 617 GURL url("file:///etc/passwd"); 618 base::FilePath file(TEST_PATH("/etc/passwd")); 619 620 p->Add(kRendererID); 621 622 p->GrantRequestURL(kRendererID, url); 623 p->GrantReadFile(kRendererID, file); 624 p->GrantWebUIBindings(kRendererID); 625 626 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); 627 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 628 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); 629 630 p->Remove(kRendererID); 631 632 // Renderers are added and removed on the UI thread, but the policy can be 633 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be 634 // prepared to answer policy questions about renderers who no longer exist. 635 636 // In this case, we default to secure behavior. 637 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); 638 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 639 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); 640 } 641 642 } // namespace content 643