#include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
#include <memory>
#include <string>
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "base/observer_list.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/password_manager/account_password_store_factory.h"
#include "chrome/browser/password_manager/password_reuse_manager_factory.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
#include "chrome/browser/safe_browsing/chrome_user_population_helper.h"
#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/sync/user_event_service_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/google/core/common/google_util.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/password_manager/core/browser/form_parsing/form_data_parser.h"
#include "components/password_manager/core/browser/insecure_credentials_helper.h"
#include "components/password_manager/core/browser/leak_detection_dialog_utils.h"
#include "components/password_manager/core/browser/password_sync_util.h"
#include "components/password_manager/core/browser/ui/password_check_referrer.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h"
#include "components/safe_browsing/content/browser/password_protection/password_protection_request_content.h"
#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
#include "components/safe_browsing/content/browser/triggers/trigger_throttler.h"
#include "components/safe_browsing/content/browser/ui_manager.h"
#include "components/safe_browsing/content/browser/unsafe_resource_util.h"
#include "components/safe_browsing/content/browser/web_contents_key.h"
#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
#include "components/safe_browsing/core/browser/db/database_manager.h"
#include "components/safe_browsing/core/browser/realtime/policy_engine.h"
#include "components/safe_browsing/core/browser/safe_browsing_metrics_collector.h"
#include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h"
#include "components/safe_browsing/core/browser/verdict_cache_manager.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/safe_browsing/core/common/safebrowsing_constants.h"
#include "components/safe_browsing/core/common/utils.h"
#include "components/security_interstitials/core/unsafe_resource.h"
#include "components/signin/public/base/consent_level.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/protocol/user_event_specifics.pb.h"
#include "components/sync/service/sync_service.h"
#include "components/sync_user_events/user_event_service.h"
#include "components/unified_consent/pref_names.h"
#include "components/variations/service/variations_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
#include "url/url_util.h"
#if BUILDFLAG(FULL_SAFE_BROWSING)
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/password_manager/android/password_checkup_launcher_helper_impl.h"
#include "chrome/browser/password_manager/android/password_manager_android_util.h"
#include "chrome/browser/safe_browsing/android/password_reuse_controller_android.h"
#include "chrome/browser/safe_browsing/android/safe_browsing_referring_app_bridge_android.h"
#include "components/password_manager/core/browser/password_check_referrer_android.h"
#include "components/password_manager/core/browser/split_stores_and_local_upm.h"
#include "ui/android/window_android.h"
#else
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/hats/trust_safety_sentiment_service.h"
#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
#endif
RecordAction;
UserMetricsAction;
BrowserThread;
using enum safe_browsing::ExtendedReportingLevel;
GaiaPasswordReuse;
UserEventSpecifics;
GaiaPasswordCaptured;
PasswordReuseDialogInteraction;
PasswordReuseLookup;
PasswordReuseEvent;
SafeBrowsingStatus;
namespace safe_browsing {
ReusedPasswordAccountType;
namespace {
const int kPasswordEventAttributionUserGestureLimit = …;
const float kProbabilityForSendingReportsFromSafeURLs = …;
const int kOverrideVerdictCacheDurationSec = …;
const int kPasswordCaptureEventLogFreqDaysMin = …;
const int kPasswordCaptureEventLogFreqDaysExtra = …;
int64_t GetMicrosecondsSinceWindowsEpoch(base::Time time) { … }
PasswordReuseLookup::ReputationVerdict GetVerdictToLogFromResponse(
LoginReputationClientResponse::VerdictType response_verdict) { … }
int64_t GetLastCommittedNavigationID(content::WebContents* web_contents) { … }
void OpenUrl(content::WebContents* current_web_contents,
const GURL& url,
const content::Referrer& referrer,
bool in_new_tab) { … }
int64_t GetNavigationIDFromPrefsByOrigin(PrefService* prefs,
const Origin& origin) { … }
std::unique_ptr<UserEventSpecifics> GetNewUserEventSpecifics() { … }
std::unique_ptr<UserEventSpecifics> GetUserEventSpecificsWithNavigationId(
int64_t navigation_id) { … }
std::unique_ptr<UserEventSpecifics> GetUserEventSpecifics(
content::WebContents* web_contents) { … }
#if BUILDFLAG(IS_ANDROID)
struct CredentialFoundInStore {
bool is_account_store;
bool is_profile_store;
};
CredentialFoundInStore CheckCredentialsStore(
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials) {
bool is_account_credential = false;
bool is_profile_credential = false;
for (const password_manager::MatchingReusedCredential& credential :
matching_reused_credentials) {
if ((credential.in_store &
password_manager::PasswordForm::Store::kAccountStore) ==
password_manager::PasswordForm::Store::kAccountStore) {
is_account_credential = true;
}
if ((credential.in_store &
password_manager::PasswordForm::Store::kProfileStore) ==
password_manager::PasswordForm::Store::kProfileStore) {
is_profile_credential = true;
}
}
return CredentialFoundInStore(is_account_credential, is_profile_credential);
}
#endif
}
ChromePasswordProtectionService::ChromePasswordProtectionService(
SafeBrowsingService* sb_service,
Profile* profile)
: … { … }
void ChromePasswordProtectionService::Init() { … }
void ChromePasswordProtectionService::Shutdown() { … }
ChromePasswordProtectionService::~ChromePasswordProtectionService() = default;
ChromePasswordProtectionService*
ChromePasswordProtectionService::GetPasswordProtectionService(
Profile* profile) { … }
bool ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble(
content::WebContents* web_contents,
PasswordType password_type) { … }
safe_browsing::LoginReputationClientRequest::UrlDisplayExperiment
ChromePasswordProtectionService::GetUrlDisplayExperiment() const { … }
void ChromePasswordProtectionService::ShowModalWarning(
PasswordProtectionRequest* request,
LoginReputationClientResponse::VerdictType verdict_type,
const std::string& verdict_token,
ReusedPasswordAccountType password_type) { … }
void ChromePasswordProtectionService::OnModalWarningShownForSavedPassword(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
const std::string& verdict_token) { … }
void ChromePasswordProtectionService::OnModalWarningShownForGaiaPassword(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
const std::string& verdict_token) { … }
void ChromePasswordProtectionService::OnModalWarningShownForEnterprisePassword(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
const std::string& verdict_token) { … }
void ChromePasswordProtectionService::ShowInterstitial(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type) { … }
void ChromePasswordProtectionService::OnUserAction(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
RequestOutcome outcome,
LoginReputationClientResponse::VerdictType verdict_type,
const std::string& verdict_token,
WarningUIType ui_type,
WarningAction action) { … }
void ChromePasswordProtectionService::AddObserver(Observer* observer) { … }
void ChromePasswordProtectionService::RemoveObserver(Observer* observer) { … }
void ChromePasswordProtectionService::MaybeStartThreatDetailsCollection(
content::WebContents* web_contents,
const std::string& token,
ReusedPasswordAccountType password_type) { … }
void ChromePasswordProtectionService::MaybeFinishCollectingThreatDetails(
content::WebContents* web_contents,
bool did_proceed) { … }
void ChromePasswordProtectionService::MaybeLogPasswordReuseDetectedEvent(
content::WebContents* web_contents) { … }
void ChromePasswordProtectionService::MaybeLogPasswordReuseDialogInteraction(
int64_t navigation_id,
PasswordReuseDialogInteraction::InteractionResult interaction_result) { … }
void ChromePasswordProtectionService::MaybeLogPasswordReuseLookupResult(
content::WebContents* web_contents,
PasswordReuseLookup::LookupResult result) { … }
void ChromePasswordProtectionService::
MaybeLogPasswordReuseLookupResultWithVerdict(
content::WebContents* web_contents,
PasswordType password_type,
PasswordReuseLookup::LookupResult result,
PasswordReuseLookup::ReputationVerdict verdict,
const std::string& verdict_token) { … }
void ChromePasswordProtectionService::MaybeLogPasswordReuseLookupEvent(
content::WebContents* web_contents,
RequestOutcome outcome,
PasswordType password_type,
const LoginReputationClientResponse* response) { … }
void ChromePasswordProtectionService::
CheckGaiaPasswordChangeForAllSignedInUsers(const std::string& username) { … }
void ChromePasswordProtectionService::OnGaiaPasswordChanged(
const std::string& username,
bool is_other_gaia_password) { … }
GURL ChromePasswordProtectionService::GetEnterpriseChangePasswordURL() const { … }
GURL ChromePasswordProtectionService::GetDefaultChangePasswordURL() const { … }
void ChromePasswordProtectionService::HandleUserActionOnModalWarning(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
RequestOutcome outcome,
LoginReputationClientResponse::VerdictType verdict_type,
const std::string& verdict_token,
WarningAction action) { … }
void ChromePasswordProtectionService::LogDialogMetricsOnChangePassword(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
int64_t navigation_id,
RequestOutcome outcome,
LoginReputationClientResponse::VerdictType verdict_type,
const std::string& verdict_token) { … }
void ChromePasswordProtectionService::AddModelWarningBypasstoPref() { … }
void ChromePasswordProtectionService::OpenPasswordCheck(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type) { … }
void ChromePasswordProtectionService::HandleUserActionOnPageInfo(
content::WebContents* web_contents,
ReusedPasswordAccountType password_type,
WarningAction action) { … }
void ChromePasswordProtectionService::HandleResetPasswordOnInterstitial(
content::WebContents* web_contents,
WarningAction action) { … }
std::u16string ChromePasswordProtectionService::GetWarningDetailText(
ReusedPasswordAccountType password_type) const { … }
std::string ChromePasswordProtectionService::GetOrganizationName(
ReusedPasswordAccountType password_type) const { … }
#if !BUILDFLAG(IS_ANDROID)
void ChromePasswordProtectionService::MaybeReportPasswordReuseDetected(
const GURL& main_frame_url,
const std::string& username,
PasswordType password_type,
bool is_phishing_url,
bool warning_shown) { … }
void ChromePasswordProtectionService::ReportPasswordChanged() { … }
#endif
bool ChromePasswordProtectionService::HasUnhandledEnterprisePasswordReuse(
content::WebContents* web_contents) const { … }
void ChromePasswordProtectionService::OnWarningTriggerChanged() { … }
void ChromePasswordProtectionService::OnEnterprisePasswordUrlChanged() { … }
bool ChromePasswordProtectionService::CanShowInterstitial(
ReusedPasswordAccountType password_type,
const GURL& main_frame_url) { … }
void ChromePasswordProtectionService::SetLogPasswordCaptureTimer(
const base::TimeDelta& delay) { … }
void ChromePasswordProtectionService::MaybeLogPasswordCapture(bool did_log_in) { … }
void ChromePasswordProtectionService::UpdateSecurityState(
SBThreatType threat_type,
ReusedPasswordAccountType password_type,
content::WebContents* web_contents) { … }
void ChromePasswordProtectionService::FillReferrerChain(
const GURL& event_url,
SessionID event_tab_id,
LoginReputationClientRequest::Frame* frame) { … }
std::string ChromePasswordProtectionService::GetSyncPasswordHashFromPrefs() { … }
PrefService* ChromePasswordProtectionService::GetPrefs() { … }
bool ChromePasswordProtectionService::IsSafeBrowsingEnabled() { … }
bool ChromePasswordProtectionService::IsExtendedReporting() { … }
bool ChromePasswordProtectionService::IsIncognito() { … }
bool ChromePasswordProtectionService::IsInPasswordAlertMode(
ReusedPasswordAccountType password_type) { … }
bool ChromePasswordProtectionService::IsPingingEnabled(
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type) { … }
RequestOutcome ChromePasswordProtectionService::GetPingNotSentReason(
LoginReputationClientRequest::TriggerType trigger_type,
const GURL& url,
ReusedPasswordAccountType password_type) { … }
void ChromePasswordProtectionService::FillUserPopulation(
const GURL& main_frame_url,
LoginReputationClientRequest* request_proto) { … }
bool ChromePasswordProtectionService::IsPrimaryAccountSyncingHistory() const { … }
bool ChromePasswordProtectionService::IsPrimaryAccountSignedIn() const { … }
bool ChromePasswordProtectionService::IsAccountGmail(
const std::string& username) const { … }
AccountInfo ChromePasswordProtectionService::GetAccountInfoForUsername(
const std::string& username) const { … }
bool ChromePasswordProtectionService::IsInExcludedCountry() { … }
PasswordReuseEvent::SyncAccountType
ChromePasswordProtectionService::GetSyncAccountType() const { … }
void ChromePasswordProtectionService::
RemoveUnhandledSyncPasswordReuseOnURLsDeleted(
bool all_history,
const history::URLRows& deleted_rows) { … }
bool ChromePasswordProtectionService::UserClickedThroughSBInterstitial(
PasswordProtectionRequest* request) { … }
AccountInfo ChromePasswordProtectionService::GetAccountInfo() const { … }
ChromeUserPopulation::UserPopulation
ChromePasswordProtectionService::GetUserPopulationPref() const { … }
ChromePasswordProtectionService::ChromePasswordProtectionService(
Profile* profile,
scoped_refptr<SafeBrowsingUIManager> ui_manager,
StringProvider sync_password_hash_provider,
VerdictCacheManager* cache_manager,
ChangePhishedCredentialsCallback add_phished_credentials,
ChangePhishedCredentialsCallback remove_phished_credentials)
: … { … }
#if BUILDFLAG(IS_ANDROID)
ChromePasswordProtectionService::ChromePasswordProtectionService(
Profile* profile,
scoped_refptr<SafeBrowsingUIManager> ui_manager,
StringProvider sync_password_hash_provider,
VerdictCacheManager* cache_manager,
ChangePhishedCredentialsCallback add_phished_credentials,
ChangePhishedCredentialsCallback remove_phished_credentials,
std::unique_ptr<PasswordCheckupLauncherHelper> checkup_launcher)
: PasswordProtectionService(
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
false,
nullptr,
false,
SafeBrowsingMetricsCollectorFactory::GetForProfile(profile)),
ui_manager_(ui_manager),
trigger_manager_(nullptr),
profile_(profile),
cache_manager_(cache_manager),
add_phished_credentials_(std::move(add_phished_credentials)),
remove_phished_credentials_(std::move(remove_phished_credentials)),
sync_password_hash_provider_for_testing_(sync_password_hash_provider),
checkup_launcher_(std::move(checkup_launcher)) {
Init();
}
#endif
std::unique_ptr<PasswordProtectionCommitDeferringCondition>
MaybeCreateCommitDeferringCondition(
content::NavigationHandle& navigation_handle) { … }
PasswordProtectionTrigger
ChromePasswordProtectionService::GetPasswordProtectionWarningTriggerPref(
ReusedPasswordAccountType password_type) const { … }
bool ChromePasswordProtectionService::IsURLAllowlistedForPasswordEntry(
const GURL& url) const { … }
void ChromePasswordProtectionService::PersistPhishedSavedPasswordCredential(
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials) { … }
void ChromePasswordProtectionService::RemovePhishedSavedPasswordCredential(
const std::vector<password_manager::MatchingReusedCredential>&
matching_reused_credentials) { … }
#if BUILDFLAG(IS_ANDROID)
LoginReputationClientRequest::ReferringAppInfo
ChromePasswordProtectionService::GetReferringAppInfo(
content::WebContents* web_contents) {
ReferringAppInfo info_struct =
safe_browsing::GetReferringAppInfo(web_contents);
LoginReputationClientRequest::ReferringAppInfo info_proto;
info_proto.set_referring_app_source(info_struct.referring_app_source);
info_proto.set_referring_app_name(info_struct.referring_app_name);
return info_proto;
}
#endif
password_manager::PasswordReuseManager*
ChromePasswordProtectionService::GetPasswordReuseManager() const { … }
password_manager::PasswordStoreInterface*
ChromePasswordProtectionService::GetProfilePasswordStore() const { … }
password_manager::PasswordStoreInterface*
ChromePasswordProtectionService::GetAccountPasswordStore() const { … }
void ChromePasswordProtectionService::SanitizeReferrerChain(
ReferrerChain* referrer_chain) { … }
bool ChromePasswordProtectionService::CanSendSamplePing() { … }
void ChromePasswordProtectionService::CacheVerdict(
const GURL& url,
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
const LoginReputationClientResponse& verdict,
const base::Time& receive_time) { … }
LoginReputationClientResponse::VerdictType
ChromePasswordProtectionService::GetCachedVerdict(
const GURL& url,
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
LoginReputationClientResponse* out_response) { … }
int ChromePasswordProtectionService::GetStoredVerdictCount(
LoginReputationClientRequest::TriggerType trigger_type) { … }
#if BUILDFLAG(FULL_SAFE_BROWSING)
gfx::Size ChromePasswordProtectionService::GetCurrentContentAreaSize() const { … }
#endif
password_manager::PasswordStoreInterface*
ChromePasswordProtectionService::GetStoreForReusedCredential(
const password_manager::MatchingReusedCredential& reused_credential) { … }
}