safe_browsing_loud_error_ui.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. // Copyright 2016 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.
  4. #include "components/security_interstitials/core/safe_browsing_loud_error_ui.h"
  5. #include "base/i18n/time_formatting.h"
  6. #include "base/metrics/histogram_macros.h"
  7. #include "base/strings/escape.h"
  8. #include "base/strings/stringprintf.h"
  9. #include "base/strings/utf_string_conversions.h"
  10. #include "base/values.h"
  11. #include "components/google/core/common/google_util.h"
  12. #include "components/grit/components_resources.h"
  13. #include "components/security_interstitials/core/common_string_util.h"
  14. #include "components/security_interstitials/core/controller_client.h"
  15. #include "components/security_interstitials/core/metrics_helper.h"
  16. #include "components/strings/grit/components_strings.h"
  17. #include "net/base/url_util.h"
  18. #include "ui/base/l10n/l10n_util.h"
  19. namespace security_interstitials {
  20. namespace {
  21. // For malware interstitial pages, we link the problematic URL to Google's
  22. // diagnostic page.
  23. const char kSbDiagnosticUrl[] =
  24. "https://transparencyreport.google.com/safe-browsing/search?url=%s";
  25. // Constants for the V4 phishing string upgrades.
  26. const char kReportPhishingErrorUrl[] =
  27. "https://safebrowsing.google.com/safebrowsing/report_error/?url=%s";
  28. void RecordExtendedReportingPrefChanged(bool report) {
  29. UMA_HISTOGRAM_BOOLEAN("SafeBrowsing.Pref.Extended.SecurityInterstitial",
  30. report);
  31. }
  32. } // namespace
  33. SafeBrowsingLoudErrorUI::SafeBrowsingLoudErrorUI(
  34. const GURL& request_url,
  35. const GURL& main_frame_url,
  36. SBInterstitialReason reason,
  37. const SBErrorDisplayOptions& display_options,
  38. const std::string& app_locale,
  39. const base::Time& time_triggered,
  40. ControllerClient* controller,
  41. bool created_prior_to_navigation)
  42. : BaseSafeBrowsingErrorUI(request_url,
  43. main_frame_url,
  44. reason,
  45. display_options,
  46. app_locale,
  47. time_triggered,
  48. controller),
  49. created_prior_to_navigation_(created_prior_to_navigation) {
  50. controller->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
  51. controller->metrics_helper()->RecordUserInteraction(
  52. MetricsHelper::TOTAL_VISITS);
  53. if (is_proceed_anyway_disabled()) {
  54. controller->metrics_helper()->RecordUserDecision(
  55. security_interstitials::MetricsHelper::PROCEEDING_DISABLED);
  56. }
  57. }
  58. SafeBrowsingLoudErrorUI::~SafeBrowsingLoudErrorUI() {
  59. controller()->metrics_helper()->RecordShutdownMetrics();
  60. }
  61. void SafeBrowsingLoudErrorUI::PopulateStringsForHtml(
  62. base::Value::Dict& load_time_data) {
  63. load_time_data.Set("type", "SAFEBROWSING");
  64. load_time_data.Set("tabTitle",
  65. l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_TITLE));
  66. load_time_data.Set(
  67. "openDetails",
  68. l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_OPEN_DETAILS_BUTTON));
  69. load_time_data.Set(
  70. "closeDetails",
  71. l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_CLOSE_DETAILS_BUTTON));
  72. load_time_data.Set(
  73. "primaryButtonText",
  74. l10n_util::GetStringUTF16(IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON));
  75. load_time_data.Set("overridable", !is_proceed_anyway_disabled());
  76. load_time_data.Set(
  77. security_interstitials::kOptInLink,
  78. l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_SCOUT_REPORTING_AGREE));
  79. load_time_data.Set(
  80. security_interstitials::kEnhancedProtectionMessage,
  81. l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_ENHANCED_PROTECTION_MESSAGE));
  82. if (always_show_back_to_safety()) {
  83. load_time_data.Set("hide_primary_button", false);
  84. } else {
  85. load_time_data.Set("hide_primary_button",
  86. created_prior_to_navigation_
  87. ? !controller()->CanGoBackBeforeNavigation()
  88. : !controller()->CanGoBack());
  89. }
  90. load_time_data.Set("billing", interstitial_reason() ==
  91. BaseSafeBrowsingErrorUI::SB_REASON_BILLING);
  92. switch (interstitial_reason()) {
  93. case BaseSafeBrowsingErrorUI::SB_REASON_MALWARE:
  94. PopulateMalwareLoadTimeData(load_time_data);
  95. break;
  96. case BaseSafeBrowsingErrorUI::SB_REASON_HARMFUL:
  97. PopulateHarmfulLoadTimeData(load_time_data);
  98. break;
  99. case BaseSafeBrowsingErrorUI::SB_REASON_PHISHING:
  100. PopulatePhishingLoadTimeData(load_time_data);
  101. break;
  102. case BaseSafeBrowsingErrorUI::SB_REASON_BILLING:
  103. PopulateBillingLoadTimeData(load_time_data);
  104. break;
  105. }
  106. // Not used by this interstitial.
  107. load_time_data.Set("recurrentErrorParagraph", "");
  108. load_time_data.Set("show_recurrent_error_paragraph", false);
  109. PopulateExtendedReportingOption(load_time_data);
  110. PopulateEnhancedProtectionMessage(load_time_data);
  111. }
  112. void SafeBrowsingLoudErrorUI::HandleCommand(
  113. SecurityInterstitialCommand command) {
  114. switch (command) {
  115. case CMD_PROCEED: {
  116. // User pressed on the button to proceed.
  117. if (!is_proceed_anyway_disabled()) {
  118. controller()->metrics_helper()->RecordUserDecision(
  119. MetricsHelper::PROCEED);
  120. controller()->Proceed();
  121. break;
  122. }
  123. // If the user can't proceed, fall through to CMD_DONT_PROCEED.
  124. [[fallthrough]];
  125. }
  126. case CMD_DONT_PROCEED: {
  127. // User pressed on the button to return to safety.
  128. // Don't record the user action here because there are other ways of
  129. // triggering DontProceed, like clicking the back button.
  130. if (is_main_frame_load_blocked()) {
  131. // If the load is blocked, we want to close the interstitial and discard
  132. // the pending entry.
  133. controller()->GoBack();
  134. } else {
  135. // Otherwise the offending entry has committed, and we need to go back
  136. // or to a safe page. We will close the interstitial when that page
  137. // commits.
  138. controller()->GoBackAfterNavigationCommitted();
  139. }
  140. break;
  141. }
  142. case CMD_DO_REPORT: {
  143. // User enabled SB Extended Reporting via the checkbox.
  144. set_extended_reporting(true);
  145. controller()->SetReportingPreference(true);
  146. RecordExtendedReportingPrefChanged(true);
  147. break;
  148. }
  149. case CMD_DONT_REPORT: {
  150. // User disabled SB Extended Reporting via the checkbox.
  151. set_extended_reporting(false);
  152. controller()->SetReportingPreference(false);
  153. RecordExtendedReportingPrefChanged(false);
  154. break;
  155. }
  156. case CMD_SHOW_MORE_SECTION: {
  157. controller()->metrics_helper()->RecordUserInteraction(
  158. security_interstitials::MetricsHelper::SHOW_ADVANCED);
  159. break;
  160. }
  161. case CMD_OPEN_HELP_CENTER: {
  162. // User pressed "Learn more".
  163. controller()->metrics_helper()->RecordUserInteraction(
  164. security_interstitials::MetricsHelper::SHOW_LEARN_MORE);
  165. GURL learn_more_url = controller()->GetBaseHelpCenterUrl();
  166. learn_more_url = net::AppendQueryParameter(
  167. learn_more_url, "p", get_help_center_article_link());
  168. learn_more_url =
  169. google_util::AppendGoogleLocaleParam(learn_more_url, app_locale());
  170. controller()->OpenURL(should_open_links_in_new_tab(), learn_more_url);
  171. break;
  172. }
  173. case CMD_RELOAD: {
  174. controller()->metrics_helper()->RecordUserInteraction(
  175. security_interstitials::MetricsHelper::RELOAD);
  176. controller()->Reload();
  177. break;
  178. }
  179. case CMD_OPEN_REPORTING_PRIVACY: {
  180. // User pressed on the SB Extended Reporting "privacy policy" link.
  181. controller()->OpenExtendedReportingPrivacyPolicy(
  182. should_open_links_in_new_tab());
  183. break;
  184. }
  185. case CMD_OPEN_WHITEPAPER: {
  186. controller()->OpenExtendedReportingWhitepaper(
  187. should_open_links_in_new_tab());
  188. break;
  189. }
  190. case CMD_OPEN_DIAGNOSTIC: {
  191. controller()->metrics_helper()->RecordUserInteraction(
  192. security_interstitials::MetricsHelper::SHOW_DIAGNOSTIC);
  193. std::string diagnostic = base::StringPrintf(
  194. kSbDiagnosticUrl,
  195. base::EscapeQueryParamValue(request_url().spec(), true).c_str());
  196. GURL diagnostic_url(diagnostic);
  197. diagnostic_url =
  198. google_util::AppendGoogleLocaleParam(diagnostic_url, app_locale());
  199. controller()->OpenURL(should_open_links_in_new_tab(), diagnostic_url);
  200. break;
  201. }
  202. case CMD_REPORT_PHISHING_ERROR: {
  203. controller()->metrics_helper()->RecordUserInteraction(
  204. security_interstitials::MetricsHelper::REPORT_PHISHING_ERROR);
  205. std::string phishing_error = base::StringPrintf(
  206. kReportPhishingErrorUrl,
  207. base::EscapeQueryParamValue(request_url().spec(), true).c_str());
  208. GURL phishing_error_url(phishing_error);
  209. phishing_error_url = google_util::AppendGoogleLocaleParam(
  210. phishing_error_url, app_locale());
  211. controller()->OpenURL(should_open_links_in_new_tab(), phishing_error_url);
  212. break;
  213. }
  214. case CMD_OPEN_ENHANCED_PROTECTION_SETTINGS: {
  215. controller()->metrics_helper()->RecordUserInteraction(
  216. security_interstitials::MetricsHelper::OPEN_ENHANCED_PROTECTION);
  217. controller()->OpenEnhancedProtectionSettings();
  218. break;
  219. }
  220. case CMD_OPEN_DATE_SETTINGS:
  221. case CMD_OPEN_LOGIN:
  222. case CMD_ERROR:
  223. case CMD_TEXT_FOUND:
  224. case CMD_TEXT_NOT_FOUND:
  225. break;
  226. }
  227. }
  228. void SafeBrowsingLoudErrorUI::PopulateMalwareLoadTimeData(
  229. base::Value::Dict& load_time_data) {
  230. load_time_data.Set("phishing", false);
  231. load_time_data.Set("heading",
  232. l10n_util::GetStringUTF16(IDS_MALWARE_V3_HEADING));
  233. load_time_data.Set(
  234. "primaryParagraph",
  235. l10n_util::GetStringFUTF16(
  236. IDS_MALWARE_V3_PRIMARY_PARAGRAPH,
  237. common_string_util::GetFormattedHostName(request_url())));
  238. load_time_data.Set(
  239. "explanationParagraph",
  240. is_main_frame_load_blocked()
  241. ? l10n_util::GetStringFUTF16(
  242. IDS_MALWARE_V3_EXPLANATION_PARAGRAPH,
  243. common_string_util::GetFormattedHostName(request_url()))
  244. : l10n_util::GetStringFUTF16(
  245. IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE,
  246. base::UTF8ToUTF16(main_frame_url().host()),
  247. common_string_util::GetFormattedHostName(request_url())));
  248. load_time_data.Set("finalParagraph", l10n_util::GetStringUTF16(
  249. IDS_MALWARE_V3_PROCEED_PARAGRAPH));
  250. }
  251. void SafeBrowsingLoudErrorUI::PopulateHarmfulLoadTimeData(
  252. base::Value::Dict& load_time_data) {
  253. load_time_data.Set("phishing", false);
  254. load_time_data.Set("heading",
  255. l10n_util::GetStringUTF16(IDS_HARMFUL_V3_HEADING));
  256. load_time_data.Set(
  257. "primaryParagraph",
  258. l10n_util::GetStringFUTF16(
  259. IDS_HARMFUL_V3_PRIMARY_PARAGRAPH,
  260. common_string_util::GetFormattedHostName(request_url())));
  261. load_time_data.Set(
  262. "explanationParagraph",
  263. l10n_util::GetStringFUTF16(
  264. IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH,
  265. common_string_util::GetFormattedHostName(request_url())));
  266. load_time_data.Set("finalParagraph", l10n_util::GetStringUTF16(
  267. IDS_HARMFUL_V3_PROCEED_PARAGRAPH));
  268. }
  269. void SafeBrowsingLoudErrorUI::PopulatePhishingLoadTimeData(
  270. base::Value::Dict& load_time_data) {
  271. load_time_data.Set("phishing", true);
  272. load_time_data.Set("heading",
  273. l10n_util::GetStringUTF16(IDS_PHISHING_V4_HEADING));
  274. load_time_data.Set(
  275. "primaryParagraph",
  276. l10n_util::GetStringFUTF16(
  277. IDS_PHISHING_V4_PRIMARY_PARAGRAPH,
  278. common_string_util::GetFormattedHostName(request_url())));
  279. load_time_data.Set(
  280. "explanationParagraph",
  281. l10n_util::GetStringFUTF16(
  282. IDS_PHISHING_V4_EXPLANATION_PARAGRAPH,
  283. common_string_util::GetFormattedHostName(request_url())));
  284. load_time_data.Set(
  285. "finalParagraph",
  286. l10n_util::GetStringUTF16(IDS_PHISHING_V4_PROCEED_AND_REPORT_PARAGRAPH));
  287. }
  288. void SafeBrowsingLoudErrorUI::PopulateExtendedReportingOption(
  289. base::Value::Dict& load_time_data) {
  290. bool can_show_extended_reporting_option = CanShowExtendedReportingOption();
  291. bool can_show_enhanced_protection_message =
  292. CanShowEnhancedProtectionMessage();
  293. load_time_data.Set(security_interstitials::kDisplayCheckBox,
  294. can_show_extended_reporting_option &&
  295. !can_show_enhanced_protection_message);
  296. if (!can_show_extended_reporting_option) {
  297. return;
  298. }
  299. load_time_data.Set(security_interstitials::kBoxChecked,
  300. is_extended_reporting_enabled());
  301. }
  302. void SafeBrowsingLoudErrorUI::PopulateEnhancedProtectionMessage(
  303. base::Value::Dict& load_time_data) {
  304. bool can_show_enhanced_protection_message =
  305. CanShowEnhancedProtectionMessage();
  306. if (can_show_enhanced_protection_message) {
  307. controller()->metrics_helper()->RecordUserInteraction(
  308. security_interstitials::MetricsHelper::SHOW_ENHANCED_PROTECTION);
  309. }
  310. load_time_data.Set(security_interstitials::kDisplayEnhancedProtectionMessage,
  311. can_show_enhanced_protection_message);
  312. }
  313. void SafeBrowsingLoudErrorUI::PopulateBillingLoadTimeData(
  314. base::Value::Dict& load_time_data) {
  315. load_time_data.Set("phishing", false);
  316. load_time_data.Set("overridable", true);
  317. load_time_data.Set("tabTitle", l10n_util::GetStringUTF16(IDS_BILLING_TITLE));
  318. load_time_data.Set("heading", l10n_util::GetStringUTF16(IDS_BILLING_HEADING));
  319. load_time_data.Set("primaryParagraph",
  320. l10n_util::GetStringUTF16(IDS_BILLING_PRIMARY_PARAGRAPH));
  321. load_time_data.Set("primaryButtonText",
  322. l10n_util::GetStringUTF16(IDS_BILLING_PRIMARY_BUTTON));
  323. load_time_data.Set("proceedButtonText",
  324. l10n_util::GetStringUTF16(IDS_BILLING_PROCEED_BUTTON));
  325. load_time_data.Set("openDetails", "");
  326. load_time_data.Set("closeDetails", "");
  327. load_time_data.Set("explanationParagraph", "");
  328. load_time_data.Set("finalParagraph", "");
  329. }
  330. int SafeBrowsingLoudErrorUI::GetHTMLTemplateId() const {
  331. return IDR_SECURITY_INTERSTITIAL_HTML;
  332. }
  333. } // namespace security_interstitials