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 <string> | 9 #include <string> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/i18n/rtl.h" | 13 #include "base/i18n/rtl.h" |
14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
15 #include "base/metrics/field_trial.h" | 15 #include "base/metrics/field_trial.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/prefs/pref_service.h" | 17 #include "base/prefs/pref_service.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_piece.h" | 19 #include "base/strings/string_piece.h" |
20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
22 #include "base/time/time.h" | 22 #include "base/time/time.h" |
23 #include "base/values.h" | 23 #include "base/values.h" |
24 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
25 #include "chrome/browser/extensions/api/experience_sampling_private/experience_s ampling.h" | |
25 #include "chrome/browser/history/history_service_factory.h" | 26 #include "chrome/browser/history/history_service_factory.h" |
26 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/browser/renderer_preferences_util.h" | 28 #include "chrome/browser/renderer_preferences_util.h" |
28 #include "chrome/browser/safe_browsing/malware_details.h" | 29 #include "chrome/browser/safe_browsing/malware_details.h" |
29 #include "chrome/browser/safe_browsing/ui_manager.h" | 30 #include "chrome/browser/safe_browsing/ui_manager.h" |
30 #include "chrome/browser/tab_contents/tab_util.h" | 31 #include "chrome/browser/tab_contents/tab_util.h" |
31 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
32 #include "chrome/common/pref_names.h" | 33 #include "chrome/common/pref_names.h" |
33 #include "chrome/common/url_constants.h" | 34 #include "chrome/common/url_constants.h" |
34 #include "components/google/core/browser/google_util.h" | 35 #include "components/google/core/browser/google_util.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
46 #include "ui/base/resource/resource_bundle.h" | 47 #include "ui/base/resource/resource_bundle.h" |
47 #include "ui/base/webui/jstemplate_builder.h" | 48 #include "ui/base/webui/jstemplate_builder.h" |
48 #include "ui/base/webui/web_ui_util.h" | 49 #include "ui/base/webui/web_ui_util.h" |
49 | 50 |
50 using base::UserMetricsAction; | 51 using base::UserMetricsAction; |
51 using content::BrowserThread; | 52 using content::BrowserThread; |
52 using content::InterstitialPage; | 53 using content::InterstitialPage; |
53 using content::OpenURLParams; | 54 using content::OpenURLParams; |
54 using content::Referrer; | 55 using content::Referrer; |
55 using content::WebContents; | 56 using content::WebContents; |
57 using extensions::ExperienceSamplingEvent; | |
56 | 58 |
57 namespace { | 59 namespace { |
58 | 60 |
59 // For malware interstitial pages, we link the problematic URL to Google's | 61 // For malware interstitial pages, we link the problematic URL to Google's |
60 // diagnostic page. | 62 // diagnostic page. |
61 #if defined(GOOGLE_CHROME_BUILD) | 63 #if defined(GOOGLE_CHROME_BUILD) |
62 const char* const kSbDiagnosticUrl = | 64 const char* const kSbDiagnosticUrl = |
63 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&clie nt=googlechrome"; | 65 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&clie nt=googlechrome"; |
64 #else | 66 #else |
65 const char* const kSbDiagnosticUrl = | 67 const char* const kSbDiagnosticUrl = |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 const char kTakeMeBackCommand[] = "takeMeBack"; | 109 const char kTakeMeBackCommand[] = "takeMeBack"; |
108 // Special command that we use when the user navigated away from the | 110 // Special command that we use when the user navigated away from the |
109 // page. E.g., closed the tab or the window. This is only used by | 111 // page. E.g., closed the tab or the window. This is only used by |
110 // RecordUserReactionTime. | 112 // RecordUserReactionTime. |
111 const char kNavigatedAwayMetaCommand[] = "closed"; | 113 const char kNavigatedAwayMetaCommand[] = "closed"; |
112 | 114 |
113 // Other constants used to communicate with the JavaScript. | 115 // Other constants used to communicate with the JavaScript. |
114 const char kBoxChecked[] = "boxchecked"; | 116 const char kBoxChecked[] = "boxchecked"; |
115 const char kDisplayCheckBox[] = "displaycheckbox"; | 117 const char kDisplayCheckBox[] = "displaycheckbox"; |
116 | 118 |
119 // Constants for the Experience Sampling instrumentation. | |
120 const char kEventNameMalware[] = "safebrowsing_interstitial_"; | |
121 const char kEventNamePhishing[] = "phishing_interstitial_"; | |
122 const char kEventNameMalwareAndPhishing[] = | |
123 "malware_and_phishing_interstitial_"; | |
124 const char kEventNameOther[] = "safebrowsing_other_instertitial_"; | |
palmer
2014/07/25 18:05:00
Typo: Should be "interstitial".
Chris Thompson
2014/07/25 18:19:46
Done.
| |
125 | |
117 base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap> | 126 base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap> |
118 g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER; | 127 g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER; |
119 | 128 |
120 // This enum is used for a histogram. Don't reorder, delete, or insert | 129 // This enum is used for a histogram. Don't reorder, delete, or insert |
121 // elements. New elements should be added before MAX_ACTION only. | 130 // elements. New elements should be added before MAX_ACTION only. |
122 enum DetailedDecision { | 131 enum DetailedDecision { |
123 MALWARE_SHOW_NEW_SITE = 0, | 132 MALWARE_SHOW_NEW_SITE = 0, |
124 MALWARE_PROCEED_NEW_SITE, | 133 MALWARE_PROCEED_NEW_SITE, |
125 MALWARE_SHOW_CROSS_SITE, | 134 MALWARE_SHOW_CROSS_SITE, |
126 MALWARE_PROCEED_CROSS_SITE, | 135 MALWARE_PROCEED_CROSS_SITE, |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 // If there's more than one malicious resources, it means the user | 312 // If there's more than one malicious resources, it means the user |
304 // clicked through the first warning, so we don't prepare additional | 313 // clicked through the first warning, so we don't prepare additional |
305 // reports. | 314 // reports. |
306 if (unsafe_resources.size() == 1 && | 315 if (unsafe_resources.size() == 1 && |
307 unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE && | 316 unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE && |
308 malware_details_.get() == NULL && CanShowMalwareDetailsOption()) { | 317 malware_details_.get() == NULL && CanShowMalwareDetailsOption()) { |
309 malware_details_ = MalwareDetails::NewMalwareDetails( | 318 malware_details_ = MalwareDetails::NewMalwareDetails( |
310 ui_manager_, web_contents, unsafe_resources[0]); | 319 ui_manager_, web_contents, unsafe_resources[0]); |
311 } | 320 } |
312 | 321 |
322 // ExperienceSampling: Set up new sampling event for this interstitial. | |
323 // This needs to handle all types of warnings this insterstitial can show. | |
palmer
2014/07/25 18:05:00
Typo again :)
Chris Thompson
2014/07/25 18:19:46
Done.
| |
324 std::string event_name; | |
325 switch (interstitial_type_) { | |
326 case TYPE_MALWARE_AND_PHISHING: | |
327 event_name = kEventNameMalwareAndPhishing; | |
328 break; | |
329 case TYPE_MALWARE: | |
330 event_name = kEventNameMalware; | |
331 break; | |
332 case TYPE_PHISHING: | |
333 event_name = kEventNamePhishing; | |
334 break; | |
335 default: | |
336 event_name = kEventNameOther; | |
337 break; | |
338 } | |
339 sampling_event_.reset(new ExperienceSamplingEvent( | |
340 event_name, | |
341 url_, | |
342 web_contents_->GetLastCommittedURL(), | |
343 web_contents_->GetBrowserContext())); | |
344 | |
313 interstitial_page_ = InterstitialPage::Create( | 345 interstitial_page_ = InterstitialPage::Create( |
314 web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this); | 346 web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this); |
315 } | 347 } |
316 | 348 |
317 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() { | 349 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() { |
318 return (!web_contents_->GetBrowserContext()->IsOffTheRecord() && | 350 return (!web_contents_->GetBrowserContext()->IsOffTheRecord() && |
319 web_contents_->GetURL().SchemeIs(url::kHttpScheme)); | 351 web_contents_->GetURL().SchemeIs(url::kHttpScheme)); |
320 } | 352 } |
321 | 353 |
322 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { | 354 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { |
(...skipping 23 matching lines...) Expand all Loading... | |
346 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || | 378 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || |
347 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { | 379 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { |
348 url = GURL(kLearnMoreMalwareUrl); | 380 url = GURL(kLearnMoreMalwareUrl); |
349 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING || | 381 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING || |
350 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) { | 382 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) { |
351 url = GURL(kLearnMorePhishingUrl); | 383 url = GURL(kLearnMorePhishingUrl); |
352 } else { | 384 } else { |
353 NOTREACHED(); | 385 NOTREACHED(); |
354 } | 386 } |
355 | 387 |
388 sampling_event_->has_viewed_learn_more = true; | |
389 | |
356 OpenURLParams params( | 390 OpenURLParams params( |
357 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false); | 391 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false); |
358 web_contents_->OpenURL(params); | 392 web_contents_->OpenURL(params); |
359 return; | 393 return; |
360 } | 394 } |
361 | 395 |
362 if (command == kLearnMoreCommandV2) { | 396 if (command == kLearnMoreCommandV2) { |
363 // User pressed "Learn more". | 397 // User pressed "Learn more". |
364 GURL url; | 398 GURL url; |
365 SBThreatType threat_type = unsafe_resources_[0].threat_type; | 399 SBThreatType threat_type = unsafe_resources_[0].threat_type; |
366 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || | 400 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || |
367 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { | 401 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { |
368 url = GURL(kLearnMoreMalwareUrlV2); | 402 url = GURL(kLearnMoreMalwareUrlV2); |
369 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING || | 403 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING || |
370 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) { | 404 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) { |
371 url = GURL(kLearnMorePhishingUrlV2); | 405 url = GURL(kLearnMorePhishingUrlV2); |
372 } else { | 406 } else { |
373 NOTREACHED(); | 407 NOTREACHED(); |
374 } | 408 } |
375 | 409 |
410 sampling_event_->has_viewed_learn_more = true; | |
411 | |
376 OpenURLParams params( | 412 OpenURLParams params( |
377 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false); | 413 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false); |
378 web_contents_->OpenURL(params); | 414 web_contents_->OpenURL(params); |
379 return; | 415 return; |
380 } | 416 } |
381 | 417 |
382 if (command == kShowPrivacyCommand) { | 418 if (command == kShowPrivacyCommand) { |
383 // User pressed "Safe Browsing privacy policy". | 419 // User pressed "Safe Browsing privacy policy". |
384 GURL url(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL)); | 420 GURL url(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL)); |
385 OpenURLParams params( | 421 OpenURLParams params( |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, | 515 diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, |
480 false); | 516 false); |
481 web_contents_->OpenURL(params); | 517 web_contents_->OpenURL(params); |
482 return; | 518 return; |
483 } | 519 } |
484 | 520 |
485 if (command == kExpandedSeeMoreCommand) { | 521 if (command == kExpandedSeeMoreCommand) { |
486 // User expanded the "see more info" section of the page. We don't actually | 522 // User expanded the "see more info" section of the page. We don't actually |
487 // do any action based on this, it's just so that RecordUserReactionTime can | 523 // do any action based on this, it's just so that RecordUserReactionTime can |
488 // track it. | 524 // track it. |
525 | |
526 // ExperienceSampling: We track that the user expanded the details. | |
527 sampling_event_->has_viewed_details = true; | |
489 return; | 528 return; |
490 } | 529 } |
491 | 530 |
492 NOTREACHED() << "Unexpected command: " << command; | 531 NOTREACHED() << "Unexpected command: " << command; |
493 } | 532 } |
494 | 533 |
495 void SafeBrowsingBlockingPage::OverrideRendererPrefs( | 534 void SafeBrowsingBlockingPage::OverrideRendererPrefs( |
496 content::RendererPreferences* prefs) { | 535 content::RendererPreferences* prefs) { |
497 Profile* profile = Profile::FromBrowserContext( | 536 Profile* profile = Profile::FromBrowserContext( |
498 web_contents_->GetBrowserContext()); | 537 web_contents_->GetBrowserContext()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 SafeBrowsingBlockingPage* blocking_page = NULL; | 581 SafeBrowsingBlockingPage* blocking_page = NULL; |
543 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { | 582 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { |
544 // Build an interstitial for all the unsafe resources notifications. | 583 // Build an interstitial for all the unsafe resources notifications. |
545 // Don't show it now as showing an interstitial while an interstitial is | 584 // Don't show it now as showing an interstitial while an interstitial is |
546 // already showing would cause DontProceed() to be invoked. | 585 // already showing would cause DontProceed() to be invoked. |
547 blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_, | 586 blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_, |
548 iter->second); | 587 iter->second); |
549 unsafe_resource_map->erase(iter); | 588 unsafe_resource_map->erase(iter); |
550 } | 589 } |
551 | 590 |
591 // ExperienceSampling: Notify that user decided to proceed. | |
592 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed); | |
593 | |
552 // Now that this interstitial is gone, we can show the new one. | 594 // Now that this interstitial is gone, we can show the new one. |
553 if (blocking_page) | 595 if (blocking_page) |
554 blocking_page->interstitial_page_->Show(); | 596 blocking_page->interstitial_page_->Show(); |
555 } | 597 } |
556 | 598 |
557 void SafeBrowsingBlockingPage::OnDontProceed() { | 599 void SafeBrowsingBlockingPage::OnDontProceed() { |
558 // Calling this method twice will not double-count. | 600 // Calling this method twice will not double-count. |
559 RecordUserReactionTime(kNavigatedAwayMetaCommand); | 601 RecordUserReactionTime(kNavigatedAwayMetaCommand); |
560 // We could have already called Proceed(), in which case we must not notify | 602 // We could have already called Proceed(), in which case we must not notify |
561 // the SafeBrowsingUIManager again, as the client has been deleted. | 603 // the SafeBrowsingUIManager again, as the client has been deleted. |
(...skipping 23 matching lines...) Expand all Loading... | |
585 // that had a subresource warning. | 627 // that had a subresource warning. |
586 int last_committed_index = | 628 int last_committed_index = |
587 web_contents_->GetController().GetLastCommittedEntryIndex(); | 629 web_contents_->GetController().GetLastCommittedEntryIndex(); |
588 if (navigation_entry_index_to_remove_ != -1 && | 630 if (navigation_entry_index_to_remove_ != -1 && |
589 navigation_entry_index_to_remove_ != last_committed_index && | 631 navigation_entry_index_to_remove_ != last_committed_index && |
590 !web_contents_->IsBeingDestroyed()) { | 632 !web_contents_->IsBeingDestroyed()) { |
591 CHECK(web_contents_->GetController().RemoveEntryAtIndex( | 633 CHECK(web_contents_->GetController().RemoveEntryAtIndex( |
592 navigation_entry_index_to_remove_)); | 634 navigation_entry_index_to_remove_)); |
593 navigation_entry_index_to_remove_ = -1; | 635 navigation_entry_index_to_remove_ = -1; |
594 } | 636 } |
637 | |
638 // ExperienceSampling: Notify that user decided to go back. | |
639 // This also occurs if the user navigates away or closes the tab. | |
640 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kDeny); | |
595 } | 641 } |
596 | 642 |
597 void SafeBrowsingBlockingPage::OnGotHistoryCount(bool success, | 643 void SafeBrowsingBlockingPage::OnGotHistoryCount(bool success, |
598 int num_visits, | 644 int num_visits, |
599 base::Time first_visit) { | 645 base::Time first_visit) { |
600 if (success) | 646 if (success) |
601 num_visits_ = num_visits; | 647 num_visits_ = num_visits; |
602 } | 648 } |
603 | 649 |
604 void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) { | 650 void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) { |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1393 IDS_PHISHING_V3_PRIMARY_PARAGRAPH, | 1439 IDS_PHISHING_V3_PRIMARY_PARAGRAPH, |
1394 base::UTF8ToUTF16(url_.host()))); | 1440 base::UTF8ToUTF16(url_.host()))); |
1395 load_time_data->SetString( | 1441 load_time_data->SetString( |
1396 "explanationParagraph", | 1442 "explanationParagraph", |
1397 l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH, | 1443 l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH, |
1398 base::UTF8ToUTF16(url_.host()))); | 1444 base::UTF8ToUTF16(url_.host()))); |
1399 load_time_data->SetString( | 1445 load_time_data->SetString( |
1400 "finalParagraph", | 1446 "finalParagraph", |
1401 l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH)); | 1447 l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH)); |
1402 } | 1448 } |
OLD | NEW |