OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "base/bind.h" | |
6 #include "base/bind_helpers.h" | |
7 #include "base/memory/ref_counted.h" | |
8 #include "content/browser/frame_host/ancestor_throttle.h" | |
9 #include "content/public/browser/navigation_handle.h" | |
10 #include "content/public/browser/navigation_throttle.h" | |
11 #include "content/public/browser/web_contents.h" | |
12 #include "content/public/test/test_renderer_host.h" | |
13 #include "net/http/http_response_headers.h" | |
14 #include "testing/gmock/include/gmock/gmock.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 | |
17 namespace content { | |
18 | |
19 namespace { | |
20 | |
21 using HeaderDisposition = AncestorThrottle::HeaderDisposition; | |
22 | |
23 net::HttpResponseHeaders* GetAncestorHeaders(const char* xfo, const char* csp) { | |
24 std::string header_string("HTTP/1.1 200 OK\nX-Frame-Options: "); | |
25 header_string += xfo; | |
26 if (csp != nullptr) { | |
27 header_string += "\nContent-Security-Policy: "; | |
28 header_string += csp; | |
29 } | |
30 header_string += "\n\n"; | |
31 std::replace(header_string.begin(), header_string.end(), '\n', '\0'); | |
clamy
2016/12/09 17:14:01
If I read this correctly, we're replacing the \n w
arthursonzogni
2016/12/13 15:32:13
It's how the HttpResponseHeaders constructor requi
| |
32 net::HttpResponseHeaders* headers = | |
33 new net::HttpResponseHeaders(header_string); | |
34 EXPECT_TRUE(headers->HasHeader("X-Frame-Options")); | |
35 if (csp != nullptr) | |
36 EXPECT_TRUE(headers->HasHeader("Content-Security-Policy")); | |
37 return headers; | |
38 } | |
39 | |
40 } // namespace | |
41 | |
42 // AncestorThrottleTest | |
43 // ------------------------------------------------------------- | |
44 | |
45 class AncestorThrottleTest : public testing::Test {}; | |
46 | |
47 TEST_F(AncestorThrottleTest, ParsingXFrameOptions) { | |
48 struct TestCase { | |
49 const char* header; | |
50 AncestorThrottle::HeaderDisposition expected; | |
51 const char* value; | |
52 } cases[] = { | |
53 // Basic keywords | |
54 {"DENY", HeaderDisposition::DENY, "DENY"}, | |
55 {"SAMEORIGIN", HeaderDisposition::SAMEORIGIN, "SAMEORIGIN"}, | |
56 {"ALLOWALL", HeaderDisposition::ALLOWALL, "ALLOWALL"}, | |
57 | |
58 // Repeated keywords | |
59 {"DENY,DENY", HeaderDisposition::DENY, "DENY, DENY"}, | |
60 {"SAMEORIGIN,SAMEORIGIN", HeaderDisposition::SAMEORIGIN, | |
61 "SAMEORIGIN, SAMEORIGIN"}, | |
62 {"ALLOWALL,ALLOWALL", HeaderDisposition::ALLOWALL, "ALLOWALL, ALLOWALL"}, | |
63 | |
64 // Case-insensitive | |
65 {"deNy", HeaderDisposition::DENY, "deNy"}, | |
66 {"sAmEorIgIn", HeaderDisposition::SAMEORIGIN, "sAmEorIgIn"}, | |
67 {"AlLOWaLL", HeaderDisposition::ALLOWALL, "AlLOWaLL"}, | |
68 | |
69 // Trim whitespace | |
70 {" DENY", HeaderDisposition::DENY, "DENY"}, | |
71 {"SAMEORIGIN ", HeaderDisposition::SAMEORIGIN, "SAMEORIGIN"}, | |
72 {" ALLOWALL ", HeaderDisposition::ALLOWALL, "ALLOWALL"}, | |
73 {" DENY", HeaderDisposition::DENY, "DENY"}, | |
74 {"SAMEORIGIN ", HeaderDisposition::SAMEORIGIN, "SAMEORIGIN"}, | |
75 {" ALLOWALL ", HeaderDisposition::ALLOWALL, "ALLOWALL"}, | |
76 {" DENY , DENY ", HeaderDisposition::DENY, "DENY, DENY"}, | |
77 {"SAMEORIGIN, SAMEORIGIN", HeaderDisposition::SAMEORIGIN, | |
78 "SAMEORIGIN, SAMEORIGIN"}, | |
79 {"ALLOWALL ,ALLOWALL", HeaderDisposition::ALLOWALL, | |
80 "ALLOWALL, ALLOWALL"}, | |
81 }; | |
82 | |
83 AncestorThrottle throttle(nullptr); | |
84 for (const auto& test : cases) { | |
85 SCOPED_TRACE(test.header); | |
86 scoped_refptr<net::HttpResponseHeaders> headers = | |
87 GetAncestorHeaders(test.header, nullptr); | |
88 std::string header_value; | |
89 EXPECT_EQ(test.expected, | |
90 throttle.ParseHeader(headers.get(), &header_value)); | |
91 EXPECT_EQ(test.value, header_value); | |
92 } | |
93 } | |
94 | |
95 TEST_F(AncestorThrottleTest, ErrorsParsingXFrameOptions) { | |
96 struct TestCase { | |
97 const char* header; | |
98 AncestorThrottle::HeaderDisposition expected; | |
99 const char* failure; | |
100 } cases[] = { | |
101 // Empty == Invalid. | |
102 {"", HeaderDisposition::INVALID, ""}, | |
103 | |
104 // Invalid | |
105 {"INVALID", HeaderDisposition::INVALID, "INVALID"}, | |
106 {"INVALID DENY", HeaderDisposition::INVALID, "INVALID DENY"}, | |
107 {"DENY DENY", HeaderDisposition::INVALID, "DENY DENY"}, | |
108 {"DE NY", HeaderDisposition::INVALID, "DE NY"}, | |
109 | |
110 // Conflicts | |
111 {"INVALID,DENY", HeaderDisposition::CONFLICT, "INVALID, DENY"}, | |
112 {"DENY,ALLOWALL", HeaderDisposition::CONFLICT, "DENY, ALLOWALL"}, | |
113 {"SAMEORIGIN,DENY", HeaderDisposition::CONFLICT, "SAMEORIGIN, DENY"}, | |
114 {"ALLOWALL,SAMEORIGIN", HeaderDisposition::CONFLICT, | |
115 "ALLOWALL, SAMEORIGIN"}, | |
116 {"DENY, SAMEORIGIN", HeaderDisposition::CONFLICT, "DENY, SAMEORIGIN"}}; | |
117 | |
118 AncestorThrottle throttle(nullptr); | |
119 for (const auto& test : cases) { | |
120 SCOPED_TRACE(test.header); | |
121 scoped_refptr<net::HttpResponseHeaders> headers = | |
122 GetAncestorHeaders(test.header, nullptr); | |
123 std::string header_value; | |
124 EXPECT_EQ(test.expected, | |
125 throttle.ParseHeader(headers.get(), &header_value)); | |
126 EXPECT_EQ(test.failure, header_value); | |
127 } | |
128 } | |
129 | |
130 TEST_F(AncestorThrottleTest, IgnoreWhenFrameAncestorsPresent) { | |
131 struct TestCase { | |
132 const char* csp; | |
133 AncestorThrottle::HeaderDisposition expected; | |
134 } cases[] = { | |
135 {"", HeaderDisposition::DENY}, | |
136 {"frame-ancestors 'none'", HeaderDisposition::BYPASS}, | |
137 {"frame-ancestors *", HeaderDisposition::BYPASS}, | |
138 {"frame-ancestors 'self'", HeaderDisposition::BYPASS}, | |
139 {"frame-ancestors https://example.com", HeaderDisposition::BYPASS}, | |
140 {"fRaMe-AnCeStOrS *", HeaderDisposition::BYPASS}, | |
141 {"directive1; frame-ancestors 'none'", HeaderDisposition::BYPASS}, | |
142 {"directive1; frame-ancestors *", HeaderDisposition::BYPASS}, | |
143 {"directive1; frame-ancestors 'self'", HeaderDisposition::BYPASS}, | |
144 {"directive1; frame-ancestors https://example.com", | |
145 HeaderDisposition::BYPASS}, | |
146 {"directive1; fRaMe-AnCeStOrS *", HeaderDisposition::BYPASS}, | |
147 {"policy, frame-ancestors 'none'", HeaderDisposition::BYPASS}, | |
148 {"policy, frame-ancestors *", HeaderDisposition::BYPASS}, | |
149 {"policy, frame-ancestors 'self'", HeaderDisposition::BYPASS}, | |
150 {"policy, frame-ancestors https://example.com", | |
151 HeaderDisposition::BYPASS}, | |
152 {"policy, frame-ancestors 'none'", HeaderDisposition::BYPASS}, | |
153 {"policy, directive1; frame-ancestors *", HeaderDisposition::BYPASS}, | |
154 {"policy, directive1; frame-ancestors 'self'", HeaderDisposition::BYPASS}, | |
155 {"policy, directive1; frame-ancestors https://example.com", | |
156 HeaderDisposition::BYPASS}, | |
157 {"policy, directive1; fRaMe-AnCeStOrS *", HeaderDisposition::BYPASS}, | |
158 {"policy, directive1; fRaMe-AnCeStOrS *", HeaderDisposition::BYPASS}, | |
159 | |
160 {"not-frame-ancestors *", HeaderDisposition::DENY}, | |
161 {"frame-ancestors-are-lovely", HeaderDisposition::DENY}, | |
162 {"directive1; not-frame-ancestors *", HeaderDisposition::DENY}, | |
163 {"directive1; frame-ancestors-are-lovely", HeaderDisposition::DENY}, | |
164 {"policy, not-frame-ancestors *", HeaderDisposition::DENY}, | |
165 {"policy, frame-ancestors-are-lovely", HeaderDisposition::DENY}, | |
166 {"policy, directive1; not-frame-ancestors *", HeaderDisposition::DENY}, | |
167 {"policy, directive1; frame-ancestors-are-lovely", | |
168 HeaderDisposition::DENY}, | |
169 }; | |
170 | |
171 AncestorThrottle throttle(nullptr); | |
172 for (const auto& test : cases) { | |
173 SCOPED_TRACE(test.csp); | |
174 scoped_refptr<net::HttpResponseHeaders> headers = | |
175 GetAncestorHeaders("DENY", test.csp); | |
176 std::string header_value; | |
177 EXPECT_EQ(test.expected, | |
178 throttle.ParseHeader(headers.get(), &header_value)); | |
179 EXPECT_EQ("DENY", header_value); | |
180 } | |
181 } | |
182 | |
183 } // namespace content | |
OLD | NEW |