Chromium Code Reviews| 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 "components/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h" | 5 #include "components/subresource_filter/content/browser/content_subresource_filt er_driver_factory.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "components/subresource_filter/content/browser/subresource_filter_clien t.h" | 10 #include "components/subresource_filter/content/browser/subresource_filter_clien t.h" |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 // ThreadTicks is supported, otherwise returns false. | 34 // ThreadTicks is supported, otherwise returns false. |
| 35 bool ShouldMeasurePerformanceForPageLoad() { | 35 bool ShouldMeasurePerformanceForPageLoad() { |
| 36 if (!base::ThreadTicks::IsSupported()) | 36 if (!base::ThreadTicks::IsSupported()) |
| 37 return false; | 37 return false; |
| 38 // TODO(pkalinnikov): Cache |rate| and other variation params in | 38 // TODO(pkalinnikov): Cache |rate| and other variation params in |
| 39 // ContentSubresourceFilterDriverFactory. | 39 // ContentSubresourceFilterDriverFactory. |
| 40 const double rate = GetPerformanceMeasurementRate(); | 40 const double rate = GetPerformanceMeasurementRate(); |
| 41 return rate == 1 || (rate > 0 && base::RandDouble() < rate); | 41 return rate == 1 || (rate > 0 && base::RandDouble() < rate); |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Macro for UMA reporting of histograms which track data to understand | |
|
engedy
2017/03/14 10:10:20
Phrasing nit:
// Records histograms about the le
melandory
2017/03/14 15:51:55
Done.
| |
| 45 // different redirect patterns. | |
| 46 #define REPORT_REDIRECT_PATTERN_FOR_SUFFIX(suffix, hits_pattern, chain_size) \ | |
| 47 do { \ | |
| 48 UMA_HISTOGRAM_ENUMERATION( \ | |
| 49 "SubresourceFilter.PageLoad.RedirectChainMatchPattern." suffix, \ | |
| 50 hits_pattern, 0x10); \ | |
| 51 UMA_HISTOGRAM_COUNTS( \ | |
| 52 "SubresourceFilter.PageLoad.RedirectChainLength." suffix, chain_size); \ | |
| 53 } while (0) | |
| 54 | |
| 44 } // namespace | 55 } // namespace |
| 45 | 56 |
| 46 // static | 57 // static |
| 47 void ContentSubresourceFilterDriverFactory::CreateForWebContents( | 58 void ContentSubresourceFilterDriverFactory::CreateForWebContents( |
| 48 content::WebContents* web_contents, | 59 content::WebContents* web_contents, |
| 49 std::unique_ptr<SubresourceFilterClient> client) { | 60 std::unique_ptr<SubresourceFilterClient> client) { |
| 50 if (FromWebContents(web_contents)) | 61 if (FromWebContents(web_contents)) |
| 51 return; | 62 return; |
| 52 web_contents->SetUserData(kWebContentsUserDataKey, | 63 web_contents->SetUserData(kWebContentsUserDataKey, |
| 53 new ContentSubresourceFilterDriverFactory( | 64 new ContentSubresourceFilterDriverFactory( |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 const GURL& url) const { | 124 const GURL& url) const { |
| 114 return whitelisted_hosts_.find(url.host()) != whitelisted_hosts_.end(); | 125 return whitelisted_hosts_.find(url.host()) != whitelisted_hosts_.end(); |
| 115 } | 126 } |
| 116 | 127 |
| 117 void ContentSubresourceFilterDriverFactory:: | 128 void ContentSubresourceFilterDriverFactory:: |
| 118 OnMainResourceMatchedSafeBrowsingBlacklist( | 129 OnMainResourceMatchedSafeBrowsingBlacklist( |
| 119 const GURL& url, | 130 const GURL& url, |
| 120 const std::vector<GURL>& redirect_urls, | 131 const std::vector<GURL>& redirect_urls, |
| 121 safe_browsing::SBThreatType threat_type, | 132 safe_browsing::SBThreatType threat_type, |
| 122 safe_browsing::ThreatPatternType threat_type_metadata) { | 133 safe_browsing::ThreatPatternType threat_type_metadata) { |
| 123 bool is_phishing_interstitial = | 134 AddActivationListMatch( |
| 124 (threat_type == safe_browsing::SB_THREAT_TYPE_URL_PHISHING); | 135 url, GetListForThreatTypeAndMetadata(threat_type, threat_type_metadata)); |
| 125 bool is_soc_engineering_ads_interstitial = | |
| 126 threat_type_metadata == | |
| 127 safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS; | |
| 128 | |
| 129 if (is_phishing_interstitial) { | |
| 130 if (is_soc_engineering_ads_interstitial) { | |
| 131 AddActivationListMatch(url, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL); | |
| 132 } | |
| 133 AddActivationListMatch(url, ActivationList::PHISHING_INTERSTITIAL); | |
|
engedy
2017/03/14 10:10:20
When |is_phishing_interstitial| and |is_soc_engine
melandory
2017/03/14 15:51:55
I think it's better to make the activation calcula
| |
| 134 } | |
| 135 } | 136 } |
| 136 | 137 |
| 137 void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet( | 138 void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet( |
| 138 const GURL& url) { | 139 const GURL& url) { |
| 139 if (url.has_host() && url.SchemeIsHTTPOrHTTPS()) | 140 if (url.has_host() && url.SchemeIsHTTPOrHTTPS()) |
| 140 whitelisted_hosts_.insert(url.host()); | 141 whitelisted_hosts_.insert(url.host()); |
| 141 } | 142 } |
| 142 | 143 |
| 143 ContentSubresourceFilterDriverFactory::ActivationDecision | 144 ContentSubresourceFilterDriverFactory::ActivationDecision |
| 144 ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL( | 145 ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 156 return ActivationDecision::URL_WHITELISTED; | 157 return ActivationDecision::URL_WHITELISTED; |
| 157 | 158 |
| 158 switch (scope) { | 159 switch (scope) { |
| 159 case ActivationScope::ALL_SITES: | 160 case ActivationScope::ALL_SITES: |
| 160 return ActivationDecision::ACTIVATED; | 161 return ActivationDecision::ACTIVATED; |
| 161 case ActivationScope::ACTIVATION_LIST: | 162 case ActivationScope::ACTIVATION_LIST: |
| 162 // The logic to ensure only http/https URLs are activated lives in | 163 // The logic to ensure only http/https URLs are activated lives in |
| 163 // AddActivationListMatch to ensure the activation list only has relevant | 164 // AddActivationListMatch to ensure the activation list only has relevant |
| 164 // entries. | 165 // entries. |
| 165 DCHECK(url.SchemeIsHTTPOrHTTPS() || | 166 DCHECK(url.SchemeIsHTTPOrHTTPS() || |
| 166 !DidURLMatchCurrentActivationList(url)); | 167 !DidURLMatchActivationList(url, GetCurrentActivationList())); |
| 167 return DidURLMatchCurrentActivationList(url) | 168 return DidURLMatchActivationList(url, GetCurrentActivationList()) |
| 168 ? ActivationDecision::ACTIVATED | 169 ? ActivationDecision::ACTIVATED |
| 169 : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED; | 170 : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED; |
| 170 default: | 171 default: |
| 171 return ActivationDecision::ACTIVATION_DISABLED; | 172 return ActivationDecision::ACTIVATION_DISABLED; |
| 172 } | 173 } |
| 173 } | 174 } |
| 174 | 175 |
| 175 void ContentSubresourceFilterDriverFactory::ActivateForFrameHostIfNeeded( | 176 void ContentSubresourceFilterDriverFactory::ActivateForFrameHostIfNeeded( |
| 176 content::RenderFrameHost* render_frame_host, | 177 content::RenderFrameHost* render_frame_host, |
| 177 const GURL& url) { | 178 const GURL& url) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 ResetActivationState(); | 315 ResetActivationState(); |
| 315 return; | 316 return; |
| 316 } | 317 } |
| 317 | 318 |
| 318 activation_level_ = GetMaximumActivationLevel(); | 319 activation_level_ = GetMaximumActivationLevel(); |
| 319 measure_performance_ = activation_level_ != ActivationLevel::DISABLED && | 320 measure_performance_ = activation_level_ != ActivationLevel::DISABLED && |
| 320 ShouldMeasurePerformanceForPageLoad(); | 321 ShouldMeasurePerformanceForPageLoad(); |
| 321 ActivateForFrameHostIfNeeded(render_frame_host, url); | 322 ActivateForFrameHostIfNeeded(render_frame_host, url); |
| 322 } | 323 } |
| 323 | 324 |
| 324 bool ContentSubresourceFilterDriverFactory::DidURLMatchCurrentActivationList( | 325 bool ContentSubresourceFilterDriverFactory::DidURLMatchActivationList( |
| 325 const GURL& url) const { | 326 const GURL& url, |
| 327 ActivationList activation_list) const { | |
| 326 auto match_types = | 328 auto match_types = |
| 327 activation_list_matches_.find(DistillURLToHostAndPath(url)); | 329 activation_list_matches_.find(DistillURLToHostAndPath(url)); |
| 328 return match_types != activation_list_matches_.end() && | 330 return match_types != activation_list_matches_.end() && |
| 329 match_types->second.find(GetCurrentActivationList()) != | 331 match_types->second.find(activation_list) != match_types->second.end(); |
| 330 match_types->second.end(); | |
| 331 } | 332 } |
| 332 | 333 |
| 333 void ContentSubresourceFilterDriverFactory::AddActivationListMatch( | 334 void ContentSubresourceFilterDriverFactory::AddActivationListMatch( |
| 334 const GURL& url, | 335 const GURL& url, |
| 335 ActivationList match_type) { | 336 ActivationList match_type) { |
| 337 if (match_type == ActivationList::NONE) | |
| 338 return; | |
| 336 if (url.has_host() && url.SchemeIsHTTPOrHTTPS()) | 339 if (url.has_host() && url.SchemeIsHTTPOrHTTPS()) |
| 337 activation_list_matches_[DistillURLToHostAndPath(url)].insert(match_type); | 340 activation_list_matches_[DistillURLToHostAndPath(url)].insert(match_type); |
| 338 } | 341 } |
| 339 | 342 |
| 340 void ContentSubresourceFilterDriverFactory::RecordRedirectChainMatchPattern() | 343 int ContentSubresourceFilterDriverFactory::CalculateHitPatternForActivationList( |
| 341 const { | 344 ActivationList activation_list) const { |
| 342 int hits_pattern = 0; | 345 int hits_pattern = 0; |
| 343 const int kInitialURLHitMask = 0x4; | 346 const int kInitialURLHitMask = 0x4; |
| 344 const int kRedirectURLHitMask = 0x2; | 347 const int kRedirectURLHitMask = 0x2; |
| 345 const int kFinalURLHitMask = 0x1; | 348 const int kFinalURLHitMask = 0x1; |
| 346 if (navigation_chain_.size() > 1) { | 349 if (navigation_chain_.size() > 1) { |
| 347 if (DidURLMatchCurrentActivationList(navigation_chain_.back())) | 350 if (DidURLMatchActivationList(navigation_chain_.back(), activation_list)) |
| 348 hits_pattern |= kFinalURLHitMask; | 351 hits_pattern |= kFinalURLHitMask; |
| 349 if (DidURLMatchCurrentActivationList(navigation_chain_.front())) | 352 if (DidURLMatchActivationList(navigation_chain_.front(), activation_list)) |
| 350 hits_pattern |= kInitialURLHitMask; | 353 hits_pattern |= kInitialURLHitMask; |
| 351 | 354 |
| 352 // Examine redirects. | 355 // Examine redirects. |
| 353 for (size_t i = 1; i < navigation_chain_.size() - 1; ++i) { | 356 for (size_t i = 1; i < navigation_chain_.size() - 1; ++i) { |
| 354 if (DidURLMatchCurrentActivationList(navigation_chain_[i])) { | 357 if (DidURLMatchActivationList(navigation_chain_[i], activation_list)) { |
| 355 hits_pattern |= kRedirectURLHitMask; | 358 hits_pattern |= kRedirectURLHitMask; |
| 356 break; | 359 break; |
| 357 } | 360 } |
| 358 } | 361 } |
| 359 } else { | 362 } else { |
| 360 if (navigation_chain_.size() && | 363 if (navigation_chain_.size() && |
| 361 DidURLMatchCurrentActivationList(navigation_chain_.front())) { | 364 DidURLMatchActivationList(navigation_chain_.front(), activation_list)) { |
| 362 hits_pattern = 0x8; // One url hit. | 365 hits_pattern = 0x8; // One url hit. |
| 363 } | 366 } |
| 364 } | 367 } |
| 368 return hits_pattern; | |
| 369 } | |
| 370 | |
| 371 void ContentSubresourceFilterDriverFactory::RecordRedirectChainMatchPattern() | |
| 372 const { | |
| 373 RecordRedirectChainMatchPatternForList( | |
| 374 ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL); | |
| 375 RecordRedirectChainMatchPatternForList(ActivationList::PHISHING_INTERSTITIAL); | |
| 376 } | |
| 377 | |
| 378 void ContentSubresourceFilterDriverFactory:: | |
| 379 RecordRedirectChainMatchPatternForList( | |
| 380 ActivationList activation_list) const { | |
| 381 int hits_pattern = CalculateHitPatternForActivationList(activation_list); | |
| 365 if (!hits_pattern) | 382 if (!hits_pattern) |
| 366 return; | 383 return; |
| 367 UMA_HISTOGRAM_ENUMERATION( | 384 size_t chain_size = navigation_chain_.size(); |
| 368 "SubresourceFilter.PageLoad.RedirectChainMatchPattern", hits_pattern, | 385 switch (activation_list) { |
| 369 0x10 /* max value */); | 386 case ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL: |
| 370 UMA_HISTOGRAM_COUNTS("SubresourceFilter.PageLoad.RedirectChainLength", | 387 REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SocialEngineeringAdsInterstitial", |
| 371 navigation_chain_.size()); | 388 hits_pattern, chain_size); |
| 389 break; | |
| 390 case ActivationList::PHISHING_INTERSTITIAL: | |
| 391 REPORT_REDIRECT_PATTERN_FOR_SUFFIX("PhishingInterstital", hits_pattern, | |
| 392 chain_size); | |
| 393 break; | |
| 394 default: | |
|
engedy
2017/03/14 10:10:21
nit: NOTREACHED();
melandory
2017/03/14 15:51:55
Done.
| |
| 395 break; | |
| 396 } | |
| 372 } | 397 } |
| 373 | 398 |
| 374 } // namespace subresource_filter | 399 } // namespace subresource_filter |
| OLD | NEW |