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 private: 93 ChildProcessSecurityPolicyTestBrowserClient test_browser_client_; 94 ContentBrowserClient* old_browser_client_; 95 }; 96 97 98 TEST_F(ChildProcessSecurityPolicyTest, IsWebSafeSchemeTest) { 99 ChildProcessSecurityPolicyImpl* p = 100 ChildProcessSecurityPolicyImpl::GetInstance(); 101 102 EXPECT_TRUE(p->IsWebSafeScheme(chrome::kHttpScheme)); 103 EXPECT_TRUE(p->IsWebSafeScheme(chrome::kHttpsScheme)); 104 EXPECT_TRUE(p->IsWebSafeScheme(chrome::kFtpScheme)); 105 EXPECT_TRUE(p->IsWebSafeScheme(chrome::kDataScheme)); 106 EXPECT_TRUE(p->IsWebSafeScheme("feed")); 107 EXPECT_TRUE(p->IsWebSafeScheme(chrome::kBlobScheme)); 108 EXPECT_TRUE(p->IsWebSafeScheme(chrome::kFileSystemScheme)); 109 110 EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme")); 111 p->RegisterWebSafeScheme("registered-web-safe-scheme"); 112 EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme")); 113 114 EXPECT_FALSE(p->IsWebSafeScheme(chrome::kChromeUIScheme)); 115 } 116 117 TEST_F(ChildProcessSecurityPolicyTest, IsPseudoSchemeTest) { 118 ChildProcessSecurityPolicyImpl* p = 119 ChildProcessSecurityPolicyImpl::GetInstance(); 120 121 EXPECT_TRUE(p->IsPseudoScheme(chrome::kAboutScheme)); 122 EXPECT_TRUE(p->IsPseudoScheme(chrome::kJavaScriptScheme)); 123 EXPECT_TRUE(p->IsPseudoScheme(kViewSourceScheme)); 124 125 EXPECT_FALSE(p->IsPseudoScheme("registered-pseudo-scheme")); 126 p->RegisterPseudoScheme("registered-pseudo-scheme"); 127 EXPECT_TRUE(p->IsPseudoScheme("registered-pseudo-scheme")); 128 129 EXPECT_FALSE(p->IsPseudoScheme(chrome::kChromeUIScheme)); 130 } 131 132 TEST_F(ChildProcessSecurityPolicyTest, StandardSchemesTest) { 133 ChildProcessSecurityPolicyImpl* p = 134 ChildProcessSecurityPolicyImpl::GetInstance(); 135 136 p->Add(kRendererID); 137 138 // Safe 139 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/"))); 140 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/"))); 141 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("ftp://ftp.gnu.org/"))); 142 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,<b>Hi</b>"))); 143 EXPECT_TRUE(p->CanRequestURL(kRendererID, 144 GURL("view-source:http://www.google.com/"))); 145 EXPECT_TRUE(p->CanRequestURL( 146 kRendererID, GURL("filesystem:http://localhost/temporary/a.gif"))); 147 148 // Dangerous 149 EXPECT_FALSE(p->CanRequestURL(kRendererID, 150 GURL("file:///etc/passwd"))); 151 EXPECT_FALSE(p->CanRequestURL(kRendererID, 152 GURL("chrome://foo/bar"))); 153 154 p->Remove(kRendererID); 155 } 156 157 TEST_F(ChildProcessSecurityPolicyTest, AboutTest) { 158 ChildProcessSecurityPolicyImpl* p = 159 ChildProcessSecurityPolicyImpl::GetInstance(); 160 161 p->Add(kRendererID); 162 163 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank"))); 164 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK"))); 165 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK"))); 166 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank"))); 167 168 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:memory"))); 169 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); 170 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:cache"))); 171 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:hang"))); 172 173 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory"))); 174 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh"))); 175 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe"))); 176 177 // Requests for about: pages should be denied. 178 p->GrantRequestURL(kRendererID, GURL("about:crash")); 179 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash"))); 180 181 // These requests for chrome:// pages should be granted. 182 GURL chrome_url("chrome://foo"); 183 p->GrantRequestURL(kRendererID, chrome_url); 184 EXPECT_TRUE(p->CanRequestURL(kRendererID, chrome_url)); 185 186 p->Remove(kRendererID); 187 } 188 189 TEST_F(ChildProcessSecurityPolicyTest, JavaScriptTest) { 190 ChildProcessSecurityPolicyImpl* p = 191 ChildProcessSecurityPolicyImpl::GetInstance(); 192 193 p->Add(kRendererID); 194 195 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); 196 p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')")); 197 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')"))); 198 199 p->Remove(kRendererID); 200 } 201 202 TEST_F(ChildProcessSecurityPolicyTest, RegisterWebSafeSchemeTest) { 203 ChildProcessSecurityPolicyImpl* p = 204 ChildProcessSecurityPolicyImpl::GetInstance(); 205 206 p->Add(kRendererID); 207 208 // Currently, "asdf" is destined for ShellExecute, so it is allowed. 209 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); 210 211 // Once we register "asdf", we default to deny. 212 RegisterTestScheme("asdf"); 213 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); 214 215 // We can allow new schemes by adding them to the whitelist. 216 p->RegisterWebSafeScheme("asdf"); 217 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers"))); 218 219 // Cleanup. 220 p->Remove(kRendererID); 221 } 222 223 TEST_F(ChildProcessSecurityPolicyTest, CanServiceCommandsTest) { 224 ChildProcessSecurityPolicyImpl* p = 225 ChildProcessSecurityPolicyImpl::GetInstance(); 226 227 p->Add(kRendererID); 228 229 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 230 p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd")); 231 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 232 233 // We should forget our state if we repeat a renderer id. 234 p->Remove(kRendererID); 235 p->Add(kRendererID); 236 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 237 p->Remove(kRendererID); 238 } 239 240 TEST_F(ChildProcessSecurityPolicyTest, ViewSource) { 241 ChildProcessSecurityPolicyImpl* p = 242 ChildProcessSecurityPolicyImpl::GetInstance(); 243 244 p->Add(kRendererID); 245 246 // View source is determined by the embedded scheme. 247 EXPECT_TRUE(p->CanRequestURL(kRendererID, 248 GURL("view-source:http://www.google.com/"))); 249 EXPECT_FALSE(p->CanRequestURL(kRendererID, 250 GURL("view-source:file:///etc/passwd"))); 251 EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 252 EXPECT_FALSE(p->CanRequestURL( 253 kRendererID, GURL("view-source:view-source:http://www.google.com/"))); 254 255 p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd")); 256 // View source needs to be able to request the embedded scheme. 257 EXPECT_TRUE(p->CanRequestURL(kRendererID, 258 GURL("view-source:file:///etc/passwd"))); 259 EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd"))); 260 261 p->Remove(kRendererID); 262 } 263 264 TEST_F(ChildProcessSecurityPolicyTest, SpecificFile) { 265 ChildProcessSecurityPolicyImpl* p = 266 ChildProcessSecurityPolicyImpl::GetInstance(); 267 268 p->Add(kRendererID); 269 270 GURL icon_url("file:///tmp/foo.png"); 271 GURL sensitive_url("file:///etc/passwd"); 272 EXPECT_FALSE(p->CanRequestURL(kRendererID, icon_url)); 273 EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url)); 274 275 p->GrantRequestSpecificFileURL(kRendererID, icon_url); 276 EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url)); 277 EXPECT_FALSE(p->CanRequestURL(kRendererID, sensitive_url)); 278 279 p->GrantRequestURL(kRendererID, icon_url); 280 EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url)); 281 EXPECT_TRUE(p->CanRequestURL(kRendererID, sensitive_url)); 282 283 p->Remove(kRendererID); 284 } 285 286 TEST_F(ChildProcessSecurityPolicyTest, FileSystemGrantsTest) { 287 ChildProcessSecurityPolicyImpl* p = 288 ChildProcessSecurityPolicyImpl::GetInstance(); 289 290 p->Add(kRendererID); 291 std::string read_id = fileapi::IsolatedContext::GetInstance()-> 292 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 293 "read_filesystem", 294 base::FilePath()); 295 std::string read_write_id = fileapi::IsolatedContext::GetInstance()-> 296 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 297 "read_write_filesystem", 298 base::FilePath()); 299 std::string copy_into_id = fileapi::IsolatedContext::GetInstance()-> 300 RegisterFileSystemForVirtualPath(fileapi::kFileSystemTypeTest, 301 "copy_into_filesystem", 302 base::FilePath()); 303 304 // Test initially having no permissions. 305 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_id)); 306 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id)); 307 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id)); 308 309 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_write_id)); 310 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_write_id)); 311 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id)); 312 313 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id)); 314 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id)); 315 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id)); 316 317 // Testing varying combinations of grants and checks. 318 p->GrantReadFileSystem(kRendererID, read_id); 319 EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_id)); 320 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id)); 321 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id)); 322 323 p->GrantReadFileSystem(kRendererID, read_write_id); 324 p->GrantWriteFileSystem(kRendererID, read_write_id); 325 EXPECT_TRUE(p->CanReadFileSystem(kRendererID, read_write_id)); 326 EXPECT_TRUE(p->CanReadWriteFileSystem(kRendererID, read_write_id)); 327 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id)); 328 329 p->GrantCopyIntoFileSystem(kRendererID, copy_into_id); 330 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id)); 331 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id)); 332 EXPECT_TRUE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id)); 333 334 // Test revoke permissions on renderer ID removal. 335 p->Remove(kRendererID); 336 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_id)); 337 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id)); 338 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id)); 339 340 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_write_id)); 341 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_write_id)); 342 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id)); 343 344 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id)); 345 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id)); 346 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id)); 347 348 // Test having no permissions upon re-adding same renderer ID. 349 p->Add(kRendererID); 350 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_id)); 351 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_id)); 352 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_id)); 353 354 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, read_write_id)); 355 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, read_write_id)); 356 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, read_write_id)); 357 358 EXPECT_FALSE(p->CanReadFileSystem(kRendererID, copy_into_id)); 359 EXPECT_FALSE(p->CanReadWriteFileSystem(kRendererID, copy_into_id)); 360 EXPECT_FALSE(p->CanCopyIntoFileSystem(kRendererID, copy_into_id)); 361 362 // Cleanup. 363 p->Remove(kRendererID); 364 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(read_id); 365 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(read_write_id); 366 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(copy_into_id); 367 } 368 369 TEST_F(ChildProcessSecurityPolicyTest, FilePermissionGrantingAndRevoking) { 370 ChildProcessSecurityPolicyImpl* p = 371 ChildProcessSecurityPolicyImpl::GetInstance(); 372 373 p->RegisterFileSystemPermissionPolicy( 374 fileapi::kFileSystemTypeTest, 375 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION); 376 377 p->Add(kRendererID); 378 base::FilePath file(TEST_PATH("/dir/testfile")); 379 file = file.NormalizePathSeparators(); 380 fileapi::FileSystemURL url = fileapi::FileSystemURL::CreateForTest( 381 GURL("http://foo/"), fileapi::kFileSystemTypeTest, file); 382 383 // Test initially having no permissions. 384 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 385 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 386 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 387 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 388 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 389 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 390 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 391 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 392 393 // Testing every combination of permissions granting and revoking. 394 p->GrantReadFile(kRendererID, file); 395 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 396 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 397 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 398 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 399 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url)); 400 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 401 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 402 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 403 p->RevokeAllPermissionsForFile(kRendererID, file); 404 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 405 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 406 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 407 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 408 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 409 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 410 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 411 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 412 413 p->GrantCreateReadWriteFile(kRendererID, file); 414 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 415 EXPECT_TRUE(p->CanWriteFile(kRendererID, file)); 416 EXPECT_TRUE(p->CanCreateFile(kRendererID, file)); 417 EXPECT_TRUE(p->CanCreateWriteFile(kRendererID, file)); 418 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url)); 419 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url)); 420 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url)); 421 EXPECT_TRUE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 422 p->RevokeAllPermissionsForFile(kRendererID, file); 423 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 424 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 425 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 426 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 427 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 428 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 429 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 430 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 431 432 p->GrantCreateWriteFile(kRendererID, file); 433 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 434 EXPECT_TRUE(p->CanWriteFile(kRendererID, file)); 435 EXPECT_TRUE(p->CanCreateFile(kRendererID, file)); 436 EXPECT_TRUE(p->CanCreateWriteFile(kRendererID, file)); 437 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 438 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url)); 439 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url)); 440 EXPECT_TRUE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 441 p->RevokeAllPermissionsForFile(kRendererID, file); 442 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 443 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 444 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 445 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 446 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 447 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 448 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 449 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 450 451 // Test revoke permissions on renderer ID removal. 452 p->GrantCreateReadWriteFile(kRendererID, file); 453 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 454 EXPECT_TRUE(p->CanWriteFile(kRendererID, file)); 455 EXPECT_TRUE(p->CanCreateFile(kRendererID, file)); 456 EXPECT_TRUE(p->CanCreateWriteFile(kRendererID, file)); 457 EXPECT_TRUE(p->CanReadFileSystemFile(kRendererID, url)); 458 EXPECT_TRUE(p->CanWriteFileSystemFile(kRendererID, url)); 459 EXPECT_TRUE(p->CanCreateFileSystemFile(kRendererID, url)); 460 EXPECT_TRUE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 461 p->Remove(kRendererID); 462 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 463 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 464 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 465 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 466 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 467 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 468 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 469 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 470 471 // Test having no permissions upon re-adding same renderer ID. 472 p->Add(kRendererID); 473 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 474 EXPECT_FALSE(p->CanWriteFile(kRendererID, file)); 475 EXPECT_FALSE(p->CanCreateFile(kRendererID, file)); 476 EXPECT_FALSE(p->CanCreateWriteFile(kRendererID, file)); 477 EXPECT_FALSE(p->CanReadFileSystemFile(kRendererID, url)); 478 EXPECT_FALSE(p->CanWriteFileSystemFile(kRendererID, url)); 479 EXPECT_FALSE(p->CanCreateFileSystemFile(kRendererID, url)); 480 EXPECT_FALSE(p->CanCreateWriteFileSystemFile(kRendererID, url)); 481 482 // Cleanup. 483 p->Remove(kRendererID); 484 } 485 486 TEST_F(ChildProcessSecurityPolicyTest, CanReadDirectories) { 487 ChildProcessSecurityPolicyImpl* p = 488 ChildProcessSecurityPolicyImpl::GetInstance(); 489 490 p->Add(kRendererID); 491 492 EXPECT_FALSE(p->CanReadDirectory(kRendererID, 493 base::FilePath(TEST_PATH("/etc/")))); 494 p->GrantReadDirectory(kRendererID, 495 base::FilePath(TEST_PATH("/etc/"))); 496 EXPECT_TRUE(p->CanReadDirectory(kRendererID, 497 base::FilePath(TEST_PATH("/etc/")))); 498 EXPECT_TRUE(p->CanReadFile(kRendererID, 499 base::FilePath(TEST_PATH("/etc/passwd")))); 500 501 p->Remove(kRendererID); 502 p->Add(kRendererID); 503 504 EXPECT_FALSE(p->CanReadDirectory(kRendererID, 505 base::FilePath(TEST_PATH("/etc/")))); 506 EXPECT_FALSE(p->CanReadFile(kRendererID, 507 base::FilePath(TEST_PATH("/etc/passwd")))); 508 509 // Just granting read permission as a file doesn't imply reading as a 510 // directory. 511 p->GrantReadFile(kRendererID, base::FilePath(TEST_PATH("/etc/"))); 512 EXPECT_TRUE(p->CanReadFile(kRendererID, 513 base::FilePath(TEST_PATH("/etc/passwd")))); 514 EXPECT_FALSE(p->CanReadDirectory(kRendererID, 515 base::FilePath(TEST_PATH("/etc/")))); 516 517 p->Remove(kRendererID); 518 } 519 520 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) { 521 base::FilePath granted_file = base::FilePath(TEST_PATH("/home/joe")); 522 base::FilePath sibling_file = base::FilePath(TEST_PATH("/home/bob")); 523 base::FilePath child_file = base::FilePath(TEST_PATH("/home/joe/file")); 524 base::FilePath parent_file = base::FilePath(TEST_PATH("/home")); 525 base::FilePath parent_slash_file = base::FilePath(TEST_PATH("/home/")); 526 base::FilePath child_traversal1 = 527 base::FilePath(TEST_PATH("/home/joe/././file")); 528 base::FilePath child_traversal2 = base::FilePath( 529 TEST_PATH("/home/joe/file/../otherfile")); 530 base::FilePath evil_traversal1 = 531 base::FilePath(TEST_PATH("/home/joe/../../etc/passwd")); 532 base::FilePath evil_traversal2 = base::FilePath( 533 TEST_PATH("/home/joe/./.././../etc/passwd")); 534 base::FilePath self_traversal = 535 base::FilePath(TEST_PATH("/home/joe/../joe/file")); 536 base::FilePath relative_file = base::FilePath(FILE_PATH_LITERAL("home/joe")); 537 538 ChildProcessSecurityPolicyImpl* p = 539 ChildProcessSecurityPolicyImpl::GetInstance(); 540 541 // Grant permissions for a file. 542 p->Add(kRendererID); 543 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 544 base::PLATFORM_FILE_OPEN)); 545 546 GrantPermissionsForFile(p, kRendererID, granted_file, 547 base::PLATFORM_FILE_OPEN | 548 base::PLATFORM_FILE_OPEN_TRUNCATED | 549 base::PLATFORM_FILE_READ | 550 base::PLATFORM_FILE_WRITE); 551 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 552 base::PLATFORM_FILE_OPEN | 553 base::PLATFORM_FILE_OPEN_TRUNCATED | 554 base::PLATFORM_FILE_READ | 555 base::PLATFORM_FILE_WRITE)); 556 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 557 base::PLATFORM_FILE_OPEN | 558 base::PLATFORM_FILE_READ)); 559 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 560 base::PLATFORM_FILE_CREATE)); 561 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 0)); 562 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 563 base::PLATFORM_FILE_CREATE | 564 base::PLATFORM_FILE_OPEN_TRUNCATED | 565 base::PLATFORM_FILE_READ | 566 base::PLATFORM_FILE_WRITE)); 567 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file, 568 base::PLATFORM_FILE_OPEN | 569 base::PLATFORM_FILE_READ)); 570 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file, 571 base::PLATFORM_FILE_OPEN | 572 base::PLATFORM_FILE_READ)); 573 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_file, 574 base::PLATFORM_FILE_OPEN | 575 base::PLATFORM_FILE_READ)); 576 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal1, 577 base::PLATFORM_FILE_OPEN | 578 base::PLATFORM_FILE_READ)); 579 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, child_traversal2, 580 base::PLATFORM_FILE_OPEN | 581 base::PLATFORM_FILE_READ)); 582 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal1, 583 base::PLATFORM_FILE_OPEN | 584 base::PLATFORM_FILE_READ)); 585 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, evil_traversal2, 586 base::PLATFORM_FILE_OPEN | 587 base::PLATFORM_FILE_READ)); 588 // CPSP doesn't allow this case for the sake of simplicity. 589 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, self_traversal, 590 base::PLATFORM_FILE_OPEN | 591 base::PLATFORM_FILE_READ)); 592 p->Remove(kRendererID); 593 594 // Grant permissions for the directory the file is in. 595 p->Add(kRendererID); 596 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 597 base::PLATFORM_FILE_OPEN)); 598 GrantPermissionsForFile(p, kRendererID, parent_file, 599 base::PLATFORM_FILE_OPEN | 600 base::PLATFORM_FILE_READ); 601 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 602 base::PLATFORM_FILE_OPEN)); 603 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 604 base::PLATFORM_FILE_READ | 605 base::PLATFORM_FILE_WRITE)); 606 p->Remove(kRendererID); 607 608 // Grant permissions for the directory the file is in (with trailing '/'). 609 p->Add(kRendererID); 610 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 611 base::PLATFORM_FILE_OPEN)); 612 GrantPermissionsForFile(p, kRendererID, parent_slash_file, 613 base::PLATFORM_FILE_OPEN | 614 base::PLATFORM_FILE_READ); 615 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 616 base::PLATFORM_FILE_OPEN)); 617 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 618 base::PLATFORM_FILE_READ | 619 base::PLATFORM_FILE_WRITE)); 620 621 // Grant permissions for the file (should overwrite the permissions granted 622 // for the directory). 623 GrantPermissionsForFile(p, kRendererID, granted_file, 624 base::PLATFORM_FILE_TEMPORARY); 625 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 626 base::PLATFORM_FILE_OPEN)); 627 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 628 base::PLATFORM_FILE_TEMPORARY)); 629 630 // Revoke all permissions for the file (it should inherit its permissions 631 // from the directory again). 632 p->RevokeAllPermissionsForFile(kRendererID, granted_file); 633 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 634 base::PLATFORM_FILE_OPEN | 635 base::PLATFORM_FILE_READ)); 636 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 637 base::PLATFORM_FILE_TEMPORARY)); 638 p->Remove(kRendererID); 639 640 // Grant file permissions for the file to main thread renderer process, 641 // make sure its worker thread renderer process inherits those. 642 p->Add(kRendererID); 643 GrantPermissionsForFile(p, kRendererID, granted_file, 644 base::PLATFORM_FILE_OPEN | 645 base::PLATFORM_FILE_READ); 646 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, 647 base::PLATFORM_FILE_OPEN | 648 base::PLATFORM_FILE_READ)); 649 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 650 base::PLATFORM_FILE_WRITE)); 651 p->AddWorker(kWorkerRendererID, kRendererID); 652 EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, 653 base::PLATFORM_FILE_OPEN | 654 base::PLATFORM_FILE_READ)); 655 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, 656 base::PLATFORM_FILE_WRITE)); 657 p->Remove(kRendererID); 658 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, 659 base::PLATFORM_FILE_OPEN | 660 base::PLATFORM_FILE_READ)); 661 p->Remove(kWorkerRendererID); 662 663 p->Add(kRendererID); 664 GrantPermissionsForFile(p, kRendererID, relative_file, 665 base::PLATFORM_FILE_OPEN); 666 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, relative_file, 667 base::PLATFORM_FILE_OPEN)); 668 p->Remove(kRendererID); 669 } 670 671 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) { 672 ChildProcessSecurityPolicyImpl* p = 673 ChildProcessSecurityPolicyImpl::GetInstance(); 674 675 GURL url("chrome://thumb/http://www.google.com/"); 676 677 p->Add(kRendererID); 678 679 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); 680 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); 681 p->GrantWebUIBindings(kRendererID); 682 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); 683 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); 684 685 p->Remove(kRendererID); 686 } 687 688 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) { 689 ChildProcessSecurityPolicyImpl* p = 690 ChildProcessSecurityPolicyImpl::GetInstance(); 691 692 GURL url("file:///etc/passwd"); 693 base::FilePath file(TEST_PATH("/etc/passwd")); 694 695 p->Add(kRendererID); 696 697 p->GrantRequestURL(kRendererID, url); 698 p->GrantReadFile(kRendererID, file); 699 p->GrantWebUIBindings(kRendererID); 700 701 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); 702 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); 703 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); 704 705 p->Remove(kRendererID); 706 707 // Renderers are added and removed on the UI thread, but the policy can be 708 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be 709 // prepared to answer policy questions about renderers who no longer exist. 710 711 // In this case, we default to secure behavior. 712 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); 713 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); 714 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); 715 } 716 717 } // namespace content 718