| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "content/browser/frame_host/ancestor_throttle.h" | 8 #include "content/browser/frame_host/ancestor_throttle.h" |
| 9 #include "content/public/browser/navigation_handle.h" | 9 #include "content/public/browser/navigation_handle.h" |
| 10 #include "content/public/browser/navigation_throttle.h" | 10 #include "content/public/browser/navigation_throttle.h" |
| 11 #include "content/public/browser/web_contents.h" | 11 #include "content/public/browser/web_contents.h" |
| 12 #include "content/public/test/test_renderer_host.h" | 12 #include "content/public/test/test_renderer_host.h" |
| 13 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.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 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 using HeaderDisposition = AncestorThrottle::HeaderDisposition; | 21 using HeaderDisposition = AncestorThrottle::HeaderDisposition; |
| 22 | 22 |
| 23 net::HttpResponseHeaders* GetAncestorHeaders(const char* xfo, const char* csp) { | 23 net::HttpResponseHeaders* GetAncestorHeaders(const char* xfo, |
| 24 const char* csp, |
| 25 const char* disposition) { |
| 24 std::string header_string("HTTP/1.1 200 OK\nX-Frame-Options: "); | 26 std::string header_string("HTTP/1.1 200 OK\nX-Frame-Options: "); |
| 25 header_string += xfo; | 27 header_string += xfo; |
| 26 if (csp != nullptr) { | 28 if (csp != nullptr) { |
| 27 header_string += "\nContent-Security-Policy: "; | 29 header_string += "\nContent-Security-Policy: "; |
| 28 header_string += csp; | 30 header_string += csp; |
| 29 } | 31 } |
| 32 if (disposition != nullptr) { |
| 33 header_string += "\nContent-Disposition: "; |
| 34 header_string += disposition; |
| 35 } |
| 30 header_string += "\n\n"; | 36 header_string += "\n\n"; |
| 31 std::replace(header_string.begin(), header_string.end(), '\n', '\0'); | 37 std::replace(header_string.begin(), header_string.end(), '\n', '\0'); |
| 32 net::HttpResponseHeaders* headers = | 38 net::HttpResponseHeaders* headers = |
| 33 new net::HttpResponseHeaders(header_string); | 39 new net::HttpResponseHeaders(header_string); |
| 34 EXPECT_TRUE(headers->HasHeader("X-Frame-Options")); | 40 EXPECT_TRUE(headers->HasHeader("X-Frame-Options")); |
| 35 if (csp != nullptr) | 41 if (csp != nullptr) |
| 36 EXPECT_TRUE(headers->HasHeader("Content-Security-Policy")); | 42 EXPECT_TRUE(headers->HasHeader("Content-Security-Policy")); |
| 37 return headers; | 43 return headers; |
| 38 } | 44 } |
| 39 | 45 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 {"SAMEORIGIN, SAMEORIGIN", HeaderDisposition::SAMEORIGIN, | 83 {"SAMEORIGIN, SAMEORIGIN", HeaderDisposition::SAMEORIGIN, |
| 78 "SAMEORIGIN, SAMEORIGIN"}, | 84 "SAMEORIGIN, SAMEORIGIN"}, |
| 79 {"ALLOWALL ,ALLOWALL", HeaderDisposition::ALLOWALL, | 85 {"ALLOWALL ,ALLOWALL", HeaderDisposition::ALLOWALL, |
| 80 "ALLOWALL, ALLOWALL"}, | 86 "ALLOWALL, ALLOWALL"}, |
| 81 }; | 87 }; |
| 82 | 88 |
| 83 AncestorThrottle throttle(nullptr); | 89 AncestorThrottle throttle(nullptr); |
| 84 for (const auto& test : cases) { | 90 for (const auto& test : cases) { |
| 85 SCOPED_TRACE(test.header); | 91 SCOPED_TRACE(test.header); |
| 86 scoped_refptr<net::HttpResponseHeaders> headers = | 92 scoped_refptr<net::HttpResponseHeaders> headers = |
| 87 GetAncestorHeaders(test.header, nullptr); | 93 GetAncestorHeaders(test.header, nullptr, nullptr); |
| 88 std::string header_value; | 94 std::string header_value; |
| 89 EXPECT_EQ(test.expected, | 95 EXPECT_EQ(test.expected, |
| 90 throttle.ParseHeader(headers.get(), &header_value)); | 96 throttle.ParseHeader(headers.get(), &header_value)); |
| 91 EXPECT_EQ(test.value, header_value); | 97 EXPECT_EQ(test.value, header_value); |
| 92 } | 98 } |
| 93 } | 99 } |
| 94 | 100 |
| 95 TEST_F(AncestorThrottleTest, ErrorsParsingXFrameOptions) { | 101 TEST_F(AncestorThrottleTest, ErrorsParsingXFrameOptions) { |
| 96 struct TestCase { | 102 struct TestCase { |
| 97 const char* header; | 103 const char* header; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 112 {"DENY,ALLOWALL", HeaderDisposition::CONFLICT, "DENY, ALLOWALL"}, | 118 {"DENY,ALLOWALL", HeaderDisposition::CONFLICT, "DENY, ALLOWALL"}, |
| 113 {"SAMEORIGIN,DENY", HeaderDisposition::CONFLICT, "SAMEORIGIN, DENY"}, | 119 {"SAMEORIGIN,DENY", HeaderDisposition::CONFLICT, "SAMEORIGIN, DENY"}, |
| 114 {"ALLOWALL,SAMEORIGIN", HeaderDisposition::CONFLICT, | 120 {"ALLOWALL,SAMEORIGIN", HeaderDisposition::CONFLICT, |
| 115 "ALLOWALL, SAMEORIGIN"}, | 121 "ALLOWALL, SAMEORIGIN"}, |
| 116 {"DENY, SAMEORIGIN", HeaderDisposition::CONFLICT, "DENY, SAMEORIGIN"}}; | 122 {"DENY, SAMEORIGIN", HeaderDisposition::CONFLICT, "DENY, SAMEORIGIN"}}; |
| 117 | 123 |
| 118 AncestorThrottle throttle(nullptr); | 124 AncestorThrottle throttle(nullptr); |
| 119 for (const auto& test : cases) { | 125 for (const auto& test : cases) { |
| 120 SCOPED_TRACE(test.header); | 126 SCOPED_TRACE(test.header); |
| 121 scoped_refptr<net::HttpResponseHeaders> headers = | 127 scoped_refptr<net::HttpResponseHeaders> headers = |
| 122 GetAncestorHeaders(test.header, nullptr); | 128 GetAncestorHeaders(test.header, nullptr, nullptr); |
| 123 std::string header_value; | 129 std::string header_value; |
| 124 EXPECT_EQ(test.expected, | 130 EXPECT_EQ(test.expected, |
| 125 throttle.ParseHeader(headers.get(), &header_value)); | 131 throttle.ParseHeader(headers.get(), &header_value)); |
| 126 EXPECT_EQ(test.failure, header_value); | 132 EXPECT_EQ(test.failure, header_value); |
| 127 } | 133 } |
| 128 } | 134 } |
| 129 | 135 |
| 130 TEST_F(AncestorThrottleTest, IgnoreWhenFrameAncestorsPresent) { | 136 TEST_F(AncestorThrottleTest, IgnoreWhenFrameAncestorsPresent) { |
| 131 struct TestCase { | 137 struct TestCase { |
| 132 const char* csp; | 138 const char* csp; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 {"policy, frame-ancestors-are-lovely", HeaderDisposition::DENY}, | 171 {"policy, frame-ancestors-are-lovely", HeaderDisposition::DENY}, |
| 166 {"policy, directive1; not-frame-ancestors *", HeaderDisposition::DENY}, | 172 {"policy, directive1; not-frame-ancestors *", HeaderDisposition::DENY}, |
| 167 {"policy, directive1; frame-ancestors-are-lovely", | 173 {"policy, directive1; frame-ancestors-are-lovely", |
| 168 HeaderDisposition::DENY}, | 174 HeaderDisposition::DENY}, |
| 169 }; | 175 }; |
| 170 | 176 |
| 171 AncestorThrottle throttle(nullptr); | 177 AncestorThrottle throttle(nullptr); |
| 172 for (const auto& test : cases) { | 178 for (const auto& test : cases) { |
| 173 SCOPED_TRACE(test.csp); | 179 SCOPED_TRACE(test.csp); |
| 174 scoped_refptr<net::HttpResponseHeaders> headers = | 180 scoped_refptr<net::HttpResponseHeaders> headers = |
| 175 GetAncestorHeaders("DENY", test.csp); | 181 GetAncestorHeaders("DENY", test.csp, nullptr); |
| 176 std::string header_value; | 182 std::string header_value; |
| 177 EXPECT_EQ(test.expected, | 183 EXPECT_EQ(test.expected, |
| 178 throttle.ParseHeader(headers.get(), &header_value)); | 184 throttle.ParseHeader(headers.get(), &header_value)); |
| 185 EXPECT_EQ("DENY", header_value); |
| 186 } |
| 187 } |
| 188 |
| 189 TEST_F(AncestorThrottleTest, IgnoreWhenAttachment) { |
| 190 struct TestCase { |
| 191 const char* disposition; |
| 192 AncestorThrottle::HeaderDisposition expected; |
| 193 } cases[] = {{"", HeaderDisposition::DENY}, |
| 194 {"attachment", HeaderDisposition::BYPASS}, |
| 195 {"inline", HeaderDisposition::DENY}, |
| 196 {"invalid", HeaderDisposition::BYPASS}}; |
| 197 |
| 198 AncestorThrottle throttle(nullptr); |
| 199 for (const auto& test : cases) { |
| 200 SCOPED_TRACE(test.disposition); |
| 201 scoped_refptr<net::HttpResponseHeaders> headers = |
| 202 GetAncestorHeaders("DENY", nullptr, test.disposition); |
| 203 std::string header_value; |
| 204 EXPECT_EQ(test.expected, |
| 205 throttle.ParseHeader(headers.get(), &header_value)); |
| 179 EXPECT_EQ("DENY", header_value); | 206 EXPECT_EQ("DENY", header_value); |
| 180 } | 207 } |
| 181 } | 208 } |
| 182 | 209 |
| 183 } // namespace content | 210 } // namespace content |
| OLD | NEW |