| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&clie
nt=chromium"; | 62 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&clie
nt=chromium"; |
| 63 #endif | 63 #endif |
| 64 | 64 |
| 65 // URL for malware and phishing, V2. | 65 // URL for malware and phishing, V2. |
| 66 const char kLearnMoreMalwareUrlV2[] = | 66 const char kLearnMoreMalwareUrlV2[] = |
| 67 "https://www.google.com/transparencyreport/safebrowsing/"; | 67 "https://www.google.com/transparencyreport/safebrowsing/"; |
| 68 const char kLearnMorePhishingUrlV2[] = | 68 const char kLearnMorePhishingUrlV2[] = |
| 69 "https://www.google.com/transparencyreport/safebrowsing/"; | 69 "https://www.google.com/transparencyreport/safebrowsing/"; |
| 70 | 70 |
| 71 const char kPrivacyLinkHtml[] = | 71 const char kPrivacyLinkHtml[] = |
| 72 "<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand('showPrivacy'); " | 72 "<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand(%d); " |
| 73 "return false;\" onmousedown=\"return false;\">%s</a>"; | 73 "return false;\" onmousedown=\"return false;\">%s</a>"; |
| 74 | 74 |
| 75 // After a malware interstitial where the user opted-in to the report | 75 // After a malware interstitial where the user opted-in to the report |
| 76 // but clicked "proceed anyway", we delay the call to | 76 // but clicked "proceed anyway", we delay the call to |
| 77 // MalwareDetails::FinishCollection() by this much time (in | 77 // MalwareDetails::FinishCollection() by this much time (in |
| 78 // milliseconds). | 78 // milliseconds). |
| 79 const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000; | 79 const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000; |
| 80 | 80 |
| 81 // The commands returned by the page when the user performs an action. | |
| 82 const char kDoReportCommand[] = "doReport"; | |
| 83 const char kDontReportCommand[] = "dontReport"; | |
| 84 const char kExpandedSeeMoreCommand[] = "expandedSeeMore"; | |
| 85 const char kLearnMoreCommand[] = "learnMore2"; | |
| 86 const char kProceedCommand[] = "proceed"; | |
| 87 const char kShowDiagnosticCommand[] = "showDiagnostic"; | |
| 88 const char kShowPrivacyCommand[] = "showPrivacy"; | |
| 89 const char kTakeMeBackCommand[] = "takeMeBack"; | |
| 90 | |
| 91 // Other constants used to communicate with the JavaScript. | 81 // Other constants used to communicate with the JavaScript. |
| 92 const char kBoxChecked[] = "boxchecked"; | 82 const char kBoxChecked[] = "boxchecked"; |
| 93 const char kDisplayCheckBox[] = "displaycheckbox"; | 83 const char kDisplayCheckBox[] = "displaycheckbox"; |
| 94 | 84 |
| 95 // Constants for the Experience Sampling instrumentation. | 85 // Constants for the Experience Sampling instrumentation. |
| 96 const char kEventNameMalware[] = "safebrowsing_interstitial_"; | 86 const char kEventNameMalware[] = "safebrowsing_interstitial_"; |
| 97 const char kEventNameHarmful[] = "harmful_interstitial_"; | 87 const char kEventNameHarmful[] = "harmful_interstitial_"; |
| 98 const char kEventNamePhishing[] = "phishing_interstitial_"; | 88 const char kEventNamePhishing[] = "phishing_interstitial_"; |
| 99 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; | 89 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; |
| 100 | 90 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 199 } |
| 210 | 200 |
| 211 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() { | 201 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() { |
| 212 return (!web_contents()->GetBrowserContext()->IsOffTheRecord() && | 202 return (!web_contents()->GetBrowserContext()->IsOffTheRecord() && |
| 213 web_contents()->GetURL().SchemeIs(url::kHttpScheme)); | 203 web_contents()->GetURL().SchemeIs(url::kHttpScheme)); |
| 214 } | 204 } |
| 215 | 205 |
| 216 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { | 206 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { |
| 217 } | 207 } |
| 218 | 208 |
| 219 void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) { | 209 void SafeBrowsingBlockingPage::CommandReceived(const std::string& page_cmd) { |
| 220 std::string command(cmd); // Make a local copy so we can modify it. | 210 if (page_cmd == "\"pageLoadComplete\"") { |
| 221 // The Jasonified response has quotes, remove them. | |
| 222 if (command.length() > 1 && command[0] == '"') { | |
| 223 command = command.substr(1, command.length() - 2); | |
| 224 } | |
| 225 | |
| 226 if (command == "pageLoadComplete") { | |
| 227 // content::WaitForRenderFrameReady sends this message when the page | 211 // content::WaitForRenderFrameReady sends this message when the page |
| 228 // load completes. Ignore it. | 212 // load completes. Ignore it. |
| 229 return; | 213 return; |
| 230 } | 214 } |
| 231 | 215 |
| 232 if (command == kDoReportCommand) { | 216 int command = 0; |
| 233 SetReportingPreference(true); | 217 bool retval = base::StringToInt(page_cmd, &command); |
| 234 return; | 218 DCHECK(retval) << page_cmd; |
| 235 } | |
| 236 | 219 |
| 237 if (command == kDontReportCommand) { | 220 switch (command) { |
| 238 SetReportingPreference(false); | 221 case CMD_DO_REPORT: { |
| 239 return; | 222 // User enabled SB Extended Reporting via the checkbox. |
| 240 } | 223 SetReportingPreference(true); |
| 224 break; |
| 225 } |
| 226 case CMD_DONT_REPORT: { |
| 227 // User disabled SB Extended Reporting via the checkbox. |
| 228 SetReportingPreference(false); |
| 229 break; |
| 230 } |
| 231 case CMD_OPEN_HELP_CENTER: { |
| 232 // User pressed "Learn more". |
| 233 metrics_helper_->RecordUserInteraction( |
| 234 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); |
| 235 GURL learn_more_url( |
| 236 interstitial_reason_ == SB_REASON_PHISHING ? |
| 237 kLearnMorePhishingUrlV2 : kLearnMoreMalwareUrlV2); |
| 238 learn_more_url = google_util::AppendGoogleLocaleParam( |
| 239 learn_more_url, g_browser_process->GetApplicationLocale()); |
| 240 OpenURLParams params(learn_more_url, |
| 241 Referrer(), |
| 242 CURRENT_TAB, |
| 243 ui::PAGE_TRANSITION_LINK, |
| 244 false); |
| 245 web_contents()->OpenURL(params); |
| 246 break; |
| 247 } |
| 248 case CMD_OPEN_REPORTING_PRIVACY: { |
| 249 // User pressed on the SB Extended Reporting "privacy policy" link. |
| 250 metrics_helper_->RecordUserInteraction( |
| 251 SecurityInterstitialMetricsHelper::SHOW_PRIVACY_POLICY); |
| 252 GURL privacy_url( |
| 253 l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL)); |
| 254 privacy_url = google_util::AppendGoogleLocaleParam( |
| 255 privacy_url, g_browser_process->GetApplicationLocale()); |
| 256 OpenURLParams params(privacy_url, |
| 257 Referrer(), |
| 258 CURRENT_TAB, |
| 259 ui::PAGE_TRANSITION_LINK, |
| 260 false); |
| 261 web_contents()->OpenURL(params); |
| 262 break; |
| 263 } |
| 264 case CMD_PROCEED: { |
| 265 // User pressed on the button to proceed. |
| 266 if (!IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) { |
| 267 metrics_helper_->RecordUserDecision( |
| 268 SecurityInterstitialMetricsHelper::PROCEED); |
| 269 interstitial_page()->Proceed(); |
| 270 // |this| has been deleted after Proceed() returns. |
| 271 break; |
| 272 } |
| 273 // If the user can't proceed, fall through to CMD_DONT_PROCEED. |
| 274 } |
| 275 case CMD_DONT_PROCEED: { |
| 276 // User pressed on the button to return to safety. |
| 277 // Don't record the user action here because there are other ways of |
| 278 // triggering DontProceed, like clicking the back button. |
| 279 if (is_main_frame_load_blocked_) { |
| 280 // If the load is blocked, we want to close the interstitial and discard |
| 281 // the pending entry. |
| 282 interstitial_page()->DontProceed(); |
| 283 // |this| has been deleted after DontProceed() returns. |
| 284 break; |
| 285 } |
| 241 | 286 |
| 242 if (command == kLearnMoreCommand) { | 287 // Otherwise the offending entry has committed, and we need to go back or |
| 243 // User pressed "Learn more". | 288 // to a safe page. We will close the interstitial when that page commits. |
| 244 metrics_helper_->RecordUserInteraction( | 289 if (web_contents()->GetController().CanGoBack()) { |
| 245 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); | 290 web_contents()->GetController().GoBack(); |
| 246 GURL learn_more_url( | 291 } else { |
| 247 interstitial_reason_ == SB_REASON_PHISHING ? | 292 web_contents()->GetController().LoadURL( |
| 248 kLearnMorePhishingUrlV2 : kLearnMoreMalwareUrlV2); | 293 GURL(chrome::kChromeUINewTabURL), |
| 249 learn_more_url = google_util::AppendGoogleLocaleParam( | 294 content::Referrer(), |
| 250 learn_more_url, g_browser_process->GetApplicationLocale()); | 295 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| 251 OpenURLParams params(learn_more_url, | 296 std::string()); |
| 252 Referrer(), | 297 } |
| 253 CURRENT_TAB, | 298 break; |
| 254 ui::PAGE_TRANSITION_LINK, | 299 } |
| 255 false); | 300 case CMD_OPEN_DIAGNOSTIC: { |
| 256 web_contents()->OpenURL(params); | 301 // User wants to see why this page is blocked. |
| 257 return; | 302 // TODO(felt): element_index will always be 0. See crbug.com/464732 |
| 258 } | 303 size_t element_index = 0; |
| 259 | 304 const UnsafeResource& unsafe_resource = unsafe_resources_[element_index]; |
| 260 if (command == kShowPrivacyCommand) { | 305 std::string bad_url_spec = unsafe_resource.url.spec(); |
| 261 // User pressed "Safe Browsing privacy policy". | 306 metrics_helper_->RecordUserInteraction( |
| 262 metrics_helper_->RecordUserInteraction( | 307 SecurityInterstitialMetricsHelper::SHOW_DIAGNOSTIC); |
| 263 SecurityInterstitialMetricsHelper::SHOW_PRIVACY_POLICY); | 308 std::string diagnostic = |
| 264 GURL privacy_url( | 309 base::StringPrintf(kSbDiagnosticUrl, |
| 265 l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL)); | 310 net::EscapeQueryParamValue(bad_url_spec, true).c_str()); |
| 266 privacy_url = google_util::AppendGoogleLocaleParam( | 311 GURL diagnostic_url(diagnostic); |
| 267 privacy_url, g_browser_process->GetApplicationLocale()); | 312 diagnostic_url = google_util::AppendGoogleLocaleParam( |
| 268 OpenURLParams params(privacy_url, | 313 diagnostic_url, g_browser_process->GetApplicationLocale()); |
| 269 Referrer(), | 314 DCHECK(unsafe_resource.threat_type == SB_THREAT_TYPE_URL_MALWARE || |
| 270 CURRENT_TAB, | 315 unsafe_resource.threat_type == |
| 271 ui::PAGE_TRANSITION_LINK, | 316 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL || |
| 272 false); | 317 unsafe_resource.threat_type == SB_THREAT_TYPE_URL_UNWANTED); |
| 273 web_contents()->OpenURL(params); | 318 OpenURLParams params( |
| 274 return; | 319 diagnostic_url, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_LINK, |
| 275 } | 320 false); |
| 276 | 321 web_contents()->OpenURL(params); |
| 277 bool proceed_blocked = false; | 322 break; |
| 278 if (command == kProceedCommand) { | 323 } |
| 279 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) { | 324 case CMD_SHOW_MORE_SECTION: { |
| 280 proceed_blocked = true; | 325 // User has opened up the hidden text. |
| 281 } else { | 326 metrics_helper_->RecordUserInteraction( |
| 282 metrics_helper_->RecordUserDecision( | 327 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); |
| 283 SecurityInterstitialMetricsHelper::PROCEED); | 328 break; |
| 284 interstitial_page()->Proceed(); | |
| 285 // |this| has been deleted after Proceed() returns. | |
| 286 return; | |
| 287 } | 329 } |
| 288 } | 330 } |
| 289 | |
| 290 if (command == kTakeMeBackCommand || proceed_blocked) { | |
| 291 // Don't record the user action here because there are other ways of | |
| 292 // triggering DontProceed, like clicking the back button. | |
| 293 if (is_main_frame_load_blocked_) { | |
| 294 // If the load is blocked, we want to close the interstitial and discard | |
| 295 // the pending entry. | |
| 296 interstitial_page()->DontProceed(); | |
| 297 // |this| has been deleted after DontProceed() returns. | |
| 298 return; | |
| 299 } | |
| 300 | |
| 301 // Otherwise the offending entry has committed, and we need to go back or | |
| 302 // to a safe page. We will close the interstitial when that page commits. | |
| 303 if (web_contents()->GetController().CanGoBack()) { | |
| 304 web_contents()->GetController().GoBack(); | |
| 305 } else { | |
| 306 web_contents()->GetController().LoadURL( | |
| 307 GURL(chrome::kChromeUINewTabURL), | |
| 308 content::Referrer(), | |
| 309 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
| 310 std::string()); | |
| 311 } | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 // The "report error" and "show diagnostic" commands can have a number | |
| 316 // appended to them, which is the index of the element they apply to. | |
| 317 size_t element_index = 0; | |
| 318 size_t colon_index = command.find(':'); | |
| 319 if (colon_index != std::string::npos) { | |
| 320 DCHECK(colon_index < command.size() - 1); | |
| 321 int result_int = 0; | |
| 322 bool result = base::StringToInt(base::StringPiece(command.begin() + | |
| 323 colon_index + 1, | |
| 324 command.end()), | |
| 325 &result_int); | |
| 326 command = command.substr(0, colon_index); | |
| 327 if (result) | |
| 328 element_index = static_cast<size_t>(result_int); | |
| 329 } | |
| 330 | |
| 331 if (element_index >= unsafe_resources_.size()) { | |
| 332 NOTREACHED(); | |
| 333 return; | |
| 334 } | |
| 335 | |
| 336 std::string bad_url_spec = unsafe_resources_[element_index].url.spec(); | |
| 337 if (command == kShowDiagnosticCommand) { | |
| 338 // We're going to take the user to Google's SafeBrowsing diagnostic page. | |
| 339 metrics_helper_->RecordUserInteraction( | |
| 340 SecurityInterstitialMetricsHelper::SHOW_DIAGNOSTIC); | |
| 341 std::string diagnostic = | |
| 342 base::StringPrintf(kSbDiagnosticUrl, | |
| 343 net::EscapeQueryParamValue(bad_url_spec, true).c_str()); | |
| 344 GURL diagnostic_url(diagnostic); | |
| 345 diagnostic_url = google_util::AppendGoogleLocaleParam( | |
| 346 diagnostic_url, g_browser_process->GetApplicationLocale()); | |
| 347 DCHECK(unsafe_resources_[element_index].threat_type == | |
| 348 SB_THREAT_TYPE_URL_MALWARE || | |
| 349 unsafe_resources_[element_index].threat_type == | |
| 350 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL || | |
| 351 unsafe_resources_[element_index].threat_type == | |
| 352 SB_THREAT_TYPE_URL_UNWANTED); | |
| 353 OpenURLParams params( | |
| 354 diagnostic_url, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_LINK, | |
| 355 false); | |
| 356 web_contents()->OpenURL(params); | |
| 357 return; | |
| 358 } | |
| 359 | |
| 360 if (command == kExpandedSeeMoreCommand) { | |
| 361 metrics_helper_->RecordUserInteraction( | |
| 362 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); | |
| 363 return; | |
| 364 } | |
| 365 | |
| 366 NOTREACHED() << "Unexpected command: " << command; | |
| 367 } | 331 } |
| 368 | 332 |
| 369 void SafeBrowsingBlockingPage::OverrideRendererPrefs( | 333 void SafeBrowsingBlockingPage::OverrideRendererPrefs( |
| 370 content::RendererPreferences* prefs) { | 334 content::RendererPreferences* prefs) { |
| 371 Profile* profile = Profile::FromBrowserContext( | 335 Profile* profile = Profile::FromBrowserContext( |
| 372 web_contents()->GetBrowserContext()); | 336 web_contents()->GetBrowserContext()); |
| 373 renderer_preferences_util::UpdateFromSystemSettings( | 337 renderer_preferences_util::UpdateFromSystemSettings( |
| 374 prefs, profile, web_contents()); | 338 prefs, profile, web_contents()); |
| 375 } | 339 } |
| 376 | 340 |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 void SafeBrowsingBlockingPage::PopulateExtendedReportingOption( | 585 void SafeBrowsingBlockingPage::PopulateExtendedReportingOption( |
| 622 base::DictionaryValue* load_time_data) { | 586 base::DictionaryValue* load_time_data) { |
| 623 // Only show checkbox if !(HTTPS || incognito-mode). | 587 // Only show checkbox if !(HTTPS || incognito-mode). |
| 624 const bool show = CanShowMalwareDetailsOption(); | 588 const bool show = CanShowMalwareDetailsOption(); |
| 625 load_time_data->SetBoolean(kDisplayCheckBox, show); | 589 load_time_data->SetBoolean(kDisplayCheckBox, show); |
| 626 if (!show) | 590 if (!show) |
| 627 return; | 591 return; |
| 628 | 592 |
| 629 const std::string privacy_link = base::StringPrintf( | 593 const std::string privacy_link = base::StringPrintf( |
| 630 kPrivacyLinkHtml, | 594 kPrivacyLinkHtml, |
| 595 CMD_OPEN_REPORTING_PRIVACY, |
| 631 l10n_util::GetStringUTF8( | 596 l10n_util::GetStringUTF8( |
| 632 IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str()); | 597 IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str()); |
| 633 load_time_data->SetString( | 598 load_time_data->SetString( |
| 634 "optInLink", | 599 "optInLink", |
| 635 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE, | 600 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE, |
| 636 base::UTF8ToUTF16(privacy_link))); | 601 base::UTF8ToUTF16(privacy_link))); |
| 637 load_time_data->SetBoolean( | 602 load_time_data->SetBoolean( |
| 638 kBoxChecked, | 603 kBoxChecked, |
| 639 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled)); | 604 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled)); |
| 640 } | 605 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 load_time_data->SetString( | 667 load_time_data->SetString( |
| 703 "explanationParagraph", | 668 "explanationParagraph", |
| 704 l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH, | 669 l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH, |
| 705 GetFormattedHostName())); | 670 GetFormattedHostName())); |
| 706 load_time_data->SetString( | 671 load_time_data->SetString( |
| 707 "finalParagraph", | 672 "finalParagraph", |
| 708 l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH)); | 673 l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH)); |
| 709 | 674 |
| 710 PopulateExtendedReportingOption(load_time_data); | 675 PopulateExtendedReportingOption(load_time_data); |
| 711 } | 676 } |
| OLD | NEW |