Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: content/common/content_security_policy/csp_context_unittest.cc

Issue 2893613002: PlzNavigate: Fix "Only one CSP is reported instead of several". (Closed)
Patch Set: Rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 6
7 #include "content/common/content_security_policy/csp_context.h" 7 #include "content/common/content_security_policy/csp_context.h"
8 #include "content/common/content_security_policy_header.h" 8 #include "content/common/content_security_policy_header.h"
9 #include "content/common/navigation_params.h" 9 #include "content/common/navigation_params.h"
10 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
11 11
12 namespace content { 12 namespace content {
13 13
14 namespace { 14 namespace {
15 15
16 class CSPContextTest : public CSPContext { 16 class CSPContextTest : public CSPContext {
17 public: 17 public:
18 const CSPViolationParams& last_violation() { return last_violation_; } 18 const std::vector<CSPViolationParams>& violations() { return violations_; }
19 19
20 void AddSchemeToBypassCSP(const std::string& scheme) { 20 void AddSchemeToBypassCSP(const std::string& scheme) {
21 scheme_to_bypass_.insert(scheme); 21 scheme_to_bypass_.insert(scheme);
22 } 22 }
23 23
24 bool SchemeShouldBypassCSP(const base::StringPiece& scheme) override { 24 bool SchemeShouldBypassCSP(const base::StringPiece& scheme) override {
25 return scheme_to_bypass_.count(scheme.as_string()); 25 return scheme_to_bypass_.count(scheme.as_string());
26 } 26 }
27 27
28 void set_sanitize_data_for_use_in_csp_violation(bool value) { 28 void set_sanitize_data_for_use_in_csp_violation(bool value) {
29 sanitize_data_for_use_in_csp_violation_ = value; 29 sanitize_data_for_use_in_csp_violation_ = value;
30 } 30 }
31 31
32 void SanitizeDataForUseInCspViolation( 32 void SanitizeDataForUseInCspViolation(
33 bool is_redirect, 33 bool is_redirect,
34 CSPDirective::Name directive, 34 CSPDirective::Name directive,
35 GURL* blocked_url, 35 GURL* blocked_url,
36 SourceLocation* source_location) const override { 36 SourceLocation* source_location) const override {
37 if (!sanitize_data_for_use_in_csp_violation_) 37 if (!sanitize_data_for_use_in_csp_violation_)
38 return; 38 return;
39 *blocked_url = blocked_url->GetOrigin(); 39 *blocked_url = blocked_url->GetOrigin();
40 *source_location = 40 *source_location =
41 SourceLocation(GURL(source_location->url).GetOrigin().spec(), 0u, 0u); 41 SourceLocation(GURL(source_location->url).GetOrigin().spec(), 0u, 0u);
42 } 42 }
43 43
44 private: 44 private:
45 void ReportContentSecurityPolicyViolation( 45 void ReportContentSecurityPolicyViolation(
46 const CSPViolationParams& violation_params) override { 46 const CSPViolationParams& violation_params) override {
47 last_violation_ = violation_params; 47 violations_.push_back(violation_params);
48 } 48 }
49 CSPViolationParams last_violation_; 49 std::vector<CSPViolationParams> violations_;
50 std::set<std::string> scheme_to_bypass_; 50 std::set<std::string> scheme_to_bypass_;
51 bool sanitize_data_for_use_in_csp_violation_ = false; 51 bool sanitize_data_for_use_in_csp_violation_ = false;
52 }; 52 };
53 53
54 // Build a new policy made of only one directive and no report endpoints. 54 // Build a new policy made of only one directive and no report endpoints.
55 ContentSecurityPolicy BuildPolicy(CSPDirective::Name directive_name, 55 ContentSecurityPolicy BuildPolicy(CSPDirective::Name directive_name,
56 std::vector<CSPSource> sources) { 56 std::vector<CSPSource> sources) {
57 return ContentSecurityPolicy( 57 return ContentSecurityPolicy(
58 ContentSecurityPolicyHeader(std::string(), // header 58 ContentSecurityPolicyHeader(std::string(), // header
59 blink::kWebContentSecurityPolicyTypeEnforce, 59 blink::kWebContentSecurityPolicyTypeEnforce,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 {CSPSource("", "a.com", false, url::PORT_UNSPECIFIED, false, 114 {CSPSource("", "a.com", false, url::PORT_UNSPECIFIED, false,
115 "/iframe")})); 115 "/iframe")}));
116 116
117 GURL blocked_url("http://a.com/login?password=1234"); 117 GURL blocked_url("http://a.com/login?password=1234");
118 SourceLocation source_location("http://a.com/login", 10u, 20u); 118 SourceLocation source_location("http://a.com/login", 10u, 20u);
119 119
120 // When the |blocked_url| and |source_location| aren't sensitive information. 120 // When the |blocked_url| and |source_location| aren't sensitive information.
121 { 121 {
122 EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, blocked_url, 122 EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, blocked_url,
123 false, source_location)); 123 false, source_location));
124 EXPECT_EQ(context.last_violation().blocked_url, blocked_url); 124 ASSERT_EQ(1u, context.violations().size());
125 EXPECT_EQ(context.last_violation().source_location.url, 125 EXPECT_EQ(context.violations()[0].blocked_url, blocked_url);
126 EXPECT_EQ(context.violations()[0].source_location.url,
126 "http://a.com/login"); 127 "http://a.com/login");
127 EXPECT_EQ(context.last_violation().source_location.line_number, 10u); 128 EXPECT_EQ(context.violations()[0].source_location.line_number, 10u);
128 EXPECT_EQ(context.last_violation().source_location.column_number, 20u); 129 EXPECT_EQ(context.violations()[0].source_location.column_number, 20u);
129 EXPECT_EQ(context.last_violation().console_message, 130 EXPECT_EQ(context.violations()[0].console_message,
130 "Refused to frame 'http://a.com/login?password=1234' because it " 131 "Refused to frame 'http://a.com/login?password=1234' because it "
131 "violates the following Content Security Policy directive: " 132 "violates the following Content Security Policy directive: "
132 "\"frame-src a.com/iframe\".\n"); 133 "\"frame-src a.com/iframe\".\n");
133 } 134 }
134 135
135 context.set_sanitize_data_for_use_in_csp_violation(true); 136 context.set_sanitize_data_for_use_in_csp_violation(true);
136 137
137 // When the |blocked_url| and |source_location| are sensitive information. 138 // When the |blocked_url| and |source_location| are sensitive information.
138 { 139 {
139 EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, blocked_url, 140 EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, blocked_url,
140 false, source_location)); 141 false, source_location));
141 EXPECT_EQ(context.last_violation().blocked_url, blocked_url.GetOrigin()); 142 ASSERT_EQ(2u, context.violations().size());
142 EXPECT_EQ(context.last_violation().source_location.url, "http://a.com/"); 143 EXPECT_EQ(context.violations()[1].blocked_url, blocked_url.GetOrigin());
143 EXPECT_EQ(context.last_violation().source_location.line_number, 0u); 144 EXPECT_EQ(context.violations()[1].source_location.url, "http://a.com/");
144 EXPECT_EQ(context.last_violation().source_location.column_number, 0u); 145 EXPECT_EQ(context.violations()[1].source_location.line_number, 0u);
145 EXPECT_EQ(context.last_violation().console_message, 146 EXPECT_EQ(context.violations()[1].source_location.column_number, 0u);
147 EXPECT_EQ(context.violations()[1].console_message,
146 "Refused to frame 'http://a.com/' because it violates the " 148 "Refused to frame 'http://a.com/' because it violates the "
147 "following Content Security Policy directive: \"frame-src " 149 "following Content Security Policy directive: \"frame-src "
148 "a.com/iframe\".\n"); 150 "a.com/iframe\".\n");
149 } 151 }
150 } 152 }
151 153
154 // When several policies are infringed, all of them must be reported.
155 TEST(CSPContextTest, MultipleInfringement) {
156 CSPContextTest context;
157 context.SetSelf(url::Origin(GURL("http://example.com")));
158
159 CSPSource source_a("", "a.com", false, url::PORT_UNSPECIFIED, false, "");
160 CSPSource source_b("", "b.com", false, url::PORT_UNSPECIFIED, false, "");
161 CSPSource source_c("", "c.com", false, url::PORT_UNSPECIFIED, false, "");
162
163 context.AddContentSecurityPolicy(
164 BuildPolicy(CSPDirective::FrameSrc, {source_a}));
165 context.AddContentSecurityPolicy(
166 BuildPolicy(CSPDirective::FrameSrc, {source_b}));
167 context.AddContentSecurityPolicy(
168 BuildPolicy(CSPDirective::FrameSrc, {source_c}));
169
170 EXPECT_FALSE(context.IsAllowedByCsp(
171 CSPDirective::FrameSrc, GURL("http://c.com"), false, SourceLocation()));
172 ASSERT_EQ(2u, context.violations().size());
173 const char console_message_a[] =
174 "Refused to frame 'http://c.com/' because it violates the following "
175 "Content Security Policy directive: \"frame-src a.com\".\n";
176 const char console_message_b[] =
177 "Refused to frame 'http://c.com/' because it violates the following "
178 "Content Security Policy directive: \"frame-src b.com\".\n";
179 EXPECT_EQ(console_message_a, context.violations()[0].console_message);
180 EXPECT_EQ(console_message_b, context.violations()[1].console_message);
181 }
182
152 } // namespace content 183 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698