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
3 // found in the LICENSE file.
5 // Implementation of the SafeBrowsingBlockingPage class.
7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
11 #include "base/bind.h"
12 #include "base/i18n/rtl.h"
13 #include "base/lazy_instance.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/metrics/histogram.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/time.h"
22 #include "base/values.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/google/google_util.h"
25 #include "chrome/browser/history/history_service_factory.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/renderer_preferences_util.h"
28 #include "chrome/browser/safe_browsing/malware_details.h"
29 #include "chrome/browser/safe_browsing/ui_manager.h"
30 #include "chrome/browser/tab_contents/tab_util.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h"
33 #include "content/public/browser/browser_thread.h"
34 #include "content/public/browser/interstitial_page.h"
35 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/user_metrics.h"
37 #include "content/public/browser/web_contents.h"
38 #include "grit/browser_resources.h"
39 #include "grit/chromium_strings.h"
40 #include "grit/generated_resources.h"
41 #include "grit/locale_settings.h"
42 #include "net/base/escape.h"
43 #include "ui/base/l10n/l10n_util.h"
44 #include "ui/base/resource/resource_bundle.h"
45 #include "ui/base/webui/jstemplate_builder.h"
46 #include "ui/base/webui/web_ui_util.h"
48 using content::BrowserThread;
49 using content::InterstitialPage;
50 using content::OpenURLParams;
51 using content::Referrer;
52 using content::UserMetricsAction;
53 using content::WebContents;
57 // For malware interstitial pages, we link the problematic URL to Google's
59 #if defined(GOOGLE_CHROME_BUILD)
60 const char* const kSbDiagnosticUrl =
61 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=googlechrome";
63 const char* const kSbDiagnosticUrl =
64 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=chromium";
67 const char kSbReportPhishingErrorUrl[] =
68 "http://www.google.com/safebrowsing/report_error/";
70 // URL for the "Learn more" link on the multi threat malware blocking page.
71 const char kLearnMoreMalwareUrl[] =
72 "https://www.google.com/support/bin/answer.py?answer=45449&topic=360"
73 "&sa=X&oi=malwarewarninglink&resnum=1&ct=help";
74 const char kLearnMoreMalwareUrlV2[] =
75 "https://www.google.com/goodtoknow/online-safety/malware/";
76 const char kLearnMorePhishingUrlV2[] =
77 "https://www.google.com/goodtoknow/online-safety/phishing/";
79 // URL for the "Learn more" link on the phishing blocking page.
80 const char kLearnMorePhishingUrl[] =
81 "https://www.google.com/support/bin/answer.py?answer=106318";
83 const char kPrivacyLinkHtml[] =
84 "<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand('showPrivacy'); "
85 "return false;\" onmousedown=\"return false;\">%s</a>";
87 // After a malware interstitial where the user opted-in to the report
88 // but clicked "proceed anyway", we delay the call to
89 // MalwareDetails::FinishCollection() by this much time (in
91 const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000;
93 // The commands returned by the page when the user performs an action.
94 const char kShowDiagnosticCommand[] = "showDiagnostic";
95 const char kReportErrorCommand[] = "reportError";
96 const char kLearnMoreCommand[] = "learnMore";
97 const char kLearnMoreCommandV2[] = "learnMore2";
98 const char kShowPrivacyCommand[] = "showPrivacy";
99 const char kProceedCommand[] = "proceed";
100 const char kTakeMeBackCommand[] = "takeMeBack";
101 const char kDoReportCommand[] = "doReport";
102 const char kDontReportCommand[] = "dontReport";
103 const char kDisplayCheckBox[] = "displaycheckbox";
104 const char kBoxChecked[] = "boxchecked";
105 const char kExpandedSeeMore[] = "expandedSeeMore";
106 // Special command that we use when the user navigated away from the
107 // page. E.g., closed the tab or the window. This is only used by
108 // RecordUserReactionTime.
109 const char kNavigatedAwayMetaCommand[] = "closed";
111 base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap>
112 g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER;
114 // These are the conditions for the summer 2013 Finch experiment.
115 // TODO(felt): Get rid of these now that experiment has ended.
116 const char kMalwareStudyName[] = "InterstitialMalware310";
117 const char kPhishingStudyName[] = "InterstitialPhishing564";
118 const char kCond7MalwareFearMsg[] = "cond7MalwareFearMsg";
119 const char kCond8PhishingFearMsg[] = "cond8PhishingFearMsg";
120 const char kCond9MalwareCollabMsg[] = "cond9MalwareCollabMsg";
121 const char kCond10PhishingCollabMsg[] = "cond10PhishingCollabMsg";
122 const char kCond11MalwareQuestion[] = "cond11MalwareQuestion";
123 const char kCond12PhishingQuestion[] = "cond12PhishingQuestion";
124 const char kCond13MalwareGoBack[] = "cond13MalwareGoBack";
125 const char kCond14PhishingGoBack[] = "cond14PhishingGoBack";
127 // This enum is used for a histogram. Don't reorder, delete, or insert
128 // elements. New elements should be added before MAX_ACTION only.
129 enum DetailedDecision {
130 MALWARE_SHOW_NEW_SITE = 0,
131 MALWARE_PROCEED_NEW_SITE,
132 MALWARE_SHOW_CROSS_SITE,
133 MALWARE_PROCEED_CROSS_SITE,
134 PHISHING_SHOW_NEW_SITE,
135 PHISHING_PROCEED_NEW_SITE,
136 PHISHING_SHOW_CROSS_SITE,
137 PHISHING_PROCEED_CROSS_SITE,
141 void RecordDetailedUserAction(DetailedDecision decision) {
142 UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialActionDetails",
144 MAX_DETAILED_ACTION);
150 SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL;
152 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we
154 class SafeBrowsingBlockingPageFactoryImpl
155 : public SafeBrowsingBlockingPageFactory {
157 virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
158 SafeBrowsingUIManager* ui_manager,
159 WebContents* web_contents,
160 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
162 // Only use the V2 page if the interstitial is for a single malware or
163 // phishing resource, the multi-threat interstitial has not been updated to
165 if (unsafe_resources.size() == 1 &&
166 (unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
167 unsafe_resources[0].threat_type ==
168 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL ||
169 unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_PHISHING ||
170 unsafe_resources[0].threat_type ==
171 SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL)) {
172 return new SafeBrowsingBlockingPageV2(ui_manager, web_contents,
175 return new SafeBrowsingBlockingPageV1(ui_manager, web_contents,
180 friend struct base::DefaultLazyInstanceTraits<
181 SafeBrowsingBlockingPageFactoryImpl>;
183 SafeBrowsingBlockingPageFactoryImpl() { }
185 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageFactoryImpl);
188 static base::LazyInstance<SafeBrowsingBlockingPageFactoryImpl>
189 g_safe_browsing_blocking_page_factory_impl = LAZY_INSTANCE_INITIALIZER;
191 SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
192 SafeBrowsingUIManager* ui_manager,
193 WebContents* web_contents,
194 const UnsafeResourceList& unsafe_resources)
195 : malware_details_proceed_delay_ms_(
196 kMalwareDetailsProceedDelayMilliSeconds),
197 ui_manager_(ui_manager),
199 is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)),
200 unsafe_resources_(unsafe_resources),
202 web_contents_(web_contents),
203 url_(unsafe_resources[0].url),
204 has_expanded_see_more_section_(false),
206 bool malware = false;
207 bool phishing = false;
208 for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
209 iter != unsafe_resources_.end(); ++iter) {
210 const UnsafeResource& resource = *iter;
211 SBThreatType threat_type = resource.threat_type;
212 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
213 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
216 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
217 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
221 DCHECK(phishing || malware);
222 if (malware && phishing)
223 interstitial_type_ = TYPE_MALWARE_AND_PHISHING;
225 interstitial_type_ = TYPE_MALWARE;
227 interstitial_type_ = TYPE_PHISHING;
229 RecordUserAction(SHOW);
230 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
231 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
232 Profile::EXPLICIT_ACCESS);
233 if (history_service) {
234 history_service->GetVisibleVisitCountToHost(
237 base::Bind(&SafeBrowsingBlockingPage::OnGotHistoryCount,
238 base::Unretained(this)));
241 if (!is_main_frame_load_blocked_) {
242 navigation_entry_index_to_remove_ =
243 web_contents->GetController().GetLastCommittedEntryIndex();
245 navigation_entry_index_to_remove_ = -1;
248 // Start computing malware details. They will be sent only
249 // if the user opts-in on the blocking page later.
250 // If there's more than one malicious resources, it means the user
251 // clicked through the first warning, so we don't prepare additional
253 if (unsafe_resources.size() == 1 &&
254 unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE &&
255 malware_details_.get() == NULL && CanShowMalwareDetailsOption()) {
256 malware_details_ = MalwareDetails::NewMalwareDetails(
257 ui_manager_, web_contents, unsafe_resources[0]);
260 interstitial_page_ = InterstitialPage::Create(
261 web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this);
264 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() {
265 return (!web_contents_->GetBrowserContext()->IsOffTheRecord() &&
266 web_contents_->GetURL().SchemeIs(content::kHttpScheme));
269 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() {
272 void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) {
273 std::string command(cmd); // Make a local copy so we can modify it.
274 // The Jasonified response has quotes, remove them.
275 if (command.length() > 1 && command[0] == '"') {
276 command = command.substr(1, command.length() - 2);
278 RecordUserReactionTime(command);
279 if (command == kDoReportCommand) {
280 SetReportingPreference(true);
284 if (command == kDontReportCommand) {
285 SetReportingPreference(false);
289 if (command == kLearnMoreCommand) {
290 // User pressed "Learn more".
292 SBThreatType threat_type = unsafe_resources_[0].threat_type;
293 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
294 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
295 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrl));
296 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
297 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
298 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrl));
303 OpenURLParams params(
304 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
305 web_contents_->OpenURL(params);
309 if (command == kLearnMoreCommandV2) {
310 // User pressed "Learn more".
312 SBThreatType threat_type = unsafe_resources_[0].threat_type;
313 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
314 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
315 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrlV2));
316 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
317 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
318 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrlV2));
323 OpenURLParams params(
324 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
325 web_contents_->OpenURL(params);
329 if (command == kShowPrivacyCommand) {
330 // User pressed "Safe Browsing privacy policy".
331 GURL url(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL));
332 OpenURLParams params(
333 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
334 web_contents_->OpenURL(params);
338 bool proceed_blocked = false;
339 if (command == kProceedCommand) {
340 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
341 proceed_blocked = true;
343 interstitial_page_->Proceed();
344 // |this| has been deleted after Proceed() returns.
349 if (command == kTakeMeBackCommand || proceed_blocked) {
350 if (is_main_frame_load_blocked_) {
351 // If the load is blocked, we want to close the interstitial and discard
352 // the pending entry.
353 interstitial_page_->DontProceed();
354 // |this| has been deleted after DontProceed() returns.
358 // Otherwise the offending entry has committed, and we need to go back or
359 // to a safe page. We will close the interstitial when that page commits.
360 if (web_contents_->GetController().CanGoBack()) {
361 web_contents_->GetController().GoBack();
363 web_contents_->GetController().LoadURL(
364 GURL(chrome::kChromeUINewTabURL),
366 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
372 // The "report error" and "show diagnostic" commands can have a number
373 // appended to them, which is the index of the element they apply to.
374 size_t element_index = 0;
375 size_t colon_index = command.find(':');
376 if (colon_index != std::string::npos) {
377 DCHECK(colon_index < command.size() - 1);
379 bool result = base::StringToInt(base::StringPiece(command.begin() +
383 command = command.substr(0, colon_index);
385 element_index = static_cast<size_t>(result_int);
388 if (element_index >= unsafe_resources_.size()) {
393 std::string bad_url_spec = unsafe_resources_[element_index].url.spec();
394 if (command == kReportErrorCommand) {
395 // User pressed "Report error" for a phishing site.
396 // Note that we cannot just put a link in the interstitial at this point.
397 // It is not OK to navigate in the context of an interstitial page.
398 SBThreatType threat_type = unsafe_resources_[element_index].threat_type;
399 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
400 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
402 safe_browsing_util::GeneratePhishingReportUrl(
403 kSbReportPhishingErrorUrl,
405 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
406 OpenURLParams params(
407 report_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
409 web_contents_->OpenURL(params);
413 if (command == kShowDiagnosticCommand) {
414 // We're going to take the user to Google's SafeBrowsing diagnostic page.
415 std::string diagnostic =
416 base::StringPrintf(kSbDiagnosticUrl,
417 net::EscapeQueryParamValue(bad_url_spec, true).c_str());
418 GURL diagnostic_url(diagnostic);
419 diagnostic_url = google_util::AppendGoogleLocaleParam(diagnostic_url);
420 DCHECK(unsafe_resources_[element_index].threat_type ==
421 SB_THREAT_TYPE_URL_MALWARE ||
422 unsafe_resources_[element_index].threat_type ==
423 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL);
424 OpenURLParams params(
425 diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
427 web_contents_->OpenURL(params);
431 if (command == kExpandedSeeMore) {
432 // User expanded the "see more info" section of the page. We don't actually
433 // do any action based on this, it's just so that RecordUserReactionTime can
438 NOTREACHED() << "Unexpected command: " << command;
441 void SafeBrowsingBlockingPage::OverrideRendererPrefs(
442 content::RendererPreferences* prefs) {
443 Profile* profile = Profile::FromBrowserContext(
444 web_contents_->GetBrowserContext());
445 renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
448 void SafeBrowsingBlockingPage::SetReportingPreference(bool report) {
449 Profile* profile = Profile::FromBrowserContext(
450 web_contents_->GetBrowserContext());
451 PrefService* pref = profile->GetPrefs();
452 pref->SetBoolean(prefs::kSafeBrowsingReportingEnabled, report);
455 void SafeBrowsingBlockingPage::OnProceed() {
457 RecordUserAction(PROCEED);
458 // Send the malware details, if we opted to.
459 FinishMalwareDetails(malware_details_proceed_delay_ms_);
461 NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, true);
463 // Check to see if some new notifications of unsafe resources have been
464 // received while we were showing the interstitial.
465 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
466 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
467 SafeBrowsingBlockingPage* blocking_page = NULL;
468 if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
469 // Build an interstitial for all the unsafe resources notifications.
470 // Don't show it now as showing an interstitial while an interstitial is
471 // already showing would cause DontProceed() to be invoked.
472 blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_,
474 unsafe_resource_map->erase(iter);
477 // Now that this interstitial is gone, we can show the new one.
479 blocking_page->interstitial_page_->Show();
482 void SafeBrowsingBlockingPage::OnDontProceed() {
483 // Calling this method twice will not double-count.
484 RecordUserReactionTime(kNavigatedAwayMetaCommand);
485 // We could have already called Proceed(), in which case we must not notify
486 // the SafeBrowsingUIManager again, as the client has been deleted.
490 RecordUserAction(DONT_PROCEED);
491 // Send the malware details, if we opted to.
492 FinishMalwareDetails(0); // No delay
494 NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false);
496 // The user does not want to proceed, clear the queued unsafe resources
497 // notifications we received while the interstitial was showing.
498 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
499 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
500 if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
501 NotifySafeBrowsingUIManager(ui_manager_, iter->second, false);
502 unsafe_resource_map->erase(iter);
505 // We don't remove the navigation entry if the tab is being destroyed as this
506 // would trigger a navigation that would cause trouble as the render view host
507 // for the tab has by then already been destroyed. We also don't delete the
508 // current entry if it has been committed again, which is possible on a page
509 // that had a subresource warning.
510 int last_committed_index =
511 web_contents_->GetController().GetLastCommittedEntryIndex();
512 if (navigation_entry_index_to_remove_ != -1 &&
513 navigation_entry_index_to_remove_ != last_committed_index &&
514 !web_contents_->IsBeingDestroyed()) {
515 CHECK(web_contents_->GetController().RemoveEntryAtIndex(
516 navigation_entry_index_to_remove_));
517 navigation_entry_index_to_remove_ = -1;
521 void SafeBrowsingBlockingPage::OnGotHistoryCount(HistoryService::Handle handle,
524 base::Time first_visit) {
526 num_visits_ = num_visits;
529 void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) {
530 // This enum is used for a histogram. Don't reorder, delete, or insert
531 // elements. New elements should be added before MAX_ACTION only.
534 MALWARE_DONT_PROCEED,
535 MALWARE_FORCED_DONT_PROCEED,
538 MULTIPLE_DONT_PROCEED,
539 MULTIPLE_FORCED_DONT_PROCEED,
542 PHISHING_DONT_PROCEED,
543 PHISHING_FORCED_DONT_PROCEED,
545 MALWARE_SHOW_ADVANCED,
546 MULTIPLE_SHOW_ADVANCED,
547 PHISHING_SHOW_ADVANCED,
549 } histogram_action = MAX_ACTION;
553 switch (interstitial_type_) {
554 case TYPE_MALWARE_AND_PHISHING:
555 histogram_action = MULTIPLE_SHOW;
558 histogram_action = MALWARE_SHOW;
561 histogram_action = PHISHING_SHOW;
566 switch (interstitial_type_) {
567 case TYPE_MALWARE_AND_PHISHING:
568 histogram_action = MULTIPLE_PROCEED;
571 histogram_action = MALWARE_PROCEED;
574 histogram_action = PHISHING_PROCEED;
579 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
580 switch (interstitial_type_) {
581 case TYPE_MALWARE_AND_PHISHING:
582 histogram_action = MULTIPLE_FORCED_DONT_PROCEED;
585 histogram_action = MALWARE_FORCED_DONT_PROCEED;
588 histogram_action = PHISHING_FORCED_DONT_PROCEED;
592 switch (interstitial_type_) {
593 case TYPE_MALWARE_AND_PHISHING:
594 histogram_action = MULTIPLE_DONT_PROCEED;
597 histogram_action = MALWARE_DONT_PROCEED;
600 histogram_action = PHISHING_DONT_PROCEED;
606 switch (interstitial_type_) {
607 case TYPE_MALWARE_AND_PHISHING:
608 histogram_action = MULTIPLE_SHOW_ADVANCED;
611 histogram_action = MALWARE_SHOW_ADVANCED;
614 histogram_action = PHISHING_SHOW_ADVANCED;
619 NOTREACHED() << "Unexpected event: " << event;
621 if (histogram_action == MAX_ACTION) {
624 UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialAction", histogram_action,
628 if (event == PROCEED || event == DONT_PROCEED) {
629 if (num_visits_ == 0 && interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
630 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
631 MALWARE_SHOW_NEW_SITE : PHISHING_SHOW_NEW_SITE);
632 if (event == PROCEED) {
633 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
634 MALWARE_PROCEED_NEW_SITE : PHISHING_PROCEED_NEW_SITE);
637 if (unsafe_resources_[0].is_subresource &&
638 interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
639 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
640 MALWARE_SHOW_CROSS_SITE : PHISHING_SHOW_CROSS_SITE);
641 if (event == PROCEED) {
642 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
643 MALWARE_PROCEED_CROSS_SITE : PHISHING_PROCEED_CROSS_SITE);
648 // TODO(felt): Get rid of the old interstitial histogram.
649 std::string action = "SBInterstitial";
650 switch (interstitial_type_) {
651 case TYPE_MALWARE_AND_PHISHING:
652 action.append("Multiple");
655 action.append("Malware");
658 action.append("Phishing");
664 action.append("Show");
667 action.append("Proceed");
670 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled))
671 action.append("ForcedDontProceed");
673 action.append("DontProceed");
678 NOTREACHED() << "Unexpected event: " << event;
681 content::RecordComputedAction(action);
684 void SafeBrowsingBlockingPage::RecordUserReactionTime(
685 const std::string& command) {
686 if (interstitial_show_time_.is_null())
687 return; // We already reported the user reaction time.
688 base::TimeDelta dt = base::TimeTicks::Now() - interstitial_show_time_;
689 DVLOG(1) << "User reaction time for command:" << command
690 << " on interstitial_type_:" << interstitial_type_
691 << " warning took " << dt.InMilliseconds() << "ms";
692 bool recorded = true;
693 if (interstitial_type_ == TYPE_MALWARE ||
694 interstitial_type_ == TYPE_MALWARE_AND_PHISHING) {
695 // There are six ways in which the malware interstitial can go
696 // away. We handle all of them here but we group two together: closing the
697 // tag / browser window and clicking on the back button in the browser (not
698 // the big green button) are considered the same action.
699 if (command == kProceedCommand) {
700 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeProceed", dt);
701 } else if (command == kTakeMeBackCommand) {
702 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeTakeMeBack", dt);
703 } else if (command == kShowDiagnosticCommand) {
704 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeDiagnostic", dt);
705 } else if (command == kShowPrivacyCommand) {
706 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimePrivacyPolicy",
708 } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
709 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore",
711 } else if (command == kNavigatedAwayMetaCommand) {
712 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt);
713 } else if (command == kExpandedSeeMore) {
714 // Only record the expanded histogram once per display of the
716 if (has_expanded_see_more_section_)
718 RecordUserAction(SHOW_ADVANCED);
719 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore",
721 has_expanded_see_more_section_ = true;
722 // Expanding the "See More" section doesn't finish the interstitial, so
723 // don't mark the reaction time as recorded.
729 // Same as above but for phishing warnings.
730 if (command == kProceedCommand) {
731 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt);
732 } else if (command == kTakeMeBackCommand) {
733 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt);
734 } else if (command == kShowDiagnosticCommand) {
735 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt);
736 } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
737 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt);
738 } else if (command == kNavigatedAwayMetaCommand) {
739 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt);
740 } else if (command == kExpandedSeeMore) {
741 // Only record the expanded histogram once per display of the
743 if (has_expanded_see_more_section_)
745 RecordUserAction(SHOW_ADVANCED);
746 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore",
748 has_expanded_see_more_section_ = true;
749 // Expanding the "See More" section doesn't finish the interstitial, so
750 // don't mark the reaction time as recorded.
756 if (recorded) // Making sure we don't double-count reaction times.
757 interstitial_show_time_ = base::TimeTicks(); // Resets the show time.
760 void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) {
761 if (malware_details_.get() == NULL)
762 return; // Not all interstitials have malware details (eg phishing).
764 if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled)) {
765 // Finish the malware details collection, send it over.
766 BrowserThread::PostDelayedTask(
767 BrowserThread::IO, FROM_HERE,
768 base::Bind(&MalwareDetails::FinishCollection, malware_details_.get()),
769 base::TimeDelta::FromMilliseconds(delay_ms));
773 bool SafeBrowsingBlockingPage::IsPrefEnabled(const char* pref) {
775 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
776 return profile->GetPrefs()->GetBoolean(pref);
780 void SafeBrowsingBlockingPage::NotifySafeBrowsingUIManager(
781 SafeBrowsingUIManager* ui_manager,
782 const UnsafeResourceList& unsafe_resources,
784 BrowserThread::PostTask(
785 BrowserThread::IO, FROM_HERE,
786 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
787 ui_manager, unsafe_resources, proceed));
791 SafeBrowsingBlockingPage::UnsafeResourceMap*
792 SafeBrowsingBlockingPage::GetUnsafeResourcesMap() {
793 return g_unsafe_resource_map.Pointer();
797 void SafeBrowsingBlockingPage::ShowBlockingPage(
798 SafeBrowsingUIManager* ui_manager,
799 const UnsafeResource& unsafe_resource) {
800 DVLOG(1) << __FUNCTION__ << " " << unsafe_resource.url.spec();
801 WebContents* web_contents = tab_util::GetWebContentsByID(
802 unsafe_resource.render_process_host_id, unsafe_resource.render_view_id);
804 InterstitialPage* interstitial =
805 InterstitialPage::GetInterstitialPage(web_contents);
806 if (interstitial && !unsafe_resource.is_subresource) {
807 // There is already an interstitial showing and we are about to display a
808 // new one for the main frame. Just hide the current one, it is now
810 interstitial->DontProceed();
815 // There are no interstitial currently showing in that tab, go ahead and
816 // show this interstitial.
817 std::vector<UnsafeResource> resources;
818 resources.push_back(unsafe_resource);
819 // Set up the factory if this has not been done already (tests do that
820 // before this method is called).
822 factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer();
823 SafeBrowsingBlockingPage* blocking_page =
824 factory_->CreateSafeBrowsingPage(ui_manager, web_contents, resources);
825 blocking_page->interstitial_page_->Show();
829 // This is an interstitial for a page's resource, let's queue it.
830 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
831 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource);
835 bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked(
836 const UnsafeResourceList& unsafe_resources) {
837 // Client-side phishing detection interstitials never block the main frame
838 // load, since they happen after the page is finished loading.
839 if (unsafe_resources[0].threat_type ==
840 SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
844 // Otherwise, check the threat type.
845 return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource;
848 SafeBrowsingBlockingPageV1::SafeBrowsingBlockingPageV1(
849 SafeBrowsingUIManager* ui_manager,
850 WebContents* web_contents,
851 const UnsafeResourceList& unsafe_resources)
852 : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
855 std::string SafeBrowsingBlockingPageV1::GetHTMLContents() {
856 // Load the HTML page and create the template components.
857 DictionaryValue strings;
858 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
861 if (unsafe_resources_.empty()) {
863 return std::string();
866 DCHECK_GT(unsafe_resources_.size(), 1U);
867 PopulateMultipleThreatStringDictionary(&strings);
868 html = rb.GetRawDataResource(
869 IDR_SAFE_BROWSING_MULTIPLE_THREAT_BLOCK).as_string();
870 interstitial_show_time_ = base::TimeTicks::Now();
871 return webui::GetTemplatesHtml(html, &strings, "template_root");
874 void SafeBrowsingBlockingPageV1::PopulateStringDictionary(
875 DictionaryValue* strings,
876 const string16& title,
877 const string16& headline,
878 const string16& description1,
879 const string16& description2,
880 const string16& description3) {
881 strings->SetString("title", title);
882 strings->SetString("headLine", headline);
883 strings->SetString("description1", description1);
884 strings->SetString("description2", description2);
885 strings->SetString("description3", description3);
886 strings->SetBoolean("proceedDisabled",
887 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
890 void SafeBrowsingBlockingPageV1::PopulateMultipleThreatStringDictionary(
891 DictionaryValue* strings) {
893 string16 malware_label =
894 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_LABEL);
895 string16 malware_link =
896 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE);
897 string16 phishing_label =
898 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_LABEL);
899 string16 phishing_link =
900 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_REPORT_ERROR);
902 ListValue* error_strings = new ListValue;
903 for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
904 iter != unsafe_resources_.end(); ++iter) {
905 const UnsafeResource& resource = *iter;
906 SBThreatType threat_type = resource.threat_type;
907 DictionaryValue* current_error_strings = new DictionaryValue;
908 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
909 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
910 current_error_strings->SetString("type", "malware");
911 current_error_strings->SetString("typeLabel", malware_label);
912 current_error_strings->SetString("errorLink", malware_link);
914 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
915 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
916 current_error_strings->SetString("type", "phishing");
917 current_error_strings->SetString("typeLabel", phishing_label);
918 current_error_strings->SetString("errorLink", phishing_link);
920 current_error_strings->SetString("url", resource.url.spec());
921 error_strings->Append(current_error_strings);
923 strings->Set("errors", error_strings);
925 switch (interstitial_type_) {
926 case TYPE_MALWARE_AND_PHISHING:
927 PopulateStringDictionary(
929 // Use the malware headline, it is the scariest one.
930 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MULTI_THREAT_TITLE),
931 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
932 l10n_util::GetStringFUTF16(
933 IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION1,
934 UTF8ToUTF16(web_contents_->GetURL().host())),
935 l10n_util::GetStringUTF16(
936 IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION2),
940 PopulateStringDictionary(
942 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_TITLE),
943 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
944 l10n_util::GetStringFUTF16(
945 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION1,
946 UTF8ToUTF16(web_contents_->GetURL().host())),
947 l10n_util::GetStringUTF16(
948 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION2),
949 l10n_util::GetStringUTF16(
950 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION3));
953 PopulateStringDictionary(
955 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_TITLE),
956 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_HEADLINE),
957 l10n_util::GetStringFUTF16(
958 IDS_SAFE_BROWSING_MULTI_PHISHING_DESCRIPTION1,
959 UTF8ToUTF16(web_contents_->GetURL().host())),
965 strings->SetString("confirm_text",
966 l10n_util::GetStringUTF16(
967 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION_AGREE));
968 strings->SetString("continue_button",
969 l10n_util::GetStringUTF16(
970 IDS_SAFE_BROWSING_MULTI_MALWARE_PROCEED_BUTTON));
971 strings->SetString("back_button",
972 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
973 strings->SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
976 void SafeBrowsingBlockingPageV1::PopulateMalwareStringDictionary(
977 DictionaryValue* strings) {
981 void SafeBrowsingBlockingPageV1::PopulatePhishingStringDictionary(
982 DictionaryValue* strings) {
986 SafeBrowsingBlockingPageV2::SafeBrowsingBlockingPageV2(
987 SafeBrowsingUIManager* ui_manager,
988 WebContents* web_contents,
989 const UnsafeResourceList& unsafe_resources)
990 : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
991 if (unsafe_resources_[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
992 unsafe_resources_[0].threat_type ==
993 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
995 base::FieldTrialList::FindFullName(kMalwareStudyName);
996 } else if (unsafe_resources_[0].threat_type ==
997 SB_THREAT_TYPE_URL_PHISHING ||
998 unsafe_resources_[0].threat_type ==
999 SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
1001 base::FieldTrialList::FindFullName(kPhishingStudyName);
1005 std::string SafeBrowsingBlockingPageV2::GetHTMLContents() {
1006 // Load the HTML page and create the template components.
1007 DictionaryValue strings;
1008 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1011 if (unsafe_resources_.empty()) {
1013 return std::string();
1016 if (unsafe_resources_.size() > 1) {
1017 // TODO(felt): Implement new multi-threat interstitial and remove
1018 // SafeBrowsingBlockingPageV1 entirely. (http://crbug.com/160336)
1021 SBThreatType threat_type = unsafe_resources_[0].threat_type;
1022 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
1023 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
1024 PopulateMalwareStringDictionary(&strings);
1025 } else { // Phishing.
1026 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
1027 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
1028 PopulatePhishingStringDictionary(&strings);
1030 html = rb.GetRawDataResource(IDR_SAFE_BROWSING_MALWARE_BLOCK_V2).
1033 interstitial_show_time_ = base::TimeTicks::Now();
1034 return webui::GetTemplatesHtml(html, &strings, "template-root");
1037 void SafeBrowsingBlockingPageV2::PopulateStringDictionary(
1038 DictionaryValue* strings,
1039 const string16& title,
1040 const string16& headline,
1041 const string16& description1,
1042 const string16& description2,
1043 const string16& description3) {
1044 strings->SetString("title", title);
1045 strings->SetString("headLine", headline);
1046 strings->SetString("description1", description1);
1047 strings->SetString("description2", description2);
1048 strings->SetString("description3", description3);
1049 strings->SetBoolean("proceedDisabled",
1050 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
1051 strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_);
1052 strings->SetBoolean("isPhishing", interstitial_type_ == TYPE_PHISHING);
1054 strings->SetString("back_button",
1055 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
1056 strings->SetString("seeMore", l10n_util::GetStringUTF16(
1057 IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE));
1058 strings->SetString("proceed",
1059 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK));
1062 strings->SetString("trialType", trialCondition_);
1063 if (trialCondition_ == kCond7MalwareFearMsg) {
1064 strings->SetString("headLine",
1065 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_FEAR_HEADLINE));
1066 } else if (trialCondition_ == kCond8PhishingFearMsg) {
1067 strings->SetString("headLine",
1068 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_FEAR_HEADLINE));
1069 } else if (trialCondition_ == kCond9MalwareCollabMsg) {
1070 strings->SetString("headLine",
1071 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_COLLAB_HEADLINE));
1072 } else if (trialCondition_ == kCond10PhishingCollabMsg) {
1073 strings->SetString("headLine",
1074 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_COLLAB_HEADLINE));
1075 } else if (trialCondition_ == kCond11MalwareQuestion) {
1076 strings->SetString("headLine",
1077 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_QUESTION_HEADLINE));
1078 } else if (trialCondition_ == kCond12PhishingQuestion) {
1079 strings->SetString("headLine",
1080 l10n_util::GetStringUTF16(
1081 IDS_SAFE_BROWSING_PHISHING_QUESTION_HEADLINE));
1082 } else if (trialCondition_ == kCond13MalwareGoBack) {
1083 strings->SetString("headLine",
1084 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_HEADLINE));
1085 } else if (trialCondition_ == kCond14PhishingGoBack) {
1086 strings->SetString("headLine",
1087 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_BACK_HEADLINE));
1090 webui::SetFontAndTextDirection(strings);
1093 void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary(
1094 DictionaryValue* strings) {
1098 void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary(
1099 DictionaryValue* strings) {
1100 // Check to see if we're blocking the main page, or a sub-resource on the
1102 string16 headline, description1, description2, description3;
1105 description3 = l10n_util::GetStringUTF16(
1106 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION3);
1107 if (is_main_frame_load_blocked_) {
1108 headline = l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE);
1109 description1 = l10n_util::GetStringFUTF16(
1110 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1,
1111 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1112 UTF8ToUTF16(url_.host()));
1113 description2 = l10n_util::GetStringUTF16(
1114 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2);
1115 strings->SetString("details", l10n_util::GetStringUTF16(
1116 IDS_SAFE_BROWSING_MALWARE_V2_DETAILS));
1118 headline = l10n_util::GetStringUTF16(
1119 IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE_SUBRESOURCE);
1120 description1 = l10n_util::GetStringFUTF16(
1121 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1_SUBRESOURCE,
1122 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1123 UTF8ToUTF16(web_contents_->GetURL().host()));
1124 description2 = l10n_util::GetStringFUTF16(
1125 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2_SUBRESOURCE,
1126 UTF8ToUTF16(url_.host()));
1127 strings->SetString("details", l10n_util::GetStringFUTF16(
1128 IDS_SAFE_BROWSING_MALWARE_V2_DETAILS_SUBRESOURCE,
1129 UTF8ToUTF16(url_.host())));
1132 PopulateStringDictionary(
1134 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_TITLE),
1140 if (!CanShowMalwareDetailsOption()) {
1141 strings->SetBoolean(kDisplayCheckBox, false);
1142 strings->SetString("confirm_text", std::string());
1143 strings->SetString(kBoxChecked, std::string());
1145 // Show the checkbox for sending malware details.
1146 strings->SetBoolean(kDisplayCheckBox, true);
1148 std::string privacy_link = base::StringPrintf(
1150 l10n_util::GetStringUTF8(
1151 IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2).c_str());
1153 strings->SetString("confirm_text",
1154 l10n_util::GetStringFUTF16(
1155 IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE,
1156 UTF8ToUTF16(privacy_link)));
1157 if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled))
1158 strings->SetString(kBoxChecked, "yes");
1160 strings->SetString(kBoxChecked, std::string());
1163 strings->SetString("report_error", string16());
1164 strings->SetString("learnMore",
1165 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
1168 void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary(
1169 DictionaryValue* strings) {
1170 PopulateStringDictionary(
1172 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_TITLE),
1173 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE),
1174 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1,
1175 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1176 UTF8ToUTF16(url_.host())),
1178 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2));
1180 strings->SetString("details", std::string());
1181 strings->SetString("confirm_text", std::string());
1182 strings->SetString(kBoxChecked, std::string());
1185 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR));
1186 strings->SetBoolean(kDisplayCheckBox, false);
1187 strings->SetString("learnMore",
1188 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));