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 |