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