1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_SAFE_BROWSING_CORE_VERDICT_CACHE_MANAGER_H_ 6 #define COMPONENTS_SAFE_BROWSING_CORE_VERDICT_CACHE_MANAGER_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "base/memory/scoped_refptr.h" 10 #include "base/memory/weak_ptr.h" 11 #include "base/scoped_observation.h" 12 #include "base/time/time.h" 13 #include "base/timer/timer.h" 14 #include "base/values.h" 15 #include "components/content_settings/core/browser/host_content_settings_map.h" 16 #include "components/history/core/browser/history_service.h" 17 #include "components/history/core/browser/history_service_observer.h" 18 #include "components/keyed_service/core/keyed_service.h" 19 #include "components/safe_browsing/core/proto/csd.pb.h" 20 #include "components/safe_browsing/core/proto/realtimeapi.pb.h" 21 #include "url/gurl.h" 22 23 class HostContentSettingsMap; 24 25 namespace safe_browsing { 26 27 using ReusedPasswordAccountType = 28 LoginReputationClientRequest::PasswordReuseEvent::ReusedPasswordAccountType; 29 30 // Structure: http://screen/YaNfDRYrcnk.png. 31 class VerdictCacheManager : public history::HistoryServiceObserver, 32 public KeyedService { 33 public: 34 explicit VerdictCacheManager( 35 history::HistoryService* history_service, 36 scoped_refptr<HostContentSettingsMap> content_settings); 37 VerdictCacheManager(const VerdictCacheManager&) = delete; 38 VerdictCacheManager& operator=(const VerdictCacheManager&) = delete; 39 VerdictCacheManager(VerdictCacheManager&&) = delete; 40 VerdictCacheManager& operator=(const VerdictCacheManager&&) = delete; 41 42 ~VerdictCacheManager() override; 43 GetWeakPtr()44 base::WeakPtr<VerdictCacheManager> GetWeakPtr() { 45 return weak_factory_.GetWeakPtr(); 46 } 47 48 // KeyedService: 49 // Called before the actual deletion of the object. 50 void Shutdown() override; 51 52 // Stores |verdict| in |content_settings_| based on its |trigger_type|, |url|, 53 // reused |password_type|, |verdict| and |receive_time|. 54 void CachePhishGuardVerdict( 55 LoginReputationClientRequest::TriggerType trigger_type, 56 ReusedPasswordAccountType password_type, 57 const LoginReputationClientResponse& verdict, 58 const base::Time& receive_time); 59 60 // Looks up |content_settings_| to find the cached verdict response. If 61 // verdict is not available or is expired, return VERDICT_TYPE_UNSPECIFIED. 62 // Can be called on any thread. 63 LoginReputationClientResponse::VerdictType GetCachedPhishGuardVerdict( 64 const GURL& url, 65 LoginReputationClientRequest::TriggerType trigger_type, 66 ReusedPasswordAccountType password_type, 67 LoginReputationClientResponse* out_response); 68 69 // Gets the total number of verdicts of the specified |trigger_type| we cached 70 // for this profile. This counts both expired and active verdicts. 71 size_t GetStoredPhishGuardVerdictCount( 72 LoginReputationClientRequest::TriggerType trigger_type); 73 74 // Stores |verdict| in |content_settings_| based on its |url|, |verdict| and 75 // |receive_time|. 76 // |store_old_cache| is used for compatibility test. It is set to true only 77 // when we need to store an old cache for testing. 78 // TODO(crbug.com/1049376): |store_old_cache| should be removed once 79 // |cache_expression| field is deprecated. 80 void CacheRealTimeUrlVerdict(const GURL& url, 81 const RTLookupResponse& verdict, 82 const base::Time& receive_time, 83 bool store_old_cache); 84 85 // Looks up |content_settings_| to find the cached verdict response. If 86 // verdict is not available or is expired, return VERDICT_TYPE_UNSPECIFIED. 87 // Otherwise, the most matching theat info will be copied to out_threat_info. 88 // Can be called on any thread. 89 RTLookupResponse::ThreatInfo::VerdictType GetCachedRealTimeUrlVerdict( 90 const GURL& url, 91 RTLookupResponse::ThreatInfo* out_threat_info); 92 93 // Overridden from history::HistoryServiceObserver. 94 void OnURLsDeleted(history::HistoryService* history_service, 95 const history::DeletionInfo& deletion_info) override; 96 97 void HistoryServiceBeingDeleted( 98 history::HistoryService* history_service) override; 99 100 // Returns true if an artificial unsafe URL has been provided using the 101 // command-line flag "mark_as_real_time_phishing". 102 static bool has_artificial_unsafe_url(); 103 104 void StopCleanUpTimerForTesting(); 105 106 private: 107 friend class SafeBrowsingBlockingPageRealTimeUrlCheckTest; 108 FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest, TestCleanUpExpiredVerdict); 109 FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest, 110 TestCleanUpExpiredVerdictWithInvalidEntry); 111 FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest, 112 TestRemoveCachedVerdictOnURLsDeleted); 113 FRIEND_TEST_ALL_PREFIXES( 114 VerdictCacheManagerTest, 115 TestRemoveRealTimeUrlCheckCachedVerdictOnURLsDeleted); 116 FRIEND_TEST_ALL_PREFIXES(VerdictCacheManagerTest, 117 TestCleanUpExpiredVerdictInBackground); 118 119 void ScheduleNextCleanUpAfterInterval(base::TimeDelta interval); 120 121 // Removes all the expired verdicts from cache. 122 void CleanUpExpiredVerdicts(); 123 void CleanUpExpiredPhishGuardVerdicts(); 124 void CleanUpExpiredRealTimeUrlCheckVerdicts(); 125 126 // Helper method to remove content settings when URLs are deleted. If 127 // |all_history| is true, removes all cached verdicts. Otherwise it removes 128 // all verdicts associated with the deleted URLs in |deleted_rows|. 129 void RemoveContentSettingsOnURLsDeleted(bool all_history, 130 const history::URLRows& deleted_rows); 131 bool RemoveExpiredPhishGuardVerdicts( 132 LoginReputationClientRequest::TriggerType trigger_type, 133 base::Value* cache_dictionary); 134 bool RemoveExpiredRealTimeUrlCheckVerdicts(base::Value* cache_dictionary); 135 136 size_t GetPhishGuardVerdictCountForURL( 137 const GURL& url, 138 LoginReputationClientRequest::TriggerType trigger_type); 139 // This method is only used for testing. 140 size_t GetRealTimeUrlCheckVerdictCountForURL(const GURL& url); 141 // Gets the total number of RealTimeUrlCheck verdicts we cached 142 // for this profile. This counts both expired and active verdicts. 143 size_t GetStoredRealTimeUrlCheckVerdictCount(); 144 145 // This adds a cached verdict for a URL that has artificially been marked as 146 // unsafe using the command line flag "mark_as_real_time_phishing". 147 void CacheArtificialVerdict(); 148 149 // Number of verdict stored for this profile for password on focus pings. 150 base::Optional<size_t> stored_verdict_count_password_on_focus_; 151 152 // Number of verdict stored for this profile for protected password entry 153 // pings. 154 base::Optional<size_t> stored_verdict_count_password_entry_; 155 156 // Number of verdict stored for this profile for real time url check pings. 157 base::Optional<size_t> stored_verdict_count_real_time_url_check_; 158 159 base::ScopedObservation<history::HistoryService, 160 history::HistoryServiceObserver> 161 history_service_observation_{this}; 162 163 // Content settings maps associated with this instance. 164 scoped_refptr<HostContentSettingsMap> content_settings_; 165 166 base::OneShotTimer cleanup_timer_; 167 168 base::WeakPtrFactory<VerdictCacheManager> weak_factory_{this}; 169 170 static bool has_artificial_unsafe_url_; 171 }; 172 173 } // namespace safe_browsing 174 175 #endif // COMPONENTS_SAFE_BROWSING_CORE_VERDICT_CACHE_MANAGER_H_ 176