Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(247)

Side by Side Diff: chrome/browser/ssl/ssl_blocking_page.cc

Issue 935663004: Add checkbox for reporting invalid TLS/SSL cert chains (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mattm comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "chrome/browser/ssl/ssl_blocking_page.h" 5 #include "chrome/browser/ssl/ssl_blocking_page.h"
6 6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
7 #include "base/build_time.h" 9 #include "base/build_time.h"
10 #include "base/callback_helpers.h"
8 #include "base/command_line.h" 11 #include "base/command_line.h"
9 #include "base/i18n/rtl.h" 12 #include "base/i18n/rtl.h"
10 #include "base/i18n/time_formatting.h" 13 #include "base/i18n/time_formatting.h"
11 #include "base/metrics/field_trial.h" 14 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/prefs/pref_service.h"
13 #include "base/process/launch.h" 17 #include "base/process/launch.h"
14 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h" 19 #include "base/strings/string_piece.h"
16 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
19 #include "base/time/time.h" 23 #include "base/time/time.h"
20 #include "base/values.h" 24 #include "base/values.h"
21 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h" 26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/interstitials/security_interstitial_metrics_helper.h"
23 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/renderer_preferences_util.h" 29 #include "chrome/browser/renderer_preferences_util.h"
30 #include "chrome/browser/safe_browsing/ui_manager.h"
25 #include "chrome/browser/ssl/ssl_error_classification.h" 31 #include "chrome/browser/ssl/ssl_error_classification.h"
26 #include "chrome/browser/ssl/ssl_error_info.h" 32 #include "chrome/browser/ssl/ssl_error_info.h"
27 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/pref_names.h"
28 #include "chrome/grit/chromium_strings.h" 35 #include "chrome/grit/chromium_strings.h"
29 #include "chrome/grit/generated_resources.h" 36 #include "chrome/grit/generated_resources.h"
30 #include "components/google/core/browser/google_util.h" 37 #include "components/google/core/browser/google_util.h"
31 #include "content/public/browser/browser_thread.h" 38 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/cert_store.h" 39 #include "content/public/browser/cert_store.h"
33 #include "content/public/browser/interstitial_page.h" 40 #include "content/public/browser/interstitial_page.h"
34 #include "content/public/browser/interstitial_page_delegate.h" 41 #include "content/public/browser/interstitial_page_delegate.h"
35 #include "content/public/browser/navigation_controller.h" 42 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/navigation_entry.h" 43 #include "content/public/browser/navigation_entry.h"
37 #include "content/public/browser/notification_service.h" 44 #include "content/public/browser/notification_service.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 } 221 }
215 222
216 } // namespace 223 } // namespace
217 224
218 // static 225 // static
219 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting = 226 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting =
220 &SSLBlockingPage::kTypeForTesting; 227 &SSLBlockingPage::kTypeForTesting;
221 228
222 // Note that we always create a navigation entry with SSL errors. 229 // Note that we always create a navigation entry with SSL errors.
223 // No error happening loading a sub-resource triggers an interstitial so far. 230 // No error happening loading a sub-resource triggers an interstitial so far.
224 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, 231 SSLBlockingPage::SSLBlockingPage(
225 int cert_error, 232 content::WebContents* web_contents,
226 const net::SSLInfo& ssl_info, 233 int cert_error,
227 const GURL& request_url, 234 const net::SSLInfo& ssl_info,
228 int options_mask, 235 const GURL& request_url,
229 const base::Time& time_triggered, 236 int options_mask,
230 const base::Callback<void(bool)>& callback) 237 const base::Time& time_triggered,
238 SafeBrowsingUIManager* safe_browsing_ui_manager,
239 const base::Callback<void(bool)>& callback)
231 : SecurityInterstitialPage(web_contents, request_url), 240 : SecurityInterstitialPage(web_contents, request_url),
232 callback_(callback), 241 callback_(callback),
233 cert_error_(cert_error), 242 cert_error_(cert_error),
234 ssl_info_(ssl_info), 243 ssl_info_(ssl_info),
235 overridable_(IsOptionsOverridable(options_mask)), 244 overridable_(IsOptionsOverridable(options_mask)),
236 danger_overridable_(true), 245 danger_overridable_(true),
237 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), 246 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0),
238 expired_but_previously_allowed_( 247 expired_but_previously_allowed_(
239 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0), 248 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0),
240 time_triggered_(time_triggered) { 249 time_triggered_(time_triggered),
250 safe_browsing_ui_manager_(safe_browsing_ui_manager) {
241 interstitial_reason_ = 251 interstitial_reason_ =
242 IsErrorDueToBadClock(time_triggered_, cert_error_) ? 252 IsErrorDueToBadClock(time_triggered_, cert_error_) ?
243 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; 253 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL;
244 254
245 // We collapse the Rappor metric name to just "ssl" so we don't leak 255 // We collapse the Rappor metric name to just "ssl" so we don't leak
246 // the "overridable" bit. We skip Rappor altogether for bad clocks. 256 // the "overridable" bit. We skip Rappor altogether for bad clocks.
247 // This must be done after calculating |interstitial_reason_| above. 257 // This must be done after calculating |interstitial_reason_| above.
248 metrics_helper_.reset(new SecurityInterstitialMetricsHelper( 258 metrics_helper_.reset(new SecurityInterstitialMetricsHelper(
249 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, 259 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix,
250 (interstitial_reason_ == SSL_REASON_BAD_CLOCK 260 (interstitial_reason_ == SSL_REASON_BAD_CLOCK
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 load_time_data->SetString( 442 load_time_data->SetString(
433 "expirationDate", 443 "expirationDate",
434 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); 444 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry()));
435 load_time_data->SetString( 445 load_time_data->SetString(
436 "currentDate", base::TimeFormatShortDate(time_triggered_)); 446 "currentDate", base::TimeFormatShortDate(time_triggered_));
437 std::vector<std::string> encoded_chain; 447 std::vector<std::string> encoded_chain;
438 ssl_info_.cert->GetPEMEncodedChain( 448 ssl_info_.cert->GetPEMEncodedChain(
439 &encoded_chain); 449 &encoded_chain);
440 load_time_data->SetString( 450 load_time_data->SetString(
441 "pem", JoinString(encoded_chain, std::string())); 451 "pem", JoinString(encoded_chain, std::string()));
452
453 PopulateExtendedReportingOption(load_time_data);
454 }
455
456 void SSLBlockingPage::PopulateExtendedReportingOption(
457 base::DictionaryValue* load_time_data) {
458 // Only show the checkbox if not off-the-record and if the
459 // command-line option is set.
460 const bool show = !web_contents()->GetBrowserContext()->IsOffTheRecord() &&
461 base::CommandLine::ForCurrentProcess()->HasSwitch(
462 switches::kEnableInvalidCertCollection);
463
464 load_time_data->SetBoolean(interstitials::kDisplayCheckBox, show);
465 if (!show)
466 return;
467
468 load_time_data->SetBoolean(
469 interstitials::kBoxChecked,
470 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled));
471
472 const std::string privacy_link = base::StringPrintf(
473 interstitials::kPrivacyLinkHtml, CMD_OPEN_REPORTING_PRIVACY,
474 l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str());
475
476 load_time_data->SetString(
477 interstitials::kOptInLink,
478 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE,
479 base::UTF8ToUTF16(privacy_link)));
442 } 480 }
443 481
444 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { 482 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) {
445 int cert_id = content::CertStore::GetInstance()->StoreCert( 483 int cert_id = content::CertStore::GetInstance()->StoreCert(
446 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); 484 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID());
447 DCHECK(cert_id); 485 DCHECK(cert_id);
448 486
449 entry->GetSSL().security_style = 487 entry->GetSSL().security_style =
450 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; 488 content::SECURITY_STYLE_AUTHENTICATION_BROKEN;
451 entry->GetSSL().cert_id = cert_id; 489 entry->GetSSL().cert_id = cert_id;
452 entry->GetSSL().cert_status = ssl_info_.cert_status; 490 entry->GetSSL().cert_status = ssl_info_.cert_status;
453 entry->GetSSL().security_bits = ssl_info_.security_bits; 491 entry->GetSSL().security_bits = ssl_info_.security_bits;
454 } 492 }
455 493
494 void SSLBlockingPage::SetCertificateReportCallbackForTesting(
495 const base::Closure& callback) {
496 certificate_report_callback_for_testing_ = callback;
497 }
498
456 // This handles the commands sent from the interstitial JavaScript. 499 // This handles the commands sent from the interstitial JavaScript.
457 // DO NOT reorder or change this logic without also changing the JavaScript! 500 // DO NOT reorder or change this logic without also changing the JavaScript!
458 void SSLBlockingPage::CommandReceived(const std::string& command) { 501 void SSLBlockingPage::CommandReceived(const std::string& command) {
459 int cmd = 0; 502 int cmd = 0;
460 bool retval = base::StringToInt(command, &cmd); 503 bool retval = base::StringToInt(command, &cmd);
461 DCHECK(retval); 504 DCHECK(retval);
462 switch (cmd) { 505 switch (cmd) {
463 case CMD_DONT_PROCEED: { 506 case CMD_DONT_PROCEED: {
464 interstitial_page()->DontProceed(); 507 interstitial_page()->DontProceed();
465 break; 508 break;
466 } 509 }
467 case CMD_PROCEED: { 510 case CMD_PROCEED: {
468 if (danger_overridable_) { 511 if (danger_overridable_) {
469 interstitial_page()->Proceed(); 512 interstitial_page()->Proceed();
470 } 513 }
471 break; 514 break;
472 } 515 }
516 case CMD_DO_REPORT: {
517 SetReportingPreference(true);
518 break;
519 }
520 case CMD_DONT_REPORT: {
521 SetReportingPreference(false);
522 break;
523 }
473 case CMD_SHOW_MORE_SECTION: { 524 case CMD_SHOW_MORE_SECTION: {
474 metrics_helper_->RecordUserInteraction( 525 metrics_helper_->RecordUserInteraction(
475 SecurityInterstitialMetricsHelper::SHOW_ADVANCED); 526 SecurityInterstitialMetricsHelper::SHOW_ADVANCED);
476 break; 527 break;
477 } 528 }
478 case CMD_OPEN_HELP_CENTER: { 529 case CMD_OPEN_HELP_CENTER: {
479 metrics_helper_->RecordUserInteraction( 530 metrics_helper_->RecordUserInteraction(
480 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); 531 SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE);
481 content::NavigationController::LoadURLParams help_page_params( 532 content::NavigationController::LoadURLParams help_page_params(
482 google_util::AppendGoogleLocaleParam( 533 google_util::AppendGoogleLocaleParam(
483 GURL(kHelpURL), g_browser_process->GetApplicationLocale())); 534 GURL(kHelpURL), g_browser_process->GetApplicationLocale()));
484 web_contents()->GetController().LoadURLWithParams(help_page_params); 535 web_contents()->GetController().LoadURLWithParams(help_page_params);
485 break; 536 break;
486 } 537 }
487 case CMD_RELOAD: { 538 case CMD_RELOAD: {
488 metrics_helper_->RecordUserInteraction( 539 metrics_helper_->RecordUserInteraction(
489 SecurityInterstitialMetricsHelper::RELOAD); 540 SecurityInterstitialMetricsHelper::RELOAD);
490 // The interstitial can't refresh itself. 541 // The interstitial can't refresh itself.
491 web_contents()->GetController().Reload(true); 542 web_contents()->GetController().Reload(true);
492 break; 543 break;
493 } 544 }
494 case CMD_OPEN_DATE_SETTINGS: { 545 case CMD_OPEN_DATE_SETTINGS: {
495 metrics_helper_->RecordUserInteraction( 546 metrics_helper_->RecordUserInteraction(
496 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS); 547 SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS);
497 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 548 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
498 base::Bind(&LaunchDateAndTimeSettings)); 549 base::Bind(&LaunchDateAndTimeSettings));
499 break; 550 break;
500 } 551 }
552 case CMD_OPEN_REPORTING_PRIVACY:
553 OpenExtendedReportingPrivacyPolicy();
554 break;
501 case CMD_OPEN_DIAGNOSTIC: 555 case CMD_OPEN_DIAGNOSTIC:
502 // Google doesn't currently have a transparency report for SSL. 556 // Google doesn't currently have a transparency report for SSL.
503 case CMD_DO_REPORT:
504 case CMD_DONT_REPORT:
505 case CMD_OPEN_REPORTING_PRIVACY:
506 // Chrome doesn't currently do Extended Reporting for SSL.
507 NOTREACHED() << "Unexpected command: " << command; 557 NOTREACHED() << "Unexpected command: " << command;
508 } 558 }
509 } 559 }
510 560
511 void SSLBlockingPage::OverrideRendererPrefs( 561 void SSLBlockingPage::OverrideRendererPrefs(
512 content::RendererPreferences* prefs) { 562 content::RendererPreferences* prefs) {
513 Profile* profile = Profile::FromBrowserContext( 563 Profile* profile = Profile::FromBrowserContext(
514 web_contents()->GetBrowserContext()); 564 web_contents()->GetBrowserContext());
515 renderer_preferences_util::UpdateFromSystemSettings( 565 renderer_preferences_util::UpdateFromSystemSettings(
516 prefs, profile, web_contents()); 566 prefs, profile, web_contents());
517 } 567 }
518 568
519 void SSLBlockingPage::OnProceed() { 569 void SSLBlockingPage::OnProceed() {
520 metrics_helper_->RecordUserDecision( 570 metrics_helper_->RecordUserDecision(
521 SecurityInterstitialMetricsHelper::PROCEED); 571 SecurityInterstitialMetricsHelper::PROCEED);
572
573 // Finish collecting information about invalid certificates, if the
574 // user opted in to.
575 FinishCertCollection();
576
522 RecordSSLExpirationPageEventState( 577 RecordSSLExpirationPageEventState(
523 expired_but_previously_allowed_, true, overridable_); 578 expired_but_previously_allowed_, true, overridable_);
524 // Accepting the certificate resumes the loading of the page. 579 // Accepting the certificate resumes the loading of the page.
525 NotifyAllowCertificate(); 580 NotifyAllowCertificate();
526 } 581 }
527 582
528 void SSLBlockingPage::OnDontProceed() { 583 void SSLBlockingPage::OnDontProceed() {
529 metrics_helper_->RecordUserDecision( 584 metrics_helper_->RecordUserDecision(
530 SecurityInterstitialMetricsHelper::DONT_PROCEED); 585 SecurityInterstitialMetricsHelper::DONT_PROCEED);
586
587 // Finish collecting information about invalid certificates, if the
588 // user opted in to.
589 FinishCertCollection();
590
531 RecordSSLExpirationPageEventState( 591 RecordSSLExpirationPageEventState(
532 expired_but_previously_allowed_, false, overridable_); 592 expired_but_previously_allowed_, false, overridable_);
533 NotifyDenyCertificate(); 593 NotifyDenyCertificate();
534 } 594 }
535 595
536 void SSLBlockingPage::NotifyDenyCertificate() { 596 void SSLBlockingPage::NotifyDenyCertificate() {
537 // It's possible that callback_ may not exist if the user clicks "Proceed" 597 // It's possible that callback_ may not exist if the user clicks "Proceed"
538 // followed by pressing the back button before the interstitial is hidden. 598 // followed by pressing the back button before the interstitial is hidden.
539 // In that case the certificate will still be treated as allowed. 599 // In that case the certificate will still be treated as allowed.
540 if (callback_.is_null()) 600 if (callback_.is_null())
(...skipping 27 matching lines...) Expand all
568 std::string SSLBlockingPage::GetSamplingEventName() const { 628 std::string SSLBlockingPage::GetSamplingEventName() const {
569 std::string event_name(kEventNameBase); 629 std::string event_name(kEventNameBase);
570 if (overridable_) 630 if (overridable_)
571 event_name.append(kEventOverridable); 631 event_name.append(kEventOverridable);
572 else 632 else
573 event_name.append(kEventNotOverridable); 633 event_name.append(kEventNotOverridable);
574 event_name.append(net::ErrorToString(cert_error_)); 634 event_name.append(net::ErrorToString(cert_error_));
575 return event_name; 635 return event_name;
576 } 636 }
577 637
638 void SSLBlockingPage::FinishCertCollection() {
639 base::ScopedClosureRunner scoped_callback(
640 certificate_report_callback_for_testing_);
641
642 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
643 switches::kEnableInvalidCertCollection) ||
644 web_contents()->GetBrowserContext()->IsOffTheRecord()) {
645 return;
646 }
647
648 const bool enabled =
649 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled);
650
651 if (!enabled)
652 return;
653
654 metrics_helper_->RecordUserInteraction(
655 SecurityInterstitialMetricsHelper::EXTENDED_REPORTING_IS_ENABLED_SSL);
656
657 if (certificate_report_callback_for_testing_.is_null())
658 scoped_callback.Reset(base::Bind(&base::DoNothing));
659
660 safe_browsing_ui_manager_->ReportInvalidCertificateChain(
661 request_url().host(), ssl_info_, scoped_callback.Release());
662 }
663
578 // static 664 // static
579 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { 665 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) {
580 return (options_mask & SSLBlockingPage::OVERRIDABLE) && 666 return (options_mask & SSLBlockingPage::OVERRIDABLE) &&
581 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); 667 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT);
582 } 668 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698