File: https_first_mode_settings_tracker.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (190 lines) | stat: -rw-r--r-- 8,020 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SSL_HTTPS_FIRST_MODE_SETTINGS_TRACKER_H_
#define CHROME_BROWSER_SSL_HTTPS_FIRST_MODE_SETTINGS_TRACKER_H_

#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/task/task_traits.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
#include "chrome/browser/ssl/daily_navigation_counter.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/site_engagement/content/site_engagement_score.h"
#include "content/public/browser/browser_thread.h"

class Profile;
namespace base {
class Clock;
}

namespace site_engagement {
class SiteEngagementService;
}

class StatefulSSLHostStateDelegate;

// The set of valid states of the user-controllable HTTPS-First Mode setting.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// Must be kept in sync with the HttpsFirstModeSetting enums located in
// chrome/browser/resources/settings/privacy_page/security_page.ts and enums.xml
// LINT.IfChange
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ssl
enum class HttpsFirstModeSetting {
  kDisabled = 0,
  // DEPRECATED: A separate Incognito setting never shipped.
  // kEnabledIncognito = 1,
  kEnabledFull = 2,
  kEnabledBalanced = 3,
  kMaxValue = kEnabledBalanced,
};
// LINT.ThenChange(/tools/metrics/histograms/metadata/security/enums.xml)

// A `KeyedService` that tracks changes to the HTTPS-First Mode pref for each
// profile. This is currently used for:
// - Recording pref state in metrics and registering the client for a synthetic
//   field trial based on that state.
// - Changing the pref based on user's Advanced Protection status.
// - Checking the Site Engagement scores of a site and enable/disable HFM based
//   on that.
class HttpsFirstModeService
    : public KeyedService,
      public safe_browsing::AdvancedProtectionStatusManager::
          StatusChangedObserver {
 public:
  explicit HttpsFirstModeService(Profile* profile, base::Clock* clock);
  ~HttpsFirstModeService() override;

  HttpsFirstModeService(const HttpsFirstModeService&) = delete;
  HttpsFirstModeService& operator=(const HttpsFirstModeService&) = delete;

  // safe_browsing::AdvancedProtectionStatusManager::StatusChangedObserver:
  void OnAdvancedProtectionStatusChanged(bool enabled) override;

  // Runs Typically Secure User and Site Engagement heuristics after the service
  // is created.
  void AfterStartup();

  // Returns true if the Typically Secure Heuristic enabled HTTPS-First Mode
  // in this profile. Does not update the recorded fallback events list.
  bool IsInterstitialEnabledByTypicallySecureUserHeuristic() const;
  // Records an HTTPS-Upgrade fallback event if the Typically Secure heuristic
  // isn't yet enabled and evicts old fallback events.
  void RecordHttpsUpgradeFallbackEvent();
  // Updates HTTPS-Upgrade fallback events and enables HTTPS-First Balanced Mode
  // if the user typically visits secure sites.
  // The first invocation of this method will almost always be a no-op in
  // browser tests because the method checks that the clock is sufficiently
  // advanced, and tests can't change the clock before getting here. Therefore,
  // browser tests need to call this method explicitly.
  void CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();

  // Gets the list of engaged sites from Site Engagement service and determines
  // whether HTTPS-First Mode should be enabled on each site. Calls
  // `done_callback` before returning.
  void MaybeEnableHttpsFirstModeForEngagedSites(
      base::OnceClosure done_callback);

  HttpsFirstModeSetting GetCurrentSetting() const;

  // Update the underlying HTTPS-First Mode prefs based on the UI setting
  // selection.
  bool UpdatePrefs(const HttpsFirstModeSetting& selection);

  // Increment recent navigation count and maybe save the counts to a pref.
  void IncrementRecentNavigationCount();
  // Returns the number of navigations counted recently in a rolling window.
  size_t GetRecentNavigationCount() const;

  // Sets the clock for use in tests.
  void SetClockForTesting(base::Clock* clock);
  // Returns the current number of fallback entries recorded.
  size_t GetFallbackEntryCountForTesting() const;

 private:
  void OnHttpsFirstModePrefChanged();
  // HTTPS-Upgrade fallback events are stored in a pref. This method extracts
  // the fallback events, deletes old events, adds a new event if
  // `add_new_entry` is true. Returns true if the heuristic indicates that
  // HFM can be auto-enabled, but this function doesn't auto-enable it.
  bool UpdateFallbackEntries(bool add_new_entry);
  // Returns true if the user is considered typically secure. Does not
  // auto-enable HFM pref, but updates the fallback events, evicting old ones.
  bool IsUserTypicallySecure();

  // Check the Site Engagement scores of the hostname of `url` and enable
  // HFM on the hostname if the HTTPS score is high enough. `url` should have a
  // default port.
  void MaybeEnableHttpsFirstModeForUrl(
      const GURL& url,
      site_engagement::SiteEngagementService* engagement_service,
      StatefulSSLHostStateDelegate* state);
  // Called after getting the engaged sites list from Site Engagement service.
  // Calls `done_callback` before returning.
  void ProcessEngagedSitesList(
      base::OnceClosure done_callback,
      const std::vector<site_engagement::mojom::SiteEngagementDetails>&
          details);

  // If true, will not clear the HTTP allowlist when the HFM pref changes next
  // time. Will be set to false again upon pref change.
  // The HFM pref can be changed by the UI setting or the Typically Secure User
  // heuristic. We only need to clear the allowlist if the UI setting is. The
  // pref observer has no way of knowing how the pref was changed, so we use
  // this bool to tell it to clear or keep the allowlist.
  bool keep_http_allowlist_on_next_pref_change_ = false;

  raw_ptr<Profile> profile_;
  PrefChangeRegistrar pref_change_registrar_;
  raw_ptr<base::Clock> clock_;

  base::Value::Dict navigation_counts_dict_;
  std::unique_ptr<DailyNavigationCounter> navigation_counter_;

  base::ScopedObservation<
      safe_browsing::AdvancedProtectionStatusManager,
      safe_browsing::AdvancedProtectionStatusManager::StatusChangedObserver>
      obs_{this};

  base::WeakPtrFactory<HttpsFirstModeService> weak_factory_{this};
};

// Factory boilerplate for creating the `HttpsFirstModeService` for each browser
// context (profile).
class HttpsFirstModeServiceFactory : public ProfileKeyedServiceFactory {
 public:
  static HttpsFirstModeService* GetForProfile(Profile* profile);
  static HttpsFirstModeServiceFactory* GetInstance();

  HttpsFirstModeServiceFactory(const HttpsFirstModeServiceFactory&) = delete;
  HttpsFirstModeServiceFactory& operator=(const HttpsFirstModeServiceFactory&) =
      delete;

  // Returns the default factory, useful in tests where it's null by default.
  static BrowserContextKeyedServiceFactory::TestingFactory
  GetDefaultFactoryForTesting();

  // Sets the clock to use when creating the service.
  static base::Clock* SetClockForTesting(base::Clock* clock);

 private:
  friend struct base::DefaultSingletonTraits<HttpsFirstModeServiceFactory>;

  HttpsFirstModeServiceFactory();
  ~HttpsFirstModeServiceFactory() override;

  // BrowserContextKeyedServiceFactory:
  std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
      content::BrowserContext* profile) const override;
};

#endif  // CHROME_BROWSER_SSL_HTTPS_FIRST_MODE_SETTINGS_TRACKER_H_