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 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 | 91 |
92 // The commands returned by the page when the user performs an action. | 92 // The commands returned by the page when the user performs an action. |
93 const char kDoReportCommand[] = "doReport"; | 93 const char kDoReportCommand[] = "doReport"; |
94 const char kDontReportCommand[] = "dontReport"; | 94 const char kDontReportCommand[] = "dontReport"; |
95 const char kExpandedSeeMoreCommand[] = "expandedSeeMore"; | 95 const char kExpandedSeeMoreCommand[] = "expandedSeeMore"; |
96 const char kLearnMoreCommand[] = "learnMore2"; | 96 const char kLearnMoreCommand[] = "learnMore2"; |
97 const char kProceedCommand[] = "proceed"; | 97 const char kProceedCommand[] = "proceed"; |
98 const char kShowDiagnosticCommand[] = "showDiagnostic"; | 98 const char kShowDiagnosticCommand[] = "showDiagnostic"; |
99 const char kShowPrivacyCommand[] = "showPrivacy"; | 99 const char kShowPrivacyCommand[] = "showPrivacy"; |
100 const char kTakeMeBackCommand[] = "takeMeBack"; | 100 const char kTakeMeBackCommand[] = "takeMeBack"; |
101 // Special command that we use when the user navigated away from the | |
102 // page. E.g., closed the tab or the window. This is only used by | |
103 // RecordUserReactionTime. | |
104 const char kNavigatedAwayMetaCommand[] = "closed"; | |
105 | 101 |
106 // Other constants used to communicate with the JavaScript. | 102 // Other constants used to communicate with the JavaScript. |
107 const char kBoxChecked[] = "boxchecked"; | 103 const char kBoxChecked[] = "boxchecked"; |
108 const char kDisplayCheckBox[] = "displaycheckbox"; | 104 const char kDisplayCheckBox[] = "displaycheckbox"; |
109 | 105 |
110 // Constants for the Experience Sampling instrumentation. | 106 // Constants for the Experience Sampling instrumentation. |
111 #if defined(ENABLE_EXTENSIONS) | 107 #if defined(ENABLE_EXTENSIONS) |
112 const char kEventNameMalware[] = "safebrowsing_interstitial_"; | 108 const char kEventNameMalware[] = "safebrowsing_interstitial_"; |
113 const char kEventNamePhishing[] = "phishing_interstitial_"; | 109 const char kEventNamePhishing[] = "phishing_interstitial_"; |
114 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; | 110 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 : malware_details_proceed_delay_ms_( | 171 : malware_details_proceed_delay_ms_( |
176 kMalwareDetailsProceedDelayMilliSeconds), | 172 kMalwareDetailsProceedDelayMilliSeconds), |
177 ui_manager_(ui_manager), | 173 ui_manager_(ui_manager), |
178 report_loop_(NULL), | 174 report_loop_(NULL), |
179 is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)), | 175 is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)), |
180 unsafe_resources_(unsafe_resources), | 176 unsafe_resources_(unsafe_resources), |
181 proceeded_(false), | 177 proceeded_(false), |
182 web_contents_(web_contents), | 178 web_contents_(web_contents), |
183 url_(unsafe_resources[0].url), | 179 url_(unsafe_resources[0].url), |
184 interstitial_page_(NULL), | 180 interstitial_page_(NULL), |
185 has_expanded_see_more_section_(false), | |
186 create_view_(true), | 181 create_view_(true), |
187 num_visits_(-1) { | 182 num_visits_(-1) { |
188 bool malware = false; | 183 bool malware = false; |
189 bool phishing = false; | 184 bool phishing = false; |
190 for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin(); | 185 for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin(); |
191 iter != unsafe_resources_.end(); ++iter) { | 186 iter != unsafe_resources_.end(); ++iter) { |
192 const UnsafeResource& resource = *iter; | 187 const UnsafeResource& resource = *iter; |
193 SBThreatType threat_type = resource.threat_type; | 188 SBThreatType threat_type = resource.threat_type; |
194 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || | 189 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || |
195 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { | 190 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 265 |
271 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { | 266 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { |
272 } | 267 } |
273 | 268 |
274 void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) { | 269 void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) { |
275 std::string command(cmd); // Make a local copy so we can modify it. | 270 std::string command(cmd); // Make a local copy so we can modify it. |
276 // The Jasonified response has quotes, remove them. | 271 // The Jasonified response has quotes, remove them. |
277 if (command.length() > 1 && command[0] == '"') { | 272 if (command.length() > 1 && command[0] == '"') { |
278 command = command.substr(1, command.length() - 2); | 273 command = command.substr(1, command.length() - 2); |
279 } | 274 } |
280 RecordUserReactionTime(command); | |
281 if (command == kDoReportCommand) { | 275 if (command == kDoReportCommand) { |
282 SetReportingPreference(true); | 276 SetReportingPreference(true); |
283 return; | 277 return; |
284 } | 278 } |
285 | 279 |
286 if (command == kDontReportCommand) { | 280 if (command == kDontReportCommand) { |
287 SetReportingPreference(false); | 281 SetReportingPreference(false); |
288 return; | 282 return; |
289 } | 283 } |
290 | 284 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 unsafe_resources_[element_index].threat_type == | 385 unsafe_resources_[element_index].threat_type == |
392 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL); | 386 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL); |
393 OpenURLParams params( | 387 OpenURLParams params( |
394 diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, | 388 diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, |
395 false); | 389 false); |
396 web_contents_->OpenURL(params); | 390 web_contents_->OpenURL(params); |
397 return; | 391 return; |
398 } | 392 } |
399 | 393 |
400 if (command == kExpandedSeeMoreCommand) { | 394 if (command == kExpandedSeeMoreCommand) { |
401 // User expanded the "see more info" section of the page. We don't actually | |
402 // do any action based on this, it's just so that RecordUserReactionTime can | |
403 // track it. | |
404 | |
405 #if defined(ENABLE_EXTENSIONS) | 395 #if defined(ENABLE_EXTENSIONS) |
406 // ExperienceSampling: We track that the user expanded the details. | 396 // ExperienceSampling: We track that the user expanded the details. |
407 if (sampling_event_.get()) | 397 if (sampling_event_.get()) |
408 sampling_event_->set_has_viewed_details(true); | 398 sampling_event_->set_has_viewed_details(true); |
409 #endif | 399 #endif |
410 return; | 400 return; |
411 } | 401 } |
412 | 402 |
413 NOTREACHED() << "Unexpected command: " << command; | 403 NOTREACHED() << "Unexpected command: " << command; |
414 } | 404 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 void SafeBrowsingBlockingPage::Show() { | 458 void SafeBrowsingBlockingPage::Show() { |
469 DCHECK(!interstitial_page_); | 459 DCHECK(!interstitial_page_); |
470 interstitial_page_ = InterstitialPage::Create( | 460 interstitial_page_ = InterstitialPage::Create( |
471 web_contents_, is_main_frame_load_blocked_, url_, this); | 461 web_contents_, is_main_frame_load_blocked_, url_, this); |
472 if (!create_view_) | 462 if (!create_view_) |
473 interstitial_page_->DontCreateViewForTesting(); | 463 interstitial_page_->DontCreateViewForTesting(); |
474 interstitial_page_->Show(); | 464 interstitial_page_->Show(); |
475 } | 465 } |
476 | 466 |
477 void SafeBrowsingBlockingPage::OnDontProceed() { | 467 void SafeBrowsingBlockingPage::OnDontProceed() { |
478 // Calling this method twice will not double-count. | |
479 RecordUserReactionTime(kNavigatedAwayMetaCommand); | |
480 // We could have already called Proceed(), in which case we must not notify | 468 // We could have already called Proceed(), in which case we must not notify |
481 // the SafeBrowsingUIManager again, as the client has been deleted. | 469 // the SafeBrowsingUIManager again, as the client has been deleted. |
482 if (proceeded_) | 470 if (proceeded_) |
483 return; | 471 return; |
484 | 472 |
485 RecordUserAction(DONT_PROCEED); | 473 RecordUserAction(DONT_PROCEED); |
486 // Send the malware details, if we opted to. | 474 // Send the malware details, if we opted to. |
487 FinishMalwareDetails(0); // No delay | 475 FinishMalwareDetails(0); // No delay |
488 | 476 |
489 NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false); | 477 NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ? | 612 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ? |
625 MALWARE_SHOW_CROSS_SITE : PHISHING_SHOW_CROSS_SITE); | 613 MALWARE_SHOW_CROSS_SITE : PHISHING_SHOW_CROSS_SITE); |
626 if (event == PROCEED) { | 614 if (event == PROCEED) { |
627 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ? | 615 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ? |
628 MALWARE_PROCEED_CROSS_SITE : PHISHING_PROCEED_CROSS_SITE); | 616 MALWARE_PROCEED_CROSS_SITE : PHISHING_PROCEED_CROSS_SITE); |
629 } | 617 } |
630 } | 618 } |
631 } | 619 } |
632 } | 620 } |
633 | 621 |
634 void SafeBrowsingBlockingPage::RecordUserReactionTime( | |
635 const std::string& command) { | |
636 if (interstitial_show_time_.is_null()) | |
637 return; // We already reported the user reaction time. | |
638 base::TimeDelta dt = base::TimeTicks::Now() - interstitial_show_time_; | |
639 DVLOG(1) << "User reaction time for command:" << command | |
640 << " on interstitial_type_:" << interstitial_type_ | |
641 << " warning took " << dt.InMilliseconds() << "ms"; | |
642 bool recorded = true; | |
643 if (interstitial_type_ == TYPE_MALWARE) { | |
644 // There are six ways in which the malware interstitial can go | |
645 // away. We handle all of them here but we group two together: closing the | |
646 // tag / browser window and clicking on the back button in the browser (not | |
647 // the big green button) are considered the same action. | |
648 if (command == kProceedCommand) { | |
649 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeProceed", dt); | |
650 } else if (command == kTakeMeBackCommand) { | |
651 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeTakeMeBack", dt); | |
652 } else if (command == kShowDiagnosticCommand) { | |
653 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeDiagnostic", dt); | |
654 } else if (command == kShowPrivacyCommand) { | |
655 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimePrivacyPolicy", | |
656 dt); | |
657 } else if (command == kLearnMoreCommand) { | |
658 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore", | |
659 dt); | |
660 } else if (command == kNavigatedAwayMetaCommand) { | |
661 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt); | |
662 } else if (command == kExpandedSeeMoreCommand) { | |
663 // Only record the expanded histogram once per display of the | |
664 // interstitial. | |
665 if (has_expanded_see_more_section_) | |
666 return; | |
667 RecordUserAction(SHOW_ADVANCED); | |
668 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore", | |
669 dt); | |
670 has_expanded_see_more_section_ = true; | |
671 // Expanding the "See More" section doesn't finish the interstitial, so | |
672 // don't mark the reaction time as recorded. | |
673 recorded = false; | |
674 } else { | |
675 recorded = false; | |
676 } | |
677 } else { | |
678 // Same as above but for phishing warnings. | |
679 if (command == kProceedCommand) { | |
680 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt); | |
681 } else if (command == kTakeMeBackCommand) { | |
682 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt); | |
683 } else if (command == kShowDiagnosticCommand) { | |
684 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt); | |
685 } else if (command == kLearnMoreCommand) { | |
686 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt); | |
687 } else if (command == kNavigatedAwayMetaCommand) { | |
688 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt); | |
689 } else if (command == kExpandedSeeMoreCommand) { | |
690 // Only record the expanded histogram once per display of the | |
691 // interstitial. | |
692 if (has_expanded_see_more_section_) | |
693 return; | |
694 RecordUserAction(SHOW_ADVANCED); | |
695 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore", | |
696 dt); | |
697 has_expanded_see_more_section_ = true; | |
698 // Expanding the "See More" section doesn't finish the interstitial, so | |
699 // don't mark the reaction time as recorded. | |
700 recorded = false; | |
701 } else { | |
702 recorded = false; | |
703 } | |
704 } | |
705 if (recorded) // Making sure we don't double-count reaction times. | |
706 interstitial_show_time_ = base::TimeTicks(); // Resets the show time. | |
707 } | |
708 | |
709 void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) { | 622 void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) { |
710 if (malware_details_.get() == NULL) | 623 if (malware_details_.get() == NULL) |
711 return; // Not all interstitials have malware details (eg phishing). | 624 return; // Not all interstitials have malware details (eg phishing). |
712 | 625 |
713 const bool enabled = | 626 const bool enabled = |
714 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled); | 627 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled); |
715 UMA_HISTOGRAM_BOOLEAN("SB2.ExtendedReportingIsEnabled", enabled); | 628 UMA_HISTOGRAM_BOOLEAN("SB2.ExtendedReportingIsEnabled", enabled); |
716 if (enabled) { | 629 if (enabled) { |
717 // Finish the malware details collection, send it over. | 630 // Finish the malware details collection, send it over. |
718 BrowserThread::PostDelayedTask( | 631 BrowserThread::PostDelayedTask( |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 l10n_util::GetStringUTF16(IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON)); | 738 l10n_util::GetStringUTF16(IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON)); |
826 load_time_data.SetBoolean( | 739 load_time_data.SetBoolean( |
827 "overridable", | 740 "overridable", |
828 !IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)); | 741 !IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)); |
829 | 742 |
830 if (interstitial_type_ == TYPE_PHISHING) | 743 if (interstitial_type_ == TYPE_PHISHING) |
831 PopulatePhishingLoadTimeData(&load_time_data); | 744 PopulatePhishingLoadTimeData(&load_time_data); |
832 else | 745 else |
833 PopulateMalwareLoadTimeData(&load_time_data); | 746 PopulateMalwareLoadTimeData(&load_time_data); |
834 | 747 |
835 interstitial_show_time_ = base::TimeTicks::Now(); | |
836 | |
837 base::StringPiece html( | 748 base::StringPiece html( |
838 ResourceBundle::GetSharedInstance().GetRawDataResource( | 749 ResourceBundle::GetSharedInstance().GetRawDataResource( |
839 IRD_SECURITY_INTERSTITIAL_HTML)); | 750 IRD_SECURITY_INTERSTITIAL_HTML)); |
840 webui::UseVersion2 version; | 751 webui::UseVersion2 version; |
841 return webui::GetI18nTemplateHtml(html, &load_time_data); | 752 return webui::GetI18nTemplateHtml(html, &load_time_data); |
842 } | 753 } |
843 | 754 |
844 void SafeBrowsingBlockingPage::PopulateMalwareLoadTimeData( | 755 void SafeBrowsingBlockingPage::PopulateMalwareLoadTimeData( |
845 base::DictionaryValue* load_time_data) { | 756 base::DictionaryValue* load_time_data) { |
846 load_time_data->SetBoolean("phishing", false); | 757 load_time_data->SetBoolean("phishing", false); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 IDS_PHISHING_V3_PRIMARY_PARAGRAPH, | 804 IDS_PHISHING_V3_PRIMARY_PARAGRAPH, |
894 base::UTF8ToUTF16(url_.host()))); | 805 base::UTF8ToUTF16(url_.host()))); |
895 load_time_data->SetString( | 806 load_time_data->SetString( |
896 "explanationParagraph", | 807 "explanationParagraph", |
897 l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH, | 808 l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH, |
898 base::UTF8ToUTF16(url_.host()))); | 809 base::UTF8ToUTF16(url_.host()))); |
899 load_time_data->SetString( | 810 load_time_data->SetString( |
900 "finalParagraph", | 811 "finalParagraph", |
901 l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH)); | 812 l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH)); |
902 } | 813 } |
OLD | NEW |