| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Implementation of the SafeBrowsingBlockingPage class. | 5 // Implementation of the SafeBrowsingBlockingPage class. |
| 6 | 6 |
| 7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" | 7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" |
| 8 | 8 |
| 9 #include "base/command_line.h" | |
| 10 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 11 #include "chrome/browser/browser_process.h" | |
| 12 #include "chrome/browser/interstitials/chrome_controller_client.h" | 10 #include "chrome/browser/interstitials/chrome_controller_client.h" |
| 13 #include "chrome/browser/interstitials/chrome_metrics_helper.h" | 11 #include "chrome/browser/interstitials/chrome_metrics_helper.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/renderer_preferences_util.h" | 13 #include "chrome/browser/renderer_preferences_util.h" |
| 16 #include "chrome/browser/safe_browsing/threat_details.h" | 14 #include "chrome/browser/safe_browsing/threat_details.h" |
| 17 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
| 18 #include "chrome/common/url_constants.h" | |
| 19 #include "components/prefs/pref_service.h" | 16 #include "components/prefs/pref_service.h" |
| 20 #include "components/safe_browsing_db/safe_browsing_prefs.h" | 17 #include "components/safe_browsing_db/safe_browsing_prefs.h" |
| 21 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/interstitial_page.h" | 19 #include "content/public/browser/interstitial_page.h" |
| 23 #include "content/public/browser/navigation_entry.h" | 20 #include "content/public/browser/navigation_entry.h" |
| 24 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
| 25 | 22 |
| 26 using content::BrowserThread; | 23 using content::BrowserThread; |
| 27 using content::InterstitialPage; | 24 using content::InterstitialPage; |
| 28 using content::WebContents; | 25 using content::WebContents; |
| 29 using security_interstitials::SafeBrowsingErrorUI; | 26 using security_interstitials::SafeBrowsingErrorUI; |
| 30 using security_interstitials::SecurityInterstitialControllerClient; | 27 using security_interstitials::SecurityInterstitialControllerClient; |
| 31 | 28 |
| 32 namespace safe_browsing { | 29 namespace safe_browsing { |
| 33 | 30 |
| 34 namespace { | 31 namespace { |
| 35 | 32 |
| 36 // After a safe browsing interstitial where the user opted-in to the report | |
| 37 // but clicked "proceed anyway", we delay the call to | |
| 38 // ThreatDetails::FinishCollection() by this much time (in | |
| 39 // milliseconds). | |
| 40 const int64_t kThreatDetailsProceedDelayMilliSeconds = 3000; | |
| 41 | |
| 42 // Constants for the Experience Sampling instrumentation. | 33 // Constants for the Experience Sampling instrumentation. |
| 43 const char kEventNameMalware[] = "safebrowsing_interstitial_"; | 34 const char kEventNameMalware[] = "safebrowsing_interstitial_"; |
| 44 const char kEventNameHarmful[] = "harmful_interstitial_"; | 35 const char kEventNameHarmful[] = "harmful_interstitial_"; |
| 45 const char kEventNamePhishing[] = "phishing_interstitial_"; | 36 const char kEventNamePhishing[] = "phishing_interstitial_"; |
| 46 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; | 37 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; |
| 47 | 38 |
| 48 } // namespace | 39 } // namespace |
| 49 | 40 |
| 50 // static | 41 // static |
| 51 SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL; | 42 SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 BaseUIManager* ui_manager, | 99 BaseUIManager* ui_manager, |
| 109 WebContents* web_contents, | 100 WebContents* web_contents, |
| 110 const GURL& main_frame_url, | 101 const GURL& main_frame_url, |
| 111 const UnsafeResourceList& unsafe_resources, | 102 const UnsafeResourceList& unsafe_resources, |
| 112 const SafeBrowsingErrorUI::SBErrorDisplayOptions& display_options) | 103 const SafeBrowsingErrorUI::SBErrorDisplayOptions& display_options) |
| 113 : BaseBlockingPage( | 104 : BaseBlockingPage( |
| 114 ui_manager, | 105 ui_manager, |
| 115 web_contents, | 106 web_contents, |
| 116 unsafe_resources[0].url, | 107 unsafe_resources[0].url, |
| 117 unsafe_resources, | 108 unsafe_resources, |
| 118 CreateControllerClient(web_contents, unsafe_resources), | 109 CreateControllerClient(web_contents, unsafe_resources, ui_manager), |
| 119 display_options), | 110 display_options) { |
| 120 threat_details_proceed_delay_ms_(kThreatDetailsProceedDelayMilliSeconds) { | |
| 121 // Start computing threat details. They will be sent only | 111 // Start computing threat details. They will be sent only |
| 122 // if the user opts-in on the blocking page later. | 112 // if the user opts-in on the blocking page later. |
| 123 // If there's more than one malicious resources, it means the user | 113 // If there's more than one malicious resources, it means the user |
| 124 // clicked through the first warning, so we don't prepare additional | 114 // clicked through the first warning, so we don't prepare additional |
| 125 // reports. | 115 // reports. |
| 126 if (unsafe_resources.size() == 1 && | 116 if (unsafe_resources.size() == 1 && |
| 127 ShouldReportThreatDetails(unsafe_resources[0].threat_type) && | 117 ShouldReportThreatDetails(unsafe_resources[0].threat_type) && |
| 128 threat_details_.get() == NULL && | 118 threat_details_.get() == NULL && |
| 129 sb_error_ui()->CanShowExtendedReportingOption()) { | 119 sb_error_ui()->CanShowExtendedReportingOption()) { |
| 130 threat_details_ = ThreatDetails::NewThreatDetails(ui_manager, web_contents, | 120 threat_details_ = ThreatDetails::NewThreatDetails(ui_manager, web_contents, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 145 } | 135 } |
| 146 | 136 |
| 147 void SafeBrowsingBlockingPage::OverrideRendererPrefs( | 137 void SafeBrowsingBlockingPage::OverrideRendererPrefs( |
| 148 content::RendererPreferences* prefs) { | 138 content::RendererPreferences* prefs) { |
| 149 Profile* profile = Profile::FromBrowserContext( | 139 Profile* profile = Profile::FromBrowserContext( |
| 150 web_contents()->GetBrowserContext()); | 140 web_contents()->GetBrowserContext()); |
| 151 renderer_preferences_util::UpdateFromSystemSettings( | 141 renderer_preferences_util::UpdateFromSystemSettings( |
| 152 prefs, profile, web_contents()); | 142 prefs, profile, web_contents()); |
| 153 } | 143 } |
| 154 | 144 |
| 155 void SafeBrowsingBlockingPage::OnProceed() { | 145 void SafeBrowsingBlockingPage::HandleSubresourcesAfterProceed() { |
| 156 set_proceeded(true); | |
| 157 UpdateMetricsAfterSecurityInterstitial(); | |
| 158 | |
| 159 // Send the threat details, if we opted to. | |
| 160 FinishThreatDetails( | |
| 161 base::TimeDelta::FromMilliseconds(threat_details_proceed_delay_ms_), | |
| 162 true, /* did_proceed */ | |
| 163 controller()->metrics_helper()->NumVisits()); | |
| 164 | |
| 165 ui_manager()->OnBlockingPageDone(unsafe_resources(), true, web_contents(), | |
| 166 main_frame_url()); | |
| 167 | |
| 168 // Check to see if some new notifications of unsafe resources have been | 146 // Check to see if some new notifications of unsafe resources have been |
| 169 // received while we were showing the interstitial. | 147 // received while we were showing the interstitial. |
| 170 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); | 148 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); |
| 171 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents()); | 149 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents()); |
| 172 SafeBrowsingBlockingPage* blocking_page = NULL; | |
| 173 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { | 150 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { |
| 174 // All queued unsafe resources should be for the same page: | 151 // All queued unsafe resources should be for the same page: |
| 152 UnsafeResourceList unsafe_resources = iter->second; |
| 175 content::NavigationEntry* entry = | 153 content::NavigationEntry* entry = |
| 176 iter->second[0].GetNavigationEntryForResource(); | 154 unsafe_resources[0].GetNavigationEntryForResource(); |
| 177 // Build an interstitial for all the unsafe resources notifications. | 155 // Build an interstitial for all the unsafe resources notifications. |
| 178 // Don't show it now as showing an interstitial while an interstitial is | 156 // Don't show it now as showing an interstitial while an interstitial is |
| 179 // already showing would cause DontProceed() to be invoked. | 157 // already showing would cause DontProceed() to be invoked. |
| 180 blocking_page = factory_->CreateSafeBrowsingPage( | 158 SafeBrowsingBlockingPage* blocking_page = factory_->CreateSafeBrowsingPage( |
| 181 ui_manager(), web_contents(), entry ? entry->GetURL() : GURL(), | 159 ui_manager(), web_contents(), entry ? entry->GetURL() : GURL(), |
| 182 iter->second); | 160 unsafe_resources); |
| 183 unsafe_resource_map->erase(iter); | 161 unsafe_resource_map->erase(iter); |
| 162 |
| 163 // Now that this interstitial is gone, we can show the new one. |
| 164 blocking_page->Show(); |
| 184 } | 165 } |
| 185 | |
| 186 // Now that this interstitial is gone, we can show the new one. | |
| 187 if (blocking_page) | |
| 188 blocking_page->Show(); | |
| 189 } | 166 } |
| 190 | 167 |
| 191 content::InterstitialPageDelegate::TypeID | 168 content::InterstitialPageDelegate::TypeID |
| 192 SafeBrowsingBlockingPage::GetTypeForTesting() const { | 169 SafeBrowsingBlockingPage::GetTypeForTesting() const { |
| 193 return SafeBrowsingBlockingPage::kTypeForTesting; | 170 return SafeBrowsingBlockingPage::kTypeForTesting; |
| 194 } | 171 } |
| 195 | 172 |
| 196 void SafeBrowsingBlockingPage::FinishThreatDetails(const base::TimeDelta& delay, | 173 void SafeBrowsingBlockingPage::FinishThreatDetails(const base::TimeDelta& delay, |
| 197 bool did_proceed, | 174 bool did_proceed, |
| 198 int num_visits) { | 175 int num_visits) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 main_frame_url, resources); | 207 main_frame_url, resources); |
| 231 } | 208 } |
| 232 | 209 |
| 233 // static | 210 // static |
| 234 void SafeBrowsingBlockingPage::ShowBlockingPage( | 211 void SafeBrowsingBlockingPage::ShowBlockingPage( |
| 235 BaseUIManager* ui_manager, | 212 BaseUIManager* ui_manager, |
| 236 const UnsafeResource& unsafe_resource) { | 213 const UnsafeResource& unsafe_resource) { |
| 237 DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); | 214 DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); |
| 238 WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); | 215 WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); |
| 239 | 216 |
| 240 if (!InterstitialPage::GetInterstitialPage(web_contents) || | 217 if (InterstitialPage::GetInterstitialPage(web_contents) && |
| 241 !unsafe_resource.is_subresource) { | 218 unsafe_resource.is_subresource) { |
| 219 // This is an interstitial for a page's resource, let's queue it. |
| 220 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); |
| 221 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource); |
| 222 } else { |
| 242 // There is no interstitial currently showing in that tab, or we are about | 223 // There is no interstitial currently showing in that tab, or we are about |
| 243 // to display a new one for the main frame. If there is already an | 224 // to display a new one for the main frame. If there is already an |
| 244 // interstitial, showing the new one will automatically hide the old one. | 225 // interstitial, showing the new one will automatically hide the old one. |
| 245 content::NavigationEntry* entry = | 226 content::NavigationEntry* entry = |
| 246 unsafe_resource.GetNavigationEntryForResource(); | 227 unsafe_resource.GetNavigationEntryForResource(); |
| 247 SafeBrowsingBlockingPage* blocking_page = | 228 SafeBrowsingBlockingPage* blocking_page = |
| 248 CreateBlockingPage(ui_manager, web_contents, | 229 CreateBlockingPage(ui_manager, web_contents, |
| 249 entry ? entry->GetURL() : GURL(), unsafe_resource); | 230 entry ? entry->GetURL() : GURL(), unsafe_resource); |
| 250 blocking_page->Show(); | 231 blocking_page->Show(); |
| 251 return; | |
| 252 } | 232 } |
| 253 | |
| 254 // This is an interstitial for a page's resource, let's queue it. | |
| 255 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); | |
| 256 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource); | |
| 257 } | 233 } |
| 258 | 234 |
| 259 // static | 235 // static |
| 260 std::string SafeBrowsingBlockingPage::GetSamplingEventName( | 236 std::string SafeBrowsingBlockingPage::GetSamplingEventName( |
| 261 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { | 237 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { |
| 262 switch (interstitial_reason) { | 238 switch (interstitial_reason) { |
| 263 case SafeBrowsingErrorUI::SB_REASON_MALWARE: | 239 case SafeBrowsingErrorUI::SB_REASON_MALWARE: |
| 264 return kEventNameMalware; | 240 return kEventNameMalware; |
| 265 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: | 241 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: |
| 266 return kEventNameHarmful; | 242 return kEventNameHarmful; |
| 267 case SafeBrowsingErrorUI::SB_REASON_PHISHING: | 243 case SafeBrowsingErrorUI::SB_REASON_PHISHING: |
| 268 return kEventNamePhishing; | 244 return kEventNamePhishing; |
| 269 default: | 245 default: |
| 270 return kEventNameOther; | 246 return kEventNameOther; |
| 271 } | 247 } |
| 272 } | 248 } |
| 273 | 249 |
| 274 // static | 250 // static |
| 275 std::unique_ptr<security_interstitials::SecurityInterstitialControllerClient> | 251 std::unique_ptr<SecurityInterstitialControllerClient> |
| 276 SafeBrowsingBlockingPage::CreateControllerClient( | 252 SafeBrowsingBlockingPage::CreateControllerClient( |
| 277 WebContents* web_contents, | 253 WebContents* web_contents, |
| 278 const UnsafeResourceList& unsafe_resources) { | 254 const UnsafeResourceList& unsafe_resources, |
| 279 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason = | 255 const BaseUIManager* ui_manager) { |
| 280 GetInterstitialReason(unsafe_resources); | |
| 281 GURL request_url(unsafe_resources[0].url); | |
| 282 security_interstitials::MetricsHelper::ReportDetails reporting_info; | |
| 283 reporting_info.metric_prefix = | |
| 284 GetMetricPrefix(unsafe_resources, interstitial_reason); | |
| 285 reporting_info.extra_suffix = GetExtraMetricsSuffix(unsafe_resources); | |
| 286 | |
| 287 std::unique_ptr<ChromeMetricsHelper> metrics_helper = | |
| 288 base::MakeUnique<ChromeMetricsHelper>( | |
| 289 web_contents, request_url, reporting_info, | |
| 290 GetSamplingEventName(interstitial_reason)); | |
| 291 | |
| 292 Profile* profile = Profile::FromBrowserContext( | 256 Profile* profile = Profile::FromBrowserContext( |
| 293 web_contents->GetBrowserContext()); | 257 web_contents->GetBrowserContext()); |
| 294 DCHECK(profile); | 258 DCHECK(profile); |
| 295 | 259 |
| 296 return base::MakeUnique< | 260 std::unique_ptr<ChromeMetricsHelper> metrics_helper = |
| 297 security_interstitials::SecurityInterstitialControllerClient>( | 261 base::MakeUnique<ChromeMetricsHelper>( |
| 298 web_contents, | 262 web_contents, unsafe_resources[0].url, |
| 299 std::move(metrics_helper), | 263 GetReportingInfo(unsafe_resources), |
| 300 profile->GetPrefs(), | 264 GetSamplingEventName(GetInterstitialReason(unsafe_resources))); |
| 301 g_browser_process->GetApplicationLocale(), | 265 |
| 302 GURL(chrome::kChromeUINewTabURL)); | 266 return base::MakeUnique<SecurityInterstitialControllerClient>( |
| 267 web_contents, std::move(metrics_helper), profile->GetPrefs(), |
| 268 ui_manager->app_locale(), ui_manager->default_safe_page()); |
| 303 } | 269 } |
| 304 | 270 |
| 305 } // namespace safe_browsing | 271 } // namespace safe_browsing |
| OLD | NEW |