OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <set> | 5 #include <set> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
11 #include "content/browser/child_process_security_policy_impl.h" | 11 #include "content/browser/child_process_security_policy_impl.h" |
12 #include "content/public/common/url_constants.h" | 12 #include "content/public/common/url_constants.h" |
13 #include "content/test/test_content_browser_client.h" | 13 #include "content/test/test_content_browser_client.h" |
14 #include "googleurl/src/gurl.h" | 14 #include "googleurl/src/gurl.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 namespace content { | 17 namespace content { |
18 namespace { | 18 namespace { |
19 | 19 |
20 const int kRendererID = 42; | 20 const int kRendererID = 42; |
21 const int kWorkerRendererID = kRendererID + 1; | 21 const int kWorkerRendererID = kRendererID + 1; |
22 | 22 |
23 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | |
24 #define TEST_PATH(x) FILE_PATH_LITERAL("c:") FILE_PATH_LITERAL(x) | |
25 #else | |
26 #define TEST_PATH(x) FILE_PATH_LITERAL(x) | |
27 #endif | |
28 | |
23 class ChildProcessSecurityPolicyTestBrowserClient | 29 class ChildProcessSecurityPolicyTestBrowserClient |
24 : public TestContentBrowserClient { | 30 : public TestContentBrowserClient { |
25 public: | 31 public: |
26 ChildProcessSecurityPolicyTestBrowserClient() {} | 32 ChildProcessSecurityPolicyTestBrowserClient() {} |
27 | 33 |
28 virtual bool IsHandledURL(const GURL& url) { | 34 virtual bool IsHandledURL(const GURL& url) { |
29 return schemes_.find(url.scheme()) != schemes_.end(); | 35 return schemes_.find(url.scheme()) != schemes_.end(); |
30 } | 36 } |
31 | 37 |
32 void ClearSchemes() { | 38 void ClearSchemes() { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 | 293 |
288 p->Remove(kRendererID); | 294 p->Remove(kRendererID); |
289 } | 295 } |
290 | 296 |
291 TEST_F(ChildProcessSecurityPolicyTest, CanReadFiles) { | 297 TEST_F(ChildProcessSecurityPolicyTest, CanReadFiles) { |
292 ChildProcessSecurityPolicyImpl* p = | 298 ChildProcessSecurityPolicyImpl* p = |
293 ChildProcessSecurityPolicyImpl::GetInstance(); | 299 ChildProcessSecurityPolicyImpl::GetInstance(); |
294 | 300 |
295 p->Add(kRendererID); | 301 p->Add(kRendererID); |
296 | 302 |
297 EXPECT_FALSE(p->CanReadFile(kRendererID, | 303 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
298 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | 304 p->GrantReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd"))); |
299 p->GrantReadFile(kRendererID, FilePath(FILE_PATH_LITERAL("/etc/passwd"))); | 305 EXPECT_TRUE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
300 EXPECT_TRUE(p->CanReadFile(kRendererID, | 306 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/shadow")))); |
301 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | |
302 EXPECT_FALSE(p->CanReadFile(kRendererID, | |
303 FilePath(FILE_PATH_LITERAL("/etc/shadow")))); | |
304 | 307 |
305 p->Remove(kRendererID); | 308 p->Remove(kRendererID); |
306 p->Add(kRendererID); | 309 p->Add(kRendererID); |
307 | 310 |
308 EXPECT_FALSE(p->CanReadFile(kRendererID, | 311 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
309 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | 312 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/shadow")))); |
310 EXPECT_FALSE(p->CanReadFile(kRendererID, | |
311 FilePath(FILE_PATH_LITERAL("/etc/shadow")))); | |
312 | 313 |
313 p->Remove(kRendererID); | 314 p->Remove(kRendererID); |
314 } | 315 } |
315 | 316 |
316 TEST_F(ChildProcessSecurityPolicyTest, CanReadDirectories) { | 317 TEST_F(ChildProcessSecurityPolicyTest, CanReadDirectories) { |
317 ChildProcessSecurityPolicyImpl* p = | 318 ChildProcessSecurityPolicyImpl* p = |
318 ChildProcessSecurityPolicyImpl::GetInstance(); | 319 ChildProcessSecurityPolicyImpl::GetInstance(); |
319 | 320 |
320 p->Add(kRendererID); | 321 p->Add(kRendererID); |
321 | 322 |
322 EXPECT_FALSE(p->CanReadDirectory(kRendererID, | 323 EXPECT_FALSE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
323 FilePath(FILE_PATH_LITERAL("/etc/")))); | 324 p->GrantReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/"))); |
324 p->GrantReadDirectory(kRendererID, FilePath(FILE_PATH_LITERAL("/etc/"))); | 325 EXPECT_TRUE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
325 EXPECT_TRUE(p->CanReadDirectory(kRendererID, | 326 EXPECT_TRUE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
326 FilePath(FILE_PATH_LITERAL("/etc/")))); | |
327 EXPECT_TRUE(p->CanReadFile(kRendererID, | |
328 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | |
329 | 327 |
330 p->Remove(kRendererID); | 328 p->Remove(kRendererID); |
331 p->Add(kRendererID); | 329 p->Add(kRendererID); |
332 | 330 |
333 EXPECT_FALSE(p->CanReadDirectory(kRendererID, | 331 EXPECT_FALSE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
334 FilePath(FILE_PATH_LITERAL("/etc/")))); | 332 EXPECT_FALSE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
335 EXPECT_FALSE(p->CanReadFile(kRendererID, | |
336 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | |
337 | 333 |
338 // Just granting read permission as a file doesn't imply reading as a | 334 // Just granting read permission as a file doesn't imply reading as a |
339 // directory. | 335 // directory. |
340 p->GrantReadFile(kRendererID, FilePath(FILE_PATH_LITERAL("/etc/"))); | 336 p->GrantReadFile(kRendererID, FilePath(TEST_PATH("/etc/"))); |
341 EXPECT_TRUE(p->CanReadFile(kRendererID, | 337 EXPECT_TRUE(p->CanReadFile(kRendererID, FilePath(TEST_PATH("/etc/passwd")))); |
342 FilePath(FILE_PATH_LITERAL("/etc/passwd")))); | 338 EXPECT_FALSE(p->CanReadDirectory(kRendererID, FilePath(TEST_PATH("/etc/")))); |
343 EXPECT_FALSE(p->CanReadDirectory(kRendererID, | |
344 FilePath(FILE_PATH_LITERAL("/etc/")))); | |
345 | 339 |
346 p->Remove(kRendererID); | 340 p->Remove(kRendererID); |
347 } | 341 } |
348 | 342 |
349 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) { | 343 TEST_F(ChildProcessSecurityPolicyTest, FilePermissions) { |
350 FilePath granted_file = FilePath(FILE_PATH_LITERAL("/home/joe")); | 344 FilePath granted_file = FilePath(TEST_PATH("/home/joe")); |
351 FilePath sibling_file = FilePath(FILE_PATH_LITERAL("/home/bob")); | 345 FilePath sibling_file = FilePath(TEST_PATH("/home/bob")); |
352 FilePath child_file = FilePath(FILE_PATH_LITERAL("/home/joe/file")); | 346 FilePath child_file = FilePath(TEST_PATH("/home/joe/file")); |
353 FilePath parent_file = FilePath(FILE_PATH_LITERAL("/home")); | 347 FilePath parent_file = FilePath(TEST_PATH("/home")); |
354 FilePath parent_slash_file = FilePath(FILE_PATH_LITERAL("/home/")); | 348 FilePath parent_slash_file = FilePath(TEST_PATH("/home/")); |
355 FilePath child_traversal1 = FilePath( | 349 FilePath child_traversal1 = FilePath(TEST_PATH("/home/joe/././file")); |
356 FILE_PATH_LITERAL("/home/joe/././file")); | |
357 FilePath child_traversal2 = FilePath( | 350 FilePath child_traversal2 = FilePath( |
358 FILE_PATH_LITERAL("/home/joe/file/../otherfile")); | 351 TEST_PATH("/home/joe/file/../otherfile")); |
359 FilePath evil_traversal1 = FilePath( | 352 FilePath evil_traversal1 = FilePath(TEST_PATH("/home/joe/../../etc/passwd")); |
360 FILE_PATH_LITERAL("/home/joe/../../etc/passwd")); | |
361 FilePath evil_traversal2 = FilePath( | 353 FilePath evil_traversal2 = FilePath( |
362 FILE_PATH_LITERAL("/home/joe/./.././../etc/passwd")); | 354 TEST_PATH("/home/joe/./.././../etc/passwd")); |
363 FilePath self_traversal = FilePath( | 355 FilePath self_traversal = FilePath(TEST_PATH("/home/joe/../joe/file")); |
364 FILE_PATH_LITERAL("/home/joe/../joe/file")); | 356 FilePath relative_file = FilePath(TEST_PATH("home/joe")); |
Charlie Reis
2013/01/04 20:59:34
Isn't this going to result in c:home/joe? I suppo
| |
365 | 357 |
366 ChildProcessSecurityPolicyImpl* p = | 358 ChildProcessSecurityPolicyImpl* p = |
367 ChildProcessSecurityPolicyImpl::GetInstance(); | 359 ChildProcessSecurityPolicyImpl::GetInstance(); |
368 | 360 |
369 // Grant permissions for a file. | 361 // Grant permissions for a file. |
370 p->Add(kRendererID); | 362 p->Add(kRendererID); |
371 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, | 363 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, |
372 base::PLATFORM_FILE_OPEN)); | 364 base::PLATFORM_FILE_OPEN)); |
373 | 365 |
374 p->GrantPermissionsForFile(kRendererID, granted_file, | 366 p->GrantPermissionsForFile(kRendererID, granted_file, |
375 base::PLATFORM_FILE_OPEN | | 367 base::PLATFORM_FILE_OPEN | |
376 base::PLATFORM_FILE_OPEN_TRUNCATED | | 368 base::PLATFORM_FILE_OPEN_TRUNCATED | |
377 base::PLATFORM_FILE_READ | | 369 base::PLATFORM_FILE_READ | |
378 base::PLATFORM_FILE_WRITE); | 370 base::PLATFORM_FILE_WRITE); |
379 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, | 371 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, |
380 base::PLATFORM_FILE_OPEN | | 372 base::PLATFORM_FILE_OPEN | |
381 base::PLATFORM_FILE_OPEN_TRUNCATED | | 373 base::PLATFORM_FILE_OPEN_TRUNCATED | |
382 base::PLATFORM_FILE_READ | | 374 base::PLATFORM_FILE_READ | |
383 base::PLATFORM_FILE_WRITE)); | 375 base::PLATFORM_FILE_WRITE)); |
384 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, | 376 EXPECT_TRUE(p->HasPermissionsForFile(kRendererID, granted_file, |
385 base::PLATFORM_FILE_OPEN | | 377 base::PLATFORM_FILE_OPEN | |
386 base::PLATFORM_FILE_READ)); | 378 base::PLATFORM_FILE_READ)); |
387 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, | 379 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, |
388 base::PLATFORM_FILE_CREATE)); | 380 base::PLATFORM_FILE_CREATE)); |
381 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, 0)); | |
389 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, | 382 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, granted_file, |
390 base::PLATFORM_FILE_CREATE | | 383 base::PLATFORM_FILE_CREATE | |
391 base::PLATFORM_FILE_OPEN_TRUNCATED | | 384 base::PLATFORM_FILE_OPEN_TRUNCATED | |
392 base::PLATFORM_FILE_READ | | 385 base::PLATFORM_FILE_READ | |
393 base::PLATFORM_FILE_WRITE)); | 386 base::PLATFORM_FILE_WRITE)); |
394 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file, | 387 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, sibling_file, |
395 base::PLATFORM_FILE_OPEN | | 388 base::PLATFORM_FILE_OPEN | |
396 base::PLATFORM_FILE_READ)); | 389 base::PLATFORM_FILE_READ)); |
397 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file, | 390 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, parent_file, |
398 base::PLATFORM_FILE_OPEN | | 391 base::PLATFORM_FILE_OPEN | |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, | 472 EXPECT_TRUE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, |
480 base::PLATFORM_FILE_OPEN | | 473 base::PLATFORM_FILE_OPEN | |
481 base::PLATFORM_FILE_READ)); | 474 base::PLATFORM_FILE_READ)); |
482 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, | 475 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, |
483 base::PLATFORM_FILE_WRITE)); | 476 base::PLATFORM_FILE_WRITE)); |
484 p->Remove(kRendererID); | 477 p->Remove(kRendererID); |
485 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, | 478 EXPECT_FALSE(p->HasPermissionsForFile(kWorkerRendererID, granted_file, |
486 base::PLATFORM_FILE_OPEN | | 479 base::PLATFORM_FILE_OPEN | |
487 base::PLATFORM_FILE_READ)); | 480 base::PLATFORM_FILE_READ)); |
488 p->Remove(kWorkerRendererID); | 481 p->Remove(kWorkerRendererID); |
482 | |
483 p->Add(kRendererID); | |
484 p->GrantPermissionsForFile(kRendererID, relative_file, | |
485 base::PLATFORM_FILE_OPEN); | |
486 EXPECT_FALSE(p->HasPermissionsForFile(kRendererID, relative_file, | |
487 base::PLATFORM_FILE_OPEN)); | |
488 p->Remove(kRendererID); | |
489 } | 489 } |
490 | 490 |
491 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) { | 491 TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) { |
492 ChildProcessSecurityPolicyImpl* p = | 492 ChildProcessSecurityPolicyImpl* p = |
493 ChildProcessSecurityPolicyImpl::GetInstance(); | 493 ChildProcessSecurityPolicyImpl::GetInstance(); |
494 | 494 |
495 GURL url("chrome://thumb/http://www.google.com/"); | 495 GURL url("chrome://thumb/http://www.google.com/"); |
496 | 496 |
497 p->Add(kRendererID); | 497 p->Add(kRendererID); |
498 | 498 |
499 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); | 499 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); |
500 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); | 500 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); |
501 p->GrantWebUIBindings(kRendererID); | 501 p->GrantWebUIBindings(kRendererID); |
502 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); | 502 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); |
503 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); | 503 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); |
504 | 504 |
505 p->Remove(kRendererID); | 505 p->Remove(kRendererID); |
506 } | 506 } |
507 | 507 |
508 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) { | 508 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) { |
509 ChildProcessSecurityPolicyImpl* p = | 509 ChildProcessSecurityPolicyImpl* p = |
510 ChildProcessSecurityPolicyImpl::GetInstance(); | 510 ChildProcessSecurityPolicyImpl::GetInstance(); |
511 | 511 |
512 GURL url("file:///etc/passwd"); | 512 GURL url("file:///etc/passwd"); |
513 FilePath file(FILE_PATH_LITERAL("/etc/passwd")); | 513 FilePath file(TEST_PATH("/etc/passwd")); |
514 | 514 |
515 p->Add(kRendererID); | 515 p->Add(kRendererID); |
516 | 516 |
517 p->GrantRequestURL(kRendererID, url); | 517 p->GrantRequestURL(kRendererID, url); |
518 p->GrantReadFile(kRendererID, file); | 518 p->GrantReadFile(kRendererID, file); |
519 p->GrantWebUIBindings(kRendererID); | 519 p->GrantWebUIBindings(kRendererID); |
520 | 520 |
521 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); | 521 EXPECT_TRUE(p->CanRequestURL(kRendererID, url)); |
522 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); | 522 EXPECT_TRUE(p->CanReadFile(kRendererID, file)); |
523 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); | 523 EXPECT_TRUE(p->HasWebUIBindings(kRendererID)); |
524 | 524 |
525 p->Remove(kRendererID); | 525 p->Remove(kRendererID); |
526 | 526 |
527 // Renderers are added and removed on the UI thread, but the policy can be | 527 // Renderers are added and removed on the UI thread, but the policy can be |
528 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be | 528 // queried on the IO thread. The ChildProcessSecurityPolicy needs to be |
529 // prepared to answer policy questions about renderers who no longer exist. | 529 // prepared to answer policy questions about renderers who no longer exist. |
530 | 530 |
531 // In this case, we default to secure behavior. | 531 // In this case, we default to secure behavior. |
532 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); | 532 EXPECT_FALSE(p->CanRequestURL(kRendererID, url)); |
533 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); | 533 EXPECT_FALSE(p->CanReadFile(kRendererID, file)); |
534 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); | 534 EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); |
535 } | 535 } |
536 | 536 |
537 } // namespace content | 537 } // namespace content |
OLD | NEW |