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/SourceListDirective.h" | 5 #include "core/frame/csp/SourceListDirective.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/frame/csp/CSPSource.h" | 8 #include "core/frame/csp/CSPSource.h" |
9 #include "core/frame/csp/ContentSecurityPolicy.h" | 9 #include "core/frame/csp/ContentSecurityPolicy.h" |
10 #include "platform/network/ResourceRequest.h" | 10 #include "platform/network/ResourceRequest.h" |
(...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 EXPECT_EQ(scriptSrc.isNone(), test.expected); | 844 EXPECT_EQ(scriptSrc.isNone(), test.expected); |
845 | 845 |
846 SourceListDirective styleSrc("form-action", test.sources, csp.get()); | 846 SourceListDirective styleSrc("form-action", test.sources, csp.get()); |
847 EXPECT_EQ(styleSrc.isNone(), test.expected); | 847 EXPECT_EQ(styleSrc.isNone(), test.expected); |
848 | 848 |
849 SourceListDirective imgSrc("frame-src", test.sources, csp.get()); | 849 SourceListDirective imgSrc("frame-src", test.sources, csp.get()); |
850 EXPECT_EQ(styleSrc.isNone(), test.expected); | 850 EXPECT_EQ(styleSrc.isNone(), test.expected); |
851 } | 851 } |
852 } | 852 } |
853 | 853 |
| 854 TEST_F(SourceListDirectiveTest, GetIntersectNonces) { |
| 855 SourceListDirective listA( |
| 856 "script-src", |
| 857 "http://example.com 'nonce-abc' 'nonce-xyz' 'nonce-' 'unsafe-inline'", |
| 858 csp.get()); |
| 859 struct TestCase { |
| 860 String sources; |
| 861 String expected; |
| 862 } cases[] = { |
| 863 {"http:", ""}, |
| 864 {"http://example.com", ""}, |
| 865 {"example.com", ""}, |
| 866 {"'unsafe-inline'", ""}, |
| 867 {"'nonce-abc'", "'nonce-abc'"}, |
| 868 {"'nonce-xyz'", "'nonce-xyz'"}, |
| 869 {"'nonce-123'", ""}, |
| 870 {"'nonce-abc' 'nonce-xyz'", "'nonce-abc' 'nonce-xyz'"}, |
| 871 {"'nonce-abc' 'nonce-xyz' 'nonce'", "'nonce-abc' 'nonce-xyz'"}, |
| 872 {"'nonce-abc' 'nonce-123'", "'nonce-abc'"}, |
| 873 {"'nonce-123' 'nonce-123'", ""}, |
| 874 {"'nonce-123' 'nonce-abc'", "'nonce-abc'"}, |
| 875 {"'nonce-123' 'nonce-xyz'", "'nonce-xyz'"}, |
| 876 {"'nonce-123' 'nonce-xyx'", ""}, |
| 877 }; |
| 878 |
| 879 for (const auto& test : cases) { |
| 880 SourceListDirective listB("script-src", test.sources, csp.get()); |
| 881 HashSet<String> normalized = listA.getIntersectNonces(listB.m_nonces); |
| 882 |
| 883 SourceListDirective expectedList("script-src", test.expected, csp.get()); |
| 884 HashSet<String> expected = expectedList.m_nonces; |
| 885 EXPECT_EQ(normalized.size(), expected.size()); |
| 886 for (const auto& nonce : normalized) { |
| 887 EXPECT_TRUE(expected.contains(nonce)); |
| 888 } |
| 889 } |
| 890 } |
| 891 |
| 892 TEST_F(SourceListDirectiveTest, GetIntersectHashes) { |
| 893 SourceListDirective listA( |
| 894 "script-src", |
| 895 "http://example.com 'sha256-abc123' 'sha384-' 'sha512-321cba' 'self'", |
| 896 csp.get()); |
| 897 struct TestCase { |
| 898 String sources; |
| 899 String expected; |
| 900 } cases[] = { |
| 901 {"http:", ""}, |
| 902 {"http://example.com", ""}, |
| 903 {"example.com", ""}, |
| 904 {"'unsafe-inline'", ""}, |
| 905 {"'sha384-abc'", ""}, |
| 906 {"'sha384-'", ""}, |
| 907 {"'sha256-abc123'", "'sha256-abc123'"}, |
| 908 {"'sha256-abc123' 'sha384-'", "'sha256-abc123'"}, |
| 909 {"'sha256-abc123' 'sha512-321cba'", "'sha512-321cba' 'sha256-abc123'"}, |
| 910 {"'sha256-abc123' 'sha384-' 'sha512-321cba'", |
| 911 "'sha256-abc123' 'sha512-321cba' "}, |
| 912 {"'sha256-else' 'sha384-' 'sha512-321cba'", "'sha512-321cba' "}, |
| 913 {"'hash-123'", ""}, |
| 914 {"'sha256-123'", ""}, |
| 915 }; |
| 916 |
| 917 for (const auto& test : cases) { |
| 918 SourceListDirective listB("script-src", test.sources, csp.get()); |
| 919 HashSet<CSPHashValue> normalized = listA.getIntersectHashes(listB.m_hashes); |
| 920 |
| 921 SourceListDirective expectedList("script-src", test.expected, csp.get()); |
| 922 HashSet<CSPHashValue> expected = expectedList.m_hashes; |
| 923 EXPECT_EQ(normalized.size(), expected.size()); |
| 924 for (const auto& hash : normalized) { |
| 925 EXPECT_TRUE(expected.contains(hash)); |
| 926 } |
| 927 } |
| 928 } |
| 929 |
| 930 TEST_F(SourceListDirectiveTest, SubsumesNoncesAndHashes) { |
| 931 struct TestCase { |
| 932 bool isScriptSrc; |
| 933 String sourcesA; |
| 934 std::vector<String> sourcesB; |
| 935 bool expected; |
| 936 } cases[] = { |
| 937 // Check nonces. |
| 938 {true, |
| 939 "http://example1.com/foo/ 'unsafe-inline' 'nonce-abc'", |
| 940 {"'unsafe-inline'"}, |
| 941 false}, |
| 942 {true, |
| 943 "http://example1.com/foo/ 'self' 'unsafe-inline' 'nonce-abc'", |
| 944 {"'nonce-abc'"}, |
| 945 true}, |
| 946 {true, |
| 947 "http://example1.com/foo/ 'self' 'unsafe-inline'", |
| 948 {"'unsafe-inline' 'nonce-yay'", "'nonce-yay'"}, |
| 949 false}, |
| 950 {true, |
| 951 "http://example1.com/foo/ 'self' 'nonce-yay'", |
| 952 {"'unsafe-inline' 'nonce-yay'", "'nonce-yay'"}, |
| 953 true}, |
| 954 {true, |
| 955 "http://example1.com/foo/ 'self' 'nonce-abc' 'nonce-yay'", |
| 956 {"'unsafe-inline' https://example.test/"}, |
| 957 false}, |
| 958 {true, |
| 959 "http://example1.com/foo/ 'self' 'nonce-abc' 'nonce-yay'", |
| 960 {"'nonce-abc' https://example1.com/foo/"}, |
| 961 true}, |
| 962 {true, |
| 963 "http://example1.com/foo/ 'self' 'unsafe-inline' 'nonce-yay' " |
| 964 "'strict-dynamic'", |
| 965 {"https://example.test/ 'nonce-yay'"}, |
| 966 false}, |
| 967 {false, |
| 968 "http://example1.com/foo/ 'self' 'unsafe-inline' 'nonce-yay' " |
| 969 "'strict-dynamic'", |
| 970 {"'nonce-yay' https://example1.com/foo/"}, |
| 971 true}, |
| 972 // Check hashes. |
| 973 {true, |
| 974 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321cba'", |
| 975 {"http://example1.com/foo/page.html 'strict-dynamic'", |
| 976 "https://example1.com/foo/ 'sha512-321cba'"}, |
| 977 true}, |
| 978 {true, |
| 979 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321cba'", |
| 980 {"http://some-other.com/ 'strict-dynamic' 'sha512-321cba'", |
| 981 "http://example1.com/foo/ 'unsafe-inline' 'sha512-321cba'"}, |
| 982 true}, |
| 983 {true, |
| 984 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321cba'", |
| 985 {"http://example1.com/foo/ 'sha512-321abc' 'sha512-321cba'", |
| 986 "http://example1.com/foo/ 'sha512-321abc' 'sha512-321cba'"}, |
| 987 false}, |
| 988 {true, |
| 989 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321cba'", |
| 990 {"http://example1.com/foo/ 'unsafe-inline'", |
| 991 "http://example1.com/foo/ 'sha512-321cba'"}, |
| 992 true}, |
| 993 {true, |
| 994 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc'", |
| 995 {"http://example1.com/foo/ 'unsafe-inline' 'sha512-321abc'", |
| 996 "http://example1.com/foo/ 'sha512-321abc'"}, |
| 997 true}, |
| 998 {true, |
| 999 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc'", |
| 1000 {"'unsafe-inline' 'sha512-321abc'", |
| 1001 "http://example1.com/foo/ 'sha512-321abc'"}, |
| 1002 true}, |
| 1003 // Nonces and hashes together. |
| 1004 {true, |
| 1005 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc' " |
| 1006 "'nonce-abc'", |
| 1007 {"'unsafe-inline' 'sha512-321abc' 'self'", |
| 1008 "'unsafe-inline''sha512-321abc' https://example.test/"}, |
| 1009 true}, |
| 1010 {true, |
| 1011 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc' " |
| 1012 "'nonce-abc'", |
| 1013 {"'unsafe-inline' 'sha512-321abc' 'self' 'nonce-abc'", |
| 1014 "'sha512-321abc' https://example.test/"}, |
| 1015 true}, |
| 1016 {true, |
| 1017 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc' " |
| 1018 "'nonce-abc'", |
| 1019 {"'unsafe-inline' 'sha512-321abc' 'self'", |
| 1020 " 'sha512-321abc' https://example.test/ 'nonce-abc'"}, |
| 1021 true}, |
| 1022 {true, |
| 1023 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc' " |
| 1024 "'nonce-abc'", |
| 1025 {"'unsafe-inline' 'sha512-321abc' 'self' 'nonce-xyz'", |
| 1026 "unsafe-inline' 'sha512-321abc' https://example.test/ 'nonce-xyz'"}, |
| 1027 false}, |
| 1028 {true, |
| 1029 "http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321abc' " |
| 1030 "'nonce-abc'", |
| 1031 {"'unsafe-inline' 'sha512-321abc' 'self' 'sha512-xyz'", |
| 1032 "unsafe-inline' 'sha512-321abc' https://example.test/ 'sha512-xyz'"}, |
| 1033 false}, |
| 1034 |
| 1035 }; |
| 1036 |
| 1037 for (const auto& test : cases) { |
| 1038 SourceListDirective A(test.isScriptSrc ? "script-src" : "style-src", |
| 1039 test.sourcesA, csp.get()); |
| 1040 ContentSecurityPolicy* cspB = |
| 1041 SetUpWithOrigin("https://another.test/image.png"); |
| 1042 |
| 1043 HeapVector<Member<SourceListDirective>> vectorB; |
| 1044 for (const auto& sources : test.sourcesB) { |
| 1045 SourceListDirective* member = new SourceListDirective( |
| 1046 test.isScriptSrc ? "script-src" : "style-src", sources, cspB); |
| 1047 vectorB.append(member); |
| 1048 } |
| 1049 |
| 1050 EXPECT_EQ(A.subsumes(vectorB), test.expected); |
| 1051 } |
| 1052 } |
| 1053 |
854 } // namespace blink | 1054 } // namespace blink |
OLD | NEW |