OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "core/frame/csp/CSPSource.h" | 5 #include "core/frame/csp/CSPSource.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/frame/csp/ContentSecurityPolicy.h" | 8 #include "core/frame/csp/ContentSecurityPolicy.h" |
9 #include "platform/network/ResourceRequest.h" | 9 #include "platform/network/ResourceRequest.h" |
10 #include "platform/weborigin/KURL.h" | 10 #include "platform/weborigin/KURL.h" |
11 #include "platform/weborigin/SecurityOrigin.h" | 11 #include "platform/weborigin/SecurityOrigin.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace blink { | 14 namespace blink { |
15 | 15 |
16 class CSPSourceTest : public ::testing::Test { | 16 class CSPSourceTest : public ::testing::Test { |
17 public: | 17 public: |
18 CSPSourceTest() : csp(ContentSecurityPolicy::create()) {} | 18 CSPSourceTest() : csp(ContentSecurityPolicy::create()) {} |
19 | 19 |
20 protected: | 20 protected: |
21 Persistent<ContentSecurityPolicy> csp; | 21 Persistent<ContentSecurityPolicy> csp; |
| 22 struct Source { |
| 23 String scheme; |
| 24 String host; |
| 25 String path; |
| 26 // port is 0 if it was not specified so the default port for a given scheme |
| 27 // will be used. |
| 28 const int port; |
| 29 CSPSource::WildcardDisposition hostWildcard; |
| 30 CSPSource::WildcardDisposition portWildcard; |
| 31 }; |
| 32 |
| 33 bool equalSources(const Source& a, const Source& b) { |
| 34 return a.scheme == b.scheme && a.host == b.host && a.port == b.port && |
| 35 a.path == b.path && a.hostWildcard == b.hostWildcard && |
| 36 a.portWildcard == b.portWildcard; |
| 37 } |
22 }; | 38 }; |
23 | 39 |
24 TEST_F(CSPSourceTest, BasicMatching) { | 40 TEST_F(CSPSourceTest, BasicMatching) { |
25 KURL base; | 41 KURL base; |
26 CSPSource source(csp.get(), "http", "example.com", 8000, "/foo/", | 42 CSPSource source(csp.get(), "http", "example.com", 8000, "/foo/", |
27 CSPSource::NoWildcard, CSPSource::NoWildcard); | 43 CSPSource::NoWildcard, CSPSource::NoWildcard); |
28 | 44 |
29 EXPECT_TRUE(source.matches(KURL(base, "http://example.com:8000/foo/"))); | 45 EXPECT_TRUE(source.matches(KURL(base, "http://example.com:8000/foo/"))); |
30 EXPECT_TRUE(source.matches(KURL(base, "http://example.com:8000/foo/bar"))); | 46 EXPECT_TRUE(source.matches(KURL(base, "http://example.com:8000/foo/bar"))); |
31 EXPECT_TRUE(source.matches(KURL(base, "HTTP://EXAMPLE.com:8000/foo/BAR"))); | 47 EXPECT_TRUE(source.matches(KURL(base, "HTTP://EXAMPLE.com:8000/foo/BAR"))); |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 listB.append(httpsOnly); | 549 listB.append(httpsOnly); |
534 EXPECT_FALSE(CSPSource::firstSubsumesSecond(listA, listB)); | 550 EXPECT_FALSE(CSPSource::firstSubsumesSecond(listA, listB)); |
535 | 551 |
536 // If we add a scheme-source expression of 'http' to `listA`, then it should | 552 // If we add a scheme-source expression of 'http' to `listA`, then it should |
537 // subsume all current epxression in `listB`. | 553 // subsume all current epxression in `listB`. |
538 listA.append(httpOnly); | 554 listA.append(httpOnly); |
539 EXPECT_TRUE(CSPSource::firstSubsumesSecond(listA, listB)); | 555 EXPECT_TRUE(CSPSource::firstSubsumesSecond(listA, listB)); |
540 } | 556 } |
541 } | 557 } |
542 | 558 |
| 559 TEST_F(CSPSourceTest, Intersect) { |
| 560 struct TestCase { |
| 561 const Source a; |
| 562 const Source b; |
| 563 const Source normalized; |
| 564 } cases[] = { |
| 565 {{"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 566 CSPSource::NoWildcard}, |
| 567 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 568 CSPSource::NoWildcard}, |
| 569 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 570 CSPSource::NoWildcard}}, |
| 571 {{"ws", "example.com", "/", 0, CSPSource::NoWildcard, |
| 572 CSPSource::NoWildcard}, |
| 573 {"wss", "example.com", "/", 0, CSPSource::NoWildcard, |
| 574 CSPSource::NoWildcard}, |
| 575 {"wss", "example.com", "/", 0, CSPSource::NoWildcard, |
| 576 CSPSource::NoWildcard}}, |
| 577 // Wildcards |
| 578 {{"http", "example.com", "/", 0, CSPSource::HasWildcard, |
| 579 CSPSource::NoWildcard}, |
| 580 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 581 CSPSource::NoWildcard}, |
| 582 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 583 CSPSource::NoWildcard}}, |
| 584 {{"http", "example.com", "/", 0, CSPSource::HasWildcard, |
| 585 CSPSource::HasWildcard}, |
| 586 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 587 CSPSource::NoWildcard}, |
| 588 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 589 CSPSource::NoWildcard}}, |
| 590 {{"http", "example.com", "/", 0, CSPSource::HasWildcard, |
| 591 CSPSource::NoWildcard}, |
| 592 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 593 CSPSource::HasWildcard}, |
| 594 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 595 CSPSource::NoWildcard}}, |
| 596 // Ports |
| 597 {{"http", "example.com", "/", 80, CSPSource::NoWildcard, |
| 598 CSPSource::NoWildcard}, |
| 599 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 600 CSPSource::NoWildcard}, |
| 601 {"http", "example.com", "/", 80, CSPSource::NoWildcard, |
| 602 CSPSource::NoWildcard}}, |
| 603 // Paths |
| 604 {{"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 605 CSPSource::NoWildcard}, |
| 606 {"http", "example.com", "/1.html", 0, CSPSource::NoWildcard, |
| 607 CSPSource::NoWildcard}, |
| 608 {"http", "example.com", "/1.html", 0, CSPSource::NoWildcard, |
| 609 CSPSource::NoWildcard}}, |
| 610 {{"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 611 CSPSource::NoWildcard}, |
| 612 {"http", "example.com", "", 0, CSPSource::NoWildcard, |
| 613 CSPSource::NoWildcard}, |
| 614 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 615 CSPSource::NoWildcard}}, |
| 616 {{"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 617 CSPSource::NoWildcard}, |
| 618 {"http", "example.com", "/a/b/", 0, CSPSource::NoWildcard, |
| 619 CSPSource::NoWildcard}, |
| 620 {"http", "example.com", "/a/b/", 0, CSPSource::NoWildcard, |
| 621 CSPSource::NoWildcard}}, |
| 622 {{"http", "example.com", "/a/", 0, CSPSource::NoWildcard, |
| 623 CSPSource::NoWildcard}, |
| 624 {"http", "example.com", "/a/b/", 0, CSPSource::NoWildcard, |
| 625 CSPSource::NoWildcard}, |
| 626 {"http", "example.com", "/a/b/", 0, CSPSource::NoWildcard, |
| 627 CSPSource::NoWildcard}}, |
| 628 {{"http", "example.com", "/a/", 0, CSPSource::NoWildcard, |
| 629 CSPSource::NoWildcard}, |
| 630 {"http", "example.com", "/a/b/1.html", 0, CSPSource::NoWildcard, |
| 631 CSPSource::NoWildcard}, |
| 632 {"http", "example.com", "/a/b/1.html", 0, CSPSource::NoWildcard, |
| 633 CSPSource::NoWildcard}}, |
| 634 // Mixed |
| 635 {{"http", "example.com", "/1.html", 0, CSPSource::NoWildcard, |
| 636 CSPSource::NoWildcard}, |
| 637 {"http", "example.com", "/", 80, CSPSource::NoWildcard, |
| 638 CSPSource::NoWildcard}, |
| 639 {"http", "example.com", "/1.html", 80, CSPSource::NoWildcard, |
| 640 CSPSource::NoWildcard}}, |
| 641 }; |
| 642 |
| 643 for (const auto& test : cases) { |
| 644 CSPSource* A = |
| 645 new CSPSource(csp.get(), test.a.scheme, test.a.host, test.a.port, |
| 646 test.a.path, test.a.hostWildcard, test.a.portWildcard); |
| 647 CSPSource* B = |
| 648 new CSPSource(csp.get(), test.b.scheme, test.b.host, test.b.port, |
| 649 test.b.path, test.b.hostWildcard, test.b.portWildcard); |
| 650 |
| 651 CSPSource* normalized = A->intersect(B); |
| 652 Source intersectAB = { |
| 653 normalized->m_scheme, normalized->m_host, |
| 654 normalized->m_path, normalized->m_port, |
| 655 normalized->m_hostWildcard, normalized->m_portWildcard}; |
| 656 EXPECT_TRUE(equalSources(intersectAB, test.normalized)); |
| 657 |
| 658 // Verify the same test with A and B swapped. The result should be |
| 659 // identical. |
| 660 normalized = B->intersect(A); |
| 661 Source intersectBA = { |
| 662 normalized->m_scheme, normalized->m_host, |
| 663 normalized->m_path, normalized->m_port, |
| 664 normalized->m_hostWildcard, normalized->m_portWildcard}; |
| 665 EXPECT_TRUE(equalSources(intersectBA, test.normalized)); |
| 666 } |
| 667 } |
| 668 |
| 669 TEST_F(CSPSourceTest, IntersectSchemesOnly) { |
| 670 struct TestCase { |
| 671 const Source a; |
| 672 const Source b; |
| 673 const Source normalized; |
| 674 } cases[] = { |
| 675 // Both sources are schemes only. |
| 676 {{"http", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 677 {"http", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 678 {"http", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}}, |
| 679 {{"http", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 680 {"https", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 681 {"https", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}}, |
| 682 {{"ws", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 683 {"wss", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 684 {"wss", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}}, |
| 685 // One source is a scheme only and the other one has no wildcards. |
| 686 {{"http", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 687 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 688 CSPSource::NoWildcard}, |
| 689 {"http", "example.com", "/", 0, CSPSource::NoWildcard, |
| 690 CSPSource::NoWildcard}}, |
| 691 {{"http", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 692 {"https", "example.com", "/", 80, CSPSource::NoWildcard, |
| 693 CSPSource::NoWildcard}, |
| 694 {"https", "example.com", "/", 80, CSPSource::NoWildcard, |
| 695 CSPSource::NoWildcard}}, |
| 696 {{"https", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 697 {"http", "example.com", "/page.html", 80, CSPSource::NoWildcard, |
| 698 CSPSource::NoWildcard}, |
| 699 {"https", "example.com", "/page.html", 80, CSPSource::NoWildcard, |
| 700 CSPSource::NoWildcard}}, |
| 701 // One source is a scheme only and the other has one or two wildcards. |
| 702 {{"https", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 703 {"http", "example.com", "/page.html", 80, CSPSource::HasWildcard, |
| 704 CSPSource::NoWildcard}, |
| 705 {"https", "example.com", "/page.html", 80, CSPSource::HasWildcard, |
| 706 CSPSource::NoWildcard}}, |
| 707 {{"https", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 708 {"http", "example.com", "/page.html", 80, CSPSource::NoWildcard, |
| 709 CSPSource::HasWildcard}, |
| 710 {"https", "example.com", "/page.html", 80, CSPSource::NoWildcard, |
| 711 CSPSource::HasWildcard}}, |
| 712 {{"https", "", "", 0, CSPSource::NoWildcard, CSPSource::NoWildcard}, |
| 713 {"http", "example.com", "/page.html", 80, CSPSource::HasWildcard, |
| 714 CSPSource::HasWildcard}, |
| 715 {"https", "example.com", "/page.html", 80, CSPSource::HasWildcard, |
| 716 CSPSource::HasWildcard}}, |
| 717 }; |
| 718 |
| 719 for (const auto& test : cases) { |
| 720 CSPSource* A = |
| 721 new CSPSource(csp.get(), test.a.scheme, test.a.host, test.a.port, |
| 722 test.a.path, test.a.hostWildcard, test.a.portWildcard); |
| 723 |
| 724 CSPSource* B = |
| 725 new CSPSource(csp.get(), test.b.scheme, test.b.host, test.b.port, |
| 726 test.b.path, test.b.hostWildcard, test.b.portWildcard); |
| 727 |
| 728 CSPSource* normalized = A->intersect(B); |
| 729 Source intersectAB = { |
| 730 normalized->m_scheme, normalized->m_host, |
| 731 normalized->m_path, normalized->m_port, |
| 732 normalized->m_hostWildcard, normalized->m_portWildcard}; |
| 733 EXPECT_TRUE(equalSources(intersectAB, test.normalized)); |
| 734 |
| 735 // Verify the same test with A and B swapped. The result should be |
| 736 // identical. |
| 737 normalized = B->intersect(A); |
| 738 Source intersectBA = { |
| 739 normalized->m_scheme, normalized->m_host, |
| 740 normalized->m_path, normalized->m_port, |
| 741 normalized->m_hostWildcard, normalized->m_portWildcard}; |
| 742 EXPECT_TRUE(equalSources(intersectBA, test.normalized)); |
| 743 } |
| 744 } |
| 745 |
543 } // namespace blink | 746 } // namespace blink |
OLD | NEW |