OLD | NEW |
---|---|
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 "components/subresource_filter/content/browser/subresource_filter_safe_ browsing_activation_throttle.h" | 5 #include "components/subresource_filter/content/browser/subresource_filter_safe_ browsing_activation_throttle.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
26 | 26 |
27 namespace subresource_filter { | 27 namespace subresource_filter { |
28 | 28 |
29 namespace { | 29 namespace { |
30 | 30 |
31 char kURL[] = "http://example.test/"; | 31 char kURL[] = "http://example.test/"; |
32 char kRedirectURL[] = "http://foo.test/"; | 32 char kRedirectURL[] = "http://foo.test/"; |
33 | 33 |
34 // Names of navigation chain patterns histogram. | 34 // Names of navigation chain patterns histogram. |
35 const char kMatchesPatternHistogramNameSubresourceFilterSuffix[] = | 35 const char kMatchesPatternHistogramName[] = |
36 "SubresourceFilter.PageLoad.RedirectChainMatchPattern." | 36 "SubresourecFilter.PageLoad.FinalURLMatch."; |
engedy
2017/04/26 13:47:10
Same typo here.
melandory
2017/04/26 15:02:21
Done.
| |
37 "SubresourceFilterOnly"; | 37 const char kNavigationChainSize[] = |
38 const char kNavigationChainSizeSubresourceFilterSuffix[] = | 38 "SubresourceFilter.PageLoad.RedirectChainLength."; |
39 "SubresourceFilter.PageLoad.RedirectChainLength.SubresourceFilterOnly"; | |
40 | |
41 // Human readable representation of expected redirect chain match patterns. | |
42 // The explanations for the buckets given for the following redirect chain: | |
43 // A->B->C->D, where A is initial URL and D is a final URL. | |
44 enum RedirectChainMatchPattern { | |
45 EMPTY, // No histograms were recorded. | |
46 F0M0L1, // D is a Safe Browsing match. | |
47 F0M1L0, // B or C, or both are Safe Browsing matches. | |
48 F0M1L1, // B or C, or both and D are Safe Browsing matches. | |
49 F1M0L0, // A is Safe Browsing match | |
50 F1M0L1, // A and D are Safe Browsing matches. | |
51 F1M1L0, // B and/or C and A are Safe Browsing matches. | |
52 F1M1L1, // B and/or C and A and D are Safe Browsing matches. | |
53 NO_REDIRECTS_HIT, // Redirect chain consists of single URL, aka no redirects | |
54 // has happened, and this URL was a Safe Browsing hit. | |
55 NUM_HIT_PATTERNS, | |
56 }; | |
57 | 39 |
58 class MockSubresourceFilterClient | 40 class MockSubresourceFilterClient |
59 : public subresource_filter::SubresourceFilterClient { | 41 : public subresource_filter::SubresourceFilterClient { |
60 public: | 42 public: |
61 MockSubresourceFilterClient() {} | 43 MockSubresourceFilterClient() {} |
62 | 44 |
63 ~MockSubresourceFilterClient() override = default; | 45 ~MockSubresourceFilterClient() override = default; |
64 | 46 |
65 MOCK_METHOD1(ToggleNotificationVisibility, void(bool)); | 47 MOCK_METHOD1(ToggleNotificationVisibility, void(bool)); |
66 MOCK_METHOD1(ShouldSuppressActivation, bool(content::NavigationHandle*)); | 48 MOCK_METHOD1(ShouldSuppressActivation, bool(content::NavigationHandle*)); |
(...skipping 23 matching lines...) Expand all Loading... | |
90 return content::NavigationThrottle::PROCEED; | 72 return content::NavigationThrottle::PROCEED; |
91 } | 73 } |
92 const char* GetNameForLogging() override { | 74 const char* GetNameForLogging() override { |
93 return "TestForwardingNavigationThrottle"; | 75 return "TestForwardingNavigationThrottle"; |
94 } | 76 } |
95 | 77 |
96 private: | 78 private: |
97 DISALLOW_COPY_AND_ASSIGN(TestForwardingNavigationThrottle); | 79 DISALLOW_COPY_AND_ASSIGN(TestForwardingNavigationThrottle); |
98 }; | 80 }; |
99 | 81 |
82 std::string GetSuffixForList(const ActivationList& type) { | |
83 switch (type) { | |
84 case ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL: | |
85 return "SocialEngineeringAdsInterstitial"; | |
86 case ActivationList::PHISHING_INTERSTITIAL: | |
87 return "PhishingInterstital"; | |
88 case ActivationList::SUBRESOURCE_FILTER: | |
89 return "SubresourceFilterOnly"; | |
90 case ActivationList::NONE: | |
91 return std::string(); | |
92 } | |
93 return std::string(); | |
94 } | |
95 | |
96 struct ActivationListTestData { | |
97 const char* const activation_list; | |
98 ActivationList activation_list_type; | |
99 safe_browsing::SBThreatType threat_type; | |
100 safe_browsing::ThreatPatternType threat_type_metadata; | |
101 }; | |
102 | |
103 const ActivationListTestData kActivationListTestData[] = { | |
104 {subresource_filter::kActivationListSocialEngineeringAdsInterstitial, | |
105 ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL, | |
106 safe_browsing::SB_THREAT_TYPE_URL_PHISHING, | |
107 safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS}, | |
108 {subresource_filter::kActivationListPhishingInterstitial, | |
109 ActivationList::PHISHING_INTERSTITIAL, | |
110 safe_browsing::SB_THREAT_TYPE_URL_PHISHING, | |
111 safe_browsing::ThreatPatternType::NONE}, | |
112 {subresource_filter::kActivationListSubresourceFilter, | |
113 ActivationList::SUBRESOURCE_FILTER, | |
114 safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, | |
115 safe_browsing::ThreatPatternType::NONE}, | |
116 }; | |
117 | |
118 void ExpectSampleForSuffix(const std::string& suffix, | |
engedy
2017/04/26 13:47:10
nit: This method is a bit hard to understand. How
| |
119 const std::string& match_suffix, | |
120 const base::HistogramTester& tester) { | |
121 tester.ExpectUniqueSample(kMatchesPatternHistogramName + suffix, | |
122 (suffix == match_suffix), 1); | |
123 } | |
124 | |
100 } // namespace | 125 } // namespace |
101 | 126 |
102 class SubresourceFilterSafeBrowsingActivationThrottleTest | 127 class SubresourceFilterSafeBrowsingActivationThrottleTest |
103 : public content::RenderViewHostTestHarness, | 128 : public content::RenderViewHostTestHarness, |
104 public content::WebContentsObserver { | 129 public content::WebContentsObserver, |
130 public ::testing::WithParamInterface<ActivationListTestData> { | |
105 public: | 131 public: |
106 SubresourceFilterSafeBrowsingActivationThrottleTest() | 132 SubresourceFilterSafeBrowsingActivationThrottleTest() |
107 : field_trial_list_(nullptr) {} | 133 : field_trial_list_(nullptr) {} |
108 ~SubresourceFilterSafeBrowsingActivationThrottleTest() override {} | 134 ~SubresourceFilterSafeBrowsingActivationThrottleTest() override {} |
109 | 135 |
110 void SetUp() override { | 136 void SetUp() override { |
111 content::RenderViewHostTestHarness::SetUp(); | 137 content::RenderViewHostTestHarness::SetUp(); |
138 const ActivationListTestData& test_data = GetParam(); | |
112 scoped_feature_toggle_.reset( | 139 scoped_feature_toggle_.reset( |
113 new testing::ScopedSubresourceFilterFeatureToggle( | 140 new testing::ScopedSubresourceFilterFeatureToggle( |
114 base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled, | 141 base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled, |
115 kActivationScopeActivationList, kActivationListSubresourceFilter)); | 142 kActivationScopeActivationList, test_data.activation_list)); |
116 // Note: Using NiceMock to allow uninteresting calls and suppress warnings. | 143 // Note: Using NiceMock to allow uninteresting calls and suppress warnings. |
117 auto client = | 144 auto client = |
118 base::MakeUnique<::testing::NiceMock<MockSubresourceFilterClient>>(); | 145 base::MakeUnique<::testing::NiceMock<MockSubresourceFilterClient>>(); |
119 ContentSubresourceFilterDriverFactory::CreateForWebContents( | 146 ContentSubresourceFilterDriverFactory::CreateForWebContents( |
120 RenderViewHostTestHarness::web_contents(), std::move(client)); | 147 RenderViewHostTestHarness::web_contents(), std::move(client)); |
121 fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager(); | 148 fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager(); |
122 NavigateAndCommit(GURL("https://test.com")); | 149 NavigateAndCommit(GURL("https://test.com")); |
123 Observe(RenderViewHostTestHarness::web_contents()); | 150 Observe(RenderViewHostTestHarness::web_contents()); |
124 } | 151 } |
125 | 152 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 EXPECT_EQ(content::NavigationThrottle::PROCEED, | 184 EXPECT_EQ(content::NavigationThrottle::PROCEED, |
158 navigation_simulator_->GetLastThrottleCheckResult()); | 185 navigation_simulator_->GetLastThrottleCheckResult()); |
159 } | 186 } |
160 | 187 |
161 void CreateTestNavigationForMainFrame(const GURL& first_url) { | 188 void CreateTestNavigationForMainFrame(const GURL& first_url) { |
162 navigation_simulator_ = | 189 navigation_simulator_ = |
163 content::NavigationSimulator::CreateRendererInitiated(first_url, | 190 content::NavigationSimulator::CreateRendererInitiated(first_url, |
164 main_rfh()); | 191 main_rfh()); |
165 } | 192 } |
166 | 193 |
167 void ConfigureAsSubresourceFilterOnlyURL(const GURL& url) { | 194 void ConfigureForMatch(const GURL& url) { |
195 const ActivationListTestData& test_data = GetParam(); | |
168 fake_safe_browsing_database_->AddBlacklistedUrl( | 196 fake_safe_browsing_database_->AddBlacklistedUrl( |
169 url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER); | 197 url, test_data.threat_type, test_data.threat_type_metadata); |
170 } | 198 } |
171 | 199 |
172 void SimulateTimeout() { fake_safe_browsing_database_->SimulateTimeout(); } | 200 void SimulateTimeout() { fake_safe_browsing_database_->SimulateTimeout(); } |
173 | 201 |
174 const base::HistogramTester& tester() const { return tester_; } | 202 const base::HistogramTester& tester() const { return tester_; } |
175 | 203 |
176 private: | 204 private: |
177 base::FieldTrialList field_trial_list_; | 205 base::FieldTrialList field_trial_list_; |
178 std::unique_ptr<testing::ScopedSubresourceFilterFeatureToggle> | 206 std::unique_ptr<testing::ScopedSubresourceFilterFeatureToggle> |
179 scoped_feature_toggle_; | 207 scoped_feature_toggle_; |
180 std::unique_ptr<content::NavigationSimulator> navigation_simulator_; | 208 std::unique_ptr<content::NavigationSimulator> navigation_simulator_; |
181 scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_; | 209 scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_; |
182 base::HistogramTester tester_; | 210 base::HistogramTester tester_; |
183 content::NavigationHandle* navigation_handle_; | 211 content::NavigationHandle* navigation_handle_; |
184 | 212 |
185 DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingActivationThrottleTest); | 213 DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingActivationThrottleTest); |
186 }; | 214 }; |
187 | 215 |
188 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, | 216 TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTest, |
189 ListNotMatched_NoActivation) { | 217 ListNotMatched_NoActivation) { |
218 const ActivationListTestData& test_data = GetParam(); | |
190 const GURL url(kURL); | 219 const GURL url(kURL); |
220 const std::string suffix(GetSuffixForList(test_data.activation_list_type)); | |
191 CreateTestNavigationForMainFrame(url); | 221 CreateTestNavigationForMainFrame(url); |
192 SimulateStartAndExpectProceed(); | 222 SimulateStartAndExpectProceed(); |
193 SimulateCommitAndExpectProceed(); | 223 SimulateCommitAndExpectProceed(); |
194 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision:: | 224 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision:: |
195 ACTIVATION_LIST_NOT_MATCHED, | 225 ACTIVATION_LIST_NOT_MATCHED, |
196 factory()->GetActivationDecisionForLastCommittedPageLoad()); | 226 factory()->GetActivationDecisionForLastCommittedPageLoad()); |
197 tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix, | 227 ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", std::string(), |
198 0); | 228 tester()); |
199 tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0); | 229 ExpectSampleForSuffix("PhishingInterstital", std::string(), tester()); |
230 ExpectSampleForSuffix("SubresourceFilterOnly", std::string(), tester()); | |
231 | |
232 tester().ExpectTotalCount(kNavigationChainSize + suffix, 0); | |
200 } | 233 } |
201 | 234 |
202 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, | 235 TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTest, |
203 ListMatched_Activation) { | 236 ListMatched_Activation) { |
237 const ActivationListTestData& test_data = GetParam(); | |
204 const GURL url(kURL); | 238 const GURL url(kURL); |
205 ConfigureAsSubresourceFilterOnlyURL(url); | 239 const std::string suffix(GetSuffixForList(test_data.activation_list_type)); |
240 ConfigureForMatch(url); | |
206 CreateTestNavigationForMainFrame(url); | 241 CreateTestNavigationForMainFrame(url); |
207 SimulateStartAndExpectProceed(); | 242 SimulateStartAndExpectProceed(); |
208 SimulateCommitAndExpectProceed(); | 243 SimulateCommitAndExpectProceed(); |
209 EXPECT_EQ( | 244 EXPECT_EQ( |
210 ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED, | 245 ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED, |
211 factory()->GetActivationDecisionForLastCommittedPageLoad()); | 246 factory()->GetActivationDecisionForLastCommittedPageLoad()); |
212 tester().ExpectUniqueSample( | 247 ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", suffix, tester()); |
213 kMatchesPatternHistogramNameSubresourceFilterSuffix, NO_REDIRECTS_HIT, 1); | 248 ExpectSampleForSuffix("PhishingInterstital", suffix, tester()); |
214 tester().ExpectUniqueSample(kNavigationChainSizeSubresourceFilterSuffix, 1, | 249 ExpectSampleForSuffix("SubresourceFilterOnly", suffix, tester()); |
215 1); | 250 tester().ExpectUniqueSample(kNavigationChainSize + suffix, 1, 1); |
216 } | 251 } |
217 | 252 |
218 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, | 253 TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTest, |
219 ListNotMatchedAfterRedirect_NoActivation) { | 254 ListNotMatchedAfterRedirect_NoActivation) { |
255 const ActivationListTestData& test_data = GetParam(); | |
220 const GURL url(kURL); | 256 const GURL url(kURL); |
257 const std::string suffix(GetSuffixForList(test_data.activation_list_type)); | |
221 CreateTestNavigationForMainFrame(url); | 258 CreateTestNavigationForMainFrame(url); |
222 SimulateStartAndExpectProceed(); | 259 SimulateStartAndExpectProceed(); |
223 SimulateRedirectAndExpectProceed(GURL(kRedirectURL)); | 260 SimulateRedirectAndExpectProceed(GURL(kRedirectURL)); |
224 SimulateCommitAndExpectProceed(); | 261 SimulateCommitAndExpectProceed(); |
225 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision:: | 262 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision:: |
226 ACTIVATION_LIST_NOT_MATCHED, | 263 ACTIVATION_LIST_NOT_MATCHED, |
227 factory()->GetActivationDecisionForLastCommittedPageLoad()); | 264 factory()->GetActivationDecisionForLastCommittedPageLoad()); |
228 tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix, | 265 ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", std::string(), |
229 0); | 266 tester()); |
230 tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0); | 267 ExpectSampleForSuffix("PhishingInterstital", std::string(), tester()); |
268 ExpectSampleForSuffix("SubresourceFilterOnly", std::string(), tester()); | |
269 tester().ExpectTotalCount(kNavigationChainSize + suffix, 0); | |
231 } | 270 } |
232 | 271 |
233 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, | 272 TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTest, |
234 ListMatchedAfterRedirect_Activation) { | 273 ListMatchedAfterRedirect_Activation) { |
274 const ActivationListTestData& test_data = GetParam(); | |
235 const GURL url(kURL); | 275 const GURL url(kURL); |
236 ConfigureAsSubresourceFilterOnlyURL(GURL(kRedirectURL)); | 276 const std::string suffix(GetSuffixForList(test_data.activation_list_type)); |
277 ConfigureForMatch(GURL(kRedirectURL)); | |
237 CreateTestNavigationForMainFrame(url); | 278 CreateTestNavigationForMainFrame(url); |
238 SimulateStartAndExpectProceed(); | 279 SimulateStartAndExpectProceed(); |
239 SimulateRedirectAndExpectProceed(GURL(kRedirectURL)); | 280 SimulateRedirectAndExpectProceed(GURL(kRedirectURL)); |
240 SimulateCommitAndExpectProceed(); | 281 SimulateCommitAndExpectProceed(); |
241 EXPECT_EQ( | 282 EXPECT_EQ( |
242 ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED, | 283 ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED, |
243 factory()->GetActivationDecisionForLastCommittedPageLoad()); | 284 factory()->GetActivationDecisionForLastCommittedPageLoad()); |
244 tester().ExpectUniqueSample( | 285 tester().ExpectUniqueSample(kNavigationChainSize + suffix, 2, 1); |
245 kMatchesPatternHistogramNameSubresourceFilterSuffix, F0M0L1, 1); | 286 ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", suffix, tester()); |
246 tester().ExpectUniqueSample(kNavigationChainSizeSubresourceFilterSuffix, 2, | 287 ExpectSampleForSuffix("PhishingInterstital", suffix, tester()); |
247 1); | 288 ExpectSampleForSuffix("SubresourceFilterOnly", suffix, tester()); |
248 } | 289 } |
249 | 290 |
250 TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, | 291 TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTest, |
251 ListNotMatchedAndTimeout_NoActivation) { | 292 ListNotMatchedAndTimeout_NoActivation) { |
293 const ActivationListTestData& test_data = GetParam(); | |
252 const GURL url(kURL); | 294 const GURL url(kURL); |
295 const std::string suffix(GetSuffixForList(test_data.activation_list_type)); | |
253 SimulateTimeout(); | 296 SimulateTimeout(); |
254 CreateTestNavigationForMainFrame(url); | 297 CreateTestNavigationForMainFrame(url); |
255 SimulateStartAndExpectProceed(); | 298 SimulateStartAndExpectProceed(); |
256 SimulateCommitAndExpectProceed(); | 299 SimulateCommitAndExpectProceed(); |
257 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision:: | 300 EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision:: |
258 ACTIVATION_LIST_NOT_MATCHED, | 301 ACTIVATION_LIST_NOT_MATCHED, |
259 factory()->GetActivationDecisionForLastCommittedPageLoad()); | 302 factory()->GetActivationDecisionForLastCommittedPageLoad()); |
260 tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix, | 303 ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", std::string(), |
261 0); | 304 tester()); |
262 tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0); | 305 ExpectSampleForSuffix("PhishingInterstital", std::string(), tester()); |
306 ExpectSampleForSuffix("SubresourceFilterOnly", std::string(), tester()); | |
307 tester().ExpectTotalCount(kNavigationChainSize + suffix, 0); | |
263 } | 308 } |
264 | 309 |
265 // TODO(melandory): Once non-defering check in WillStart is implemented add one | 310 // TODO(melandory): Once non-defering check in WillStart is implemented add one |
266 // more test that destroys the Navigation along with corresponding throttles | 311 // more test that destroys the Navigation along with corresponding throttles |
267 // while the SB check is pending? (To be run by ASAN bots to ensure | 312 // while the SB check is pending? (To be run by ASAN bots to ensure |
268 // no use-after-free.) | 313 // no use-after-free.) |
269 | 314 |
315 INSTANTIATE_TEST_CASE_P(ActivationLevelTest, | |
316 SubresourceFilterSafeBrowsingActivationThrottleTest, | |
317 ::testing::ValuesIn(kActivationListTestData)); | |
318 | |
270 } // namespace subresource_filter | 319 } // namespace subresource_filter |
OLD | NEW |