blob: 4cf04ad2a56b35068e43b39b5ff58fe67484e551 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SAFE_BROWSING_CORE_BROWSER_VERDICT_CACHE_MANAGER_H_
#define COMPONENTS_SAFE_BROWSING_CORE_BROWSER_VERDICT_CACHE_MANAGER_H_
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_cache.h"
#include "components/safe_browsing/core/browser/safe_browsing_sync_observer.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "components/safe_browsing/core/common/proto/realtimeapi.pb.h"
#include "components/safe_browsing/core/common/proto/safebrowsingv5_alpha1.pb.h"
#include "url/gurl.h"
class HostContentSettingsMap;
namespace safe_browsing {
using ReusedPasswordAccountType =
LoginReputationClientRequest::PasswordReuseEvent::ReusedPasswordAccountType;
// Structure: http://screen/YaNfDRYrcnk.png.
class VerdictCacheManager : public history::HistoryServiceObserver,
public KeyedService {
public:
VerdictCacheManager(history::HistoryService* history_service,
scoped_refptr<HostContentSettingsMap> content_settings,
PrefService* pref_service,
std::unique_ptr<SafeBrowsingSyncObserver> sync_observer);
VerdictCacheManager(const VerdictCacheManager&) = delete;
VerdictCacheManager& operator=(const VerdictCacheManager&) = delete;
VerdictCacheManager(VerdictCacheManager&&) = delete;
VerdictCacheManager& operator=(const VerdictCacheManager&&) = delete;
~VerdictCacheManager() override;
base::WeakPtr<VerdictCacheManager> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// KeyedService:
// Called before the actual deletion of the object.
void Shutdown() override;
// Stores |verdict| in |content_settings_| based on its |trigger_type|, |url|,
// reused |password_type|, |verdict| and |receive_time|.
void CachePhishGuardVerdict(
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
const LoginReputationClientResponse& verdict,
const base::Time& receive_time);
// Looks up |content_settings_| to find the cached verdict response. If
// verdict is not available or is expired, return VERDICT_TYPE_UNSPECIFIED.
// Can be called on any thread.
LoginReputationClientResponse::VerdictType GetCachedPhishGuardVerdict(
const GURL& url,
LoginReputationClientRequest::TriggerType trigger_type,
ReusedPasswordAccountType password_type,
LoginReputationClientResponse* out_response);
// Gets the total number of verdicts of the specified |trigger_type| we cached
// for this profile. This counts both expired and active verdicts.
size_t GetStoredPhishGuardVerdictCount(
LoginReputationClientRequest::TriggerType trigger_type);
// Stores |verdict| in |content_settings_| based on its |url|, |verdict| and
// |receive_time|.
void CacheRealTimeUrlVerdict(const GURL& url,
const RTLookupResponse& verdict,
const base::Time& receive_time);
// Looks up |content_settings_| to find the cached verdict response. If
// verdict is not available or is expired, return VERDICT_TYPE_UNSPECIFIED.
// Otherwise, the most matching theat info will be copied to out_threat_info.
// Can be called on any thread.
RTLookupResponse::ThreatInfo::VerdictType GetCachedRealTimeUrlVerdict(
const GURL& url,
RTLookupResponse::ThreatInfo* out_threat_info);
safe_browsing::ClientSideDetectionType
GetCachedRealTimeUrlClientSideDetectionType(const GURL& url);
// Creates a page load token that is tied with the hostname of the |url|.
// The token is stored in memory.
ChromeUserPopulation::PageLoadToken CreatePageLoadToken(const GURL& url);
// Gets the page load token for the hostname of the |url|. Returns an empty
// token if the token is not found.
ChromeUserPopulation::PageLoadToken GetPageLoadToken(const GURL& url);
// Stores the results of a hash-prefix real-time lookup into a cache object.
void CacheHashPrefixRealTimeLookupResults(
const std::vector<std::string>& requested_hash_prefixes,
const std::vector<V5::FullHash>& response_full_hashes,
const V5::Duration& cache_duration);
// Searches the hash-prefix real-time cache object for the requested
// |hash_prefixes|.
std::unordered_map<std::string, std::vector<V5::FullHash>>
GetCachedHashPrefixRealTimeLookupResults(
const std::set<std::string>& hash_prefixes);
// Overridden from history::HistoryServiceObserver.
void OnURLsDeleted(history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) override;
void HistoryServiceBeingDeleted(
history::HistoryService* history_service) override;
// Called by browsing data remover.
void OnCookiesDeleted();
// Returns true if an artificial unsafe URL has been provided using
// command-line flags.
static bool has_artificial_unsafe_url();
void StopCleanUpTimerForTesting();
void SetPageLoadTokenForTesting(const GURL& url,
ChromeUserPopulation::PageLoadToken token);
private:
friend class SafeBrowsingBlockingPageRealTimeUrlCheckTest;
friend class VerdictCacheManagerTest;
FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest, TestCleanUpExpiredVerdict);
FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest,
TestCleanUpExpiredVerdictWithInvalidEntry);
FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest,
TestRemoveCachedVerdictOnURLsDeleted);
FRIEND_TEST_ALL_PREFIXES(
VerdictCacheManagerTest,
TestRemoveRealTimeUrlCheckCachedVerdictOnURLsDeleted);
FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest,
TestCleanUpExpiredVerdictInBackground);
FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest,
TestCleanUpVerdictOlderThanUpperBound);
// Enum representing the reason why page load tokens are cleared. Used to log
// histograms. Entries must not be removed or reordered.
enum class ClearReason {
kSafeBrowsingStateChanged = 0,
kCookiesDeleted = 1,
kSyncStateChanged = 2,
kMaxValue = kSyncStateChanged
};
void ScheduleNextCleanUpAfterInterval(base::TimeDelta interval);
// Removes all the expired verdicts from cache.
void CleanUpExpiredVerdicts();
void CleanUpExpiredPhishGuardVerdicts();
void CleanUpExpiredRealTimeUrlCheckVerdicts();
void CleanUpExpiredPageLoadTokens();
void CleanUpAllPageLoadTokens(ClearReason reason);
void CleanUpExpiredHashPrefixRealTimeLookupResults();
// Helper method to remove content settings when URLs are deleted. If
// |all_history| is true, removes all cached verdicts. Otherwise it removes
// all verdicts associated with the deleted URLs in |deleted_rows|.
void RemoveContentSettingsOnURLsDeleted(bool all_history,
const history::URLRows& deleted_rows);
bool RemoveExpiredPhishGuardVerdicts(
LoginReputationClientRequest::TriggerType trigger_type,
base::Value::Dict& cache_dictionary);
bool RemoveExpiredRealTimeUrlCheckVerdicts(
base::Value::Dict& cache_dictionary);
size_t GetPhishGuardVerdictCountForURL(
const GURL& url,
LoginReputationClientRequest::TriggerType trigger_type);
// This method is only used for testing.
size_t GetRealTimeUrlCheckVerdictCountForURL(const GURL& url);
// Gets the total number of RealTimeUrlCheck verdicts we cached
// for this profile. This counts both expired and active verdicts.
size_t GetStoredRealTimeUrlCheckVerdictCount();
// This adds a cached verdict for a URL that has artificially been marked as
// unsafe using the command line flag "mark_as_real_time_phishing".
void CacheArtificialRealTimeUrlVerdict();
// This adds a cached verdict for a URL that has artificially been marked as
// unsafe using the command line flag "mark_as_phish_guard_phishing".
void CacheArtificialPhishGuardVerdict();
// Number of verdict stored for this profile for password on focus pings.
absl::optional<size_t> stored_verdict_count_password_on_focus_;
// Number of verdict stored for this profile for protected password entry
// pings.
absl::optional<size_t> stored_verdict_count_password_entry_;
// Number of verdict stored for this profile for real time url check pings.
absl::optional<size_t> stored_verdict_count_real_time_url_check_;
// A map of page load tokens, keyed by the hostname.
base::flat_map<std::string, ChromeUserPopulation::PageLoadToken>
page_load_token_map_;
base::ScopedObservation<history::HistoryService,
history::HistoryServiceObserver>
history_service_observation_{this};
// Content settings maps associated with this instance.
scoped_refptr<HostContentSettingsMap> content_settings_;
base::OneShotTimer cleanup_timer_;
PrefChangeRegistrar pref_change_registrar_;
std::unique_ptr<SafeBrowsingSyncObserver> sync_observer_;
// The local cache object for hash-prefix real-time lookups.
std::unique_ptr<HashRealTimeCache> hash_realtime_cache_ =
std::make_unique<HashRealTimeCache>();
bool is_shut_down_ = false;
base::WeakPtrFactory<VerdictCacheManager> weak_factory_{this};
static bool has_artificial_unsafe_url_;
};
} // namespace safe_browsing
#endif // COMPONENTS_SAFE_BROWSING_CORE_BROWSER_VERDICT_CACHE_MANAGER_H_