blob: a795a92341e6c9e17eb45b191169e5f524a4fa4d [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/security_interstitials/core/safe_browsing_loud_error_ui.h"
#include "base/i18n/time_formatting.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "components/google/core/common/google_util.h"
#include "components/grit/components_resources.h"
#include "components/security_interstitials/core/common_string_util.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/strings/grit/components_strings.h"
#include "net/base/escape.h"
#include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h"
namespace security_interstitials {
namespace {
// For malware interstitial pages, we link the problematic URL to Google's
// diagnostic page.
const char kSbDiagnosticUrl[] =
"https://transparencyreport.google.com/safe-browsing/search?url=%s";
// Constants for the V4 phishing string upgrades.
const char kReportPhishingErrorUrl[] =
"https://www.google.com/safebrowsing/report_error/";
void RecordExtendedReportingPrefChanged(bool report) {
UMA_HISTOGRAM_BOOLEAN(
"SafeBrowsing.Pref.Scout.SetPref.SBER2Pref.SecurityInterstitial", report);
}
} // namespace
SafeBrowsingLoudErrorUI::SafeBrowsingLoudErrorUI(
const GURL& request_url,
const GURL& main_frame_url,
SBInterstitialReason reason,
const SBErrorDisplayOptions& display_options,
const std::string& app_locale,
const base::Time& time_triggered,
ControllerClient* controller)
: BaseSafeBrowsingErrorUI(request_url,
main_frame_url,
reason,
display_options,
app_locale,
time_triggered,
controller) {
controller->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
controller->metrics_helper()->RecordUserInteraction(
MetricsHelper::TOTAL_VISITS);
if (is_proceed_anyway_disabled()) {
controller->metrics_helper()->RecordUserDecision(
security_interstitials::MetricsHelper::PROCEEDING_DISABLED);
}
}
SafeBrowsingLoudErrorUI::~SafeBrowsingLoudErrorUI() {
controller()->metrics_helper()->RecordShutdownMetrics();
}
void SafeBrowsingLoudErrorUI::PopulateStringsForHtml(
base::DictionaryValue* load_time_data) {
DCHECK(load_time_data);
load_time_data->SetString("type", "SAFEBROWSING");
load_time_data->SetString(
"tabTitle", l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_TITLE));
load_time_data->SetString(
"openDetails",
l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_OPEN_DETAILS_BUTTON));
load_time_data->SetString(
"closeDetails",
l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_CLOSE_DETAILS_BUTTON));
load_time_data->SetString(
"primaryButtonText",
l10n_util::GetStringUTF16(IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON));
load_time_data->SetBoolean("overridable", !is_proceed_anyway_disabled());
load_time_data->SetBoolean(
"hide_primary_button",
always_show_back_to_safety() ? false : !controller()->CanGoBack());
load_time_data->SetBoolean(
"billing",
interstitial_reason() == BaseSafeBrowsingErrorUI::SB_REASON_BILLING);
switch (interstitial_reason()) {
case BaseSafeBrowsingErrorUI::SB_REASON_MALWARE:
PopulateMalwareLoadTimeData(load_time_data);
break;
case BaseSafeBrowsingErrorUI::SB_REASON_HARMFUL:
PopulateHarmfulLoadTimeData(load_time_data);
break;
case BaseSafeBrowsingErrorUI::SB_REASON_PHISHING:
PopulatePhishingLoadTimeData(load_time_data);
break;
case BaseSafeBrowsingErrorUI::SB_REASON_BILLING:
PopulateBillingLoadTimeData(load_time_data);
break;
}
// Not used by this interstitial.
load_time_data->SetString("recurrentErrorParagraph", "");
load_time_data->SetBoolean("show_recurrent_error_paragraph", false);
PopulateExtendedReportingOption(load_time_data);
}
void SafeBrowsingLoudErrorUI::HandleCommand(
SecurityInterstitialCommand command) {
switch (command) {
case CMD_PROCEED: {
// User pressed on the button to proceed.
if (!is_proceed_anyway_disabled()) {
controller()->metrics_helper()->RecordUserDecision(
MetricsHelper::PROCEED);
controller()->Proceed();
break;
}
// If the user can't proceed, fall through to CMD_DONT_PROCEED.
FALLTHROUGH;
}
case CMD_DONT_PROCEED: {
// User pressed on the button to return to safety.
// Don't record the user action here because there are other ways of
// triggering DontProceed, like clicking the back button.
if (is_main_frame_load_blocked()) {
// If the load is blocked, we want to close the interstitial and discard
// the pending entry.
controller()->GoBack();
} else {
// Otherwise the offending entry has committed, and we need to go back
// or to a safe page. We will close the interstitial when that page
// commits.
controller()->GoBackAfterNavigationCommitted();
}
break;
}
case CMD_DO_REPORT: {
// User enabled SB Extended Reporting via the checkbox.
set_extended_reporting(true);
controller()->SetReportingPreference(true);
RecordExtendedReportingPrefChanged(true);
break;
}
case CMD_DONT_REPORT: {
// User disabled SB Extended Reporting via the checkbox.
set_extended_reporting(false);
controller()->SetReportingPreference(false);
RecordExtendedReportingPrefChanged(false);
break;
}
case CMD_SHOW_MORE_SECTION: {
controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::SHOW_ADVANCED);
break;
}
case CMD_OPEN_HELP_CENTER: {
// User pressed "Learn more".
controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::SHOW_LEARN_MORE);
GURL learn_more_url = controller()->GetBaseHelpCenterUrl();
learn_more_url = net::AppendQueryParameter(
learn_more_url, "p", get_help_center_article_link());
learn_more_url =
google_util::AppendGoogleLocaleParam(learn_more_url, app_locale());
controller()->OpenURL(should_open_links_in_new_tab(), learn_more_url);
break;
}
case CMD_RELOAD: {
controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::RELOAD);
controller()->Reload();
break;
}
case CMD_OPEN_REPORTING_PRIVACY: {
// User pressed on the SB Extended Reporting "privacy policy" link.
controller()->OpenExtendedReportingPrivacyPolicy(
should_open_links_in_new_tab());
break;
}
case CMD_OPEN_WHITEPAPER: {
controller()->OpenExtendedReportingWhitepaper(
should_open_links_in_new_tab());
break;
}
case CMD_OPEN_DIAGNOSTIC: {
controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::SHOW_DIAGNOSTIC);
std::string diagnostic = base::StringPrintf(
kSbDiagnosticUrl,
net::EscapeQueryParamValue(request_url().spec(), true).c_str());
GURL diagnostic_url(diagnostic);
diagnostic_url =
google_util::AppendGoogleLocaleParam(diagnostic_url, app_locale());
controller()->OpenURL(should_open_links_in_new_tab(), diagnostic_url);
break;
}
case CMD_REPORT_PHISHING_ERROR: {
controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::REPORT_PHISHING_ERROR);
GURL phishing_error_url(kReportPhishingErrorUrl);
phishing_error_url = google_util::AppendGoogleLocaleParam(
phishing_error_url, app_locale());
controller()->OpenURL(should_open_links_in_new_tab(), phishing_error_url);
break;
}
case CMD_OPEN_DATE_SETTINGS:
case CMD_OPEN_LOGIN:
case CMD_ERROR:
case CMD_TEXT_FOUND:
case CMD_TEXT_NOT_FOUND:
break;
}
}
void SafeBrowsingLoudErrorUI::PopulateMalwareLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", false);
load_time_data->SetString("heading",
l10n_util::GetStringUTF16(IDS_MALWARE_V3_HEADING));
load_time_data->SetString(
"primaryParagraph",
l10n_util::GetStringFUTF16(
IDS_MALWARE_V3_PRIMARY_PARAGRAPH,
common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"explanationParagraph",
is_main_frame_load_blocked()
? l10n_util::GetStringFUTF16(
IDS_MALWARE_V3_EXPLANATION_PARAGRAPH,
common_string_util::GetFormattedHostName(request_url()))
: l10n_util::GetStringFUTF16(
IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE,
base::UTF8ToUTF16(main_frame_url().host()),
common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"finalParagraph",
l10n_util::GetStringUTF16(IDS_MALWARE_V3_PROCEED_PARAGRAPH));
}
void SafeBrowsingLoudErrorUI::PopulateHarmfulLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", false);
load_time_data->SetString("heading",
l10n_util::GetStringUTF16(IDS_HARMFUL_V3_HEADING));
load_time_data->SetString(
"primaryParagraph",
l10n_util::GetStringFUTF16(
IDS_HARMFUL_V3_PRIMARY_PARAGRAPH,
common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"explanationParagraph",
l10n_util::GetStringFUTF16(
IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH,
common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"finalParagraph",
l10n_util::GetStringUTF16(IDS_HARMFUL_V3_PROCEED_PARAGRAPH));
}
void SafeBrowsingLoudErrorUI::PopulatePhishingLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", true);
load_time_data->SetString("heading",
l10n_util::GetStringUTF16(IDS_PHISHING_V4_HEADING));
load_time_data->SetString(
"primaryParagraph",
l10n_util::GetStringFUTF16(
IDS_PHISHING_V4_PRIMARY_PARAGRAPH,
common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"explanationParagraph",
l10n_util::GetStringFUTF16(
IDS_PHISHING_V4_EXPLANATION_PARAGRAPH,
common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"finalParagraph",
l10n_util::GetStringUTF16(IDS_PHISHING_V4_PROCEED_AND_REPORT_PARAGRAPH));
}
void SafeBrowsingLoudErrorUI::PopulateExtendedReportingOption(
base::DictionaryValue* load_time_data) {
bool can_show_extended_reporting_option = CanShowExtendedReportingOption();
load_time_data->SetBoolean(security_interstitials::kDisplayCheckBox,
can_show_extended_reporting_option);
if (!can_show_extended_reporting_option) {
return;
}
const std::string privacy_link = base::StringPrintf(
security_interstitials::kPrivacyLinkHtml,
security_interstitials::CMD_OPEN_REPORTING_PRIVACY,
l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str());
load_time_data->SetString(
security_interstitials::kOptInLink,
l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_SCOUT_REPORTING_AGREE,
base::UTF8ToUTF16(privacy_link)));
load_time_data->SetBoolean(security_interstitials::kBoxChecked,
is_extended_reporting_enabled());
}
void SafeBrowsingLoudErrorUI::PopulateBillingLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", false);
load_time_data->SetBoolean("overridable", true);
load_time_data->SetString("heading",
l10n_util::GetStringUTF16(IDS_BILLING_HEADING));
load_time_data->SetString(
"primaryParagraph",
l10n_util::GetStringUTF16(IDS_BILLING_PRIMARY_PARAGRAPH));
load_time_data->SetString(
"primaryButtonText",
l10n_util::GetStringUTF16(IDS_BILLING_PRIMARY_BUTTON));
load_time_data->SetString(
"proceedButtonText",
l10n_util::GetStringUTF16(IDS_BILLING_PROCEED_BUTTON));
load_time_data->SetString("openDetails", "");
load_time_data->SetString("closeDetails", "");
load_time_data->SetString("explanationParagraph", "");
load_time_data->SetString("finalParagraph", "");
}
int SafeBrowsingLoudErrorUI::GetHTMLTemplateId() const {
return IDR_SECURITY_INTERSTITIAL_HTML;
}
} // namespace security_interstitials