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
|
// Copyright 2022 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_ANDROID_REAL_TIME_URL_CHECKS_ALLOWLIST_H_
#define COMPONENTS_SAFE_BROWSING_ANDROID_REAL_TIME_URL_CHECKS_ALLOWLIST_H_
#include <set>
#include <string>
#include "base/synchronization/lock.h"
#include "base/timer/elapsed_timer.h"
#include "url/gurl.h"
namespace safe_browsing {
// This singleton is responsible for parsing and storing the real-time URL
// checks allowlist for use by Protego on Android. This is updated periodically
// by the component updater.
class RealTimeUrlChecksAllowlist {
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused. The purpose of each value is to
// either show that populating the result was successful or provide the
// reason for failing to populate the allowlist. These errors range from
// proto parsing errors to invalid pb file formatting errors.
enum class PopulateResult {
// Populated the new allowlist successfully.
kSuccess = 0,
// Input binary file is empty.
kFailedEmpty = 1,
// Input binary file couldn't be parsed into a HighConfidenceAllowlist
// object.
kFailedProtoParse = 2,
// Failed because no URL hashes were provided.
kFailedMissingUrlHashes = 3,
// Failed because no version id was provided.
kFailedMissingVersionId = 4,
// Failed because no scheme id was provided.
kFailedMissingSchemeId = 5,
// Failed because the provided concatenated URL hash string is empty.
kFailedEmptyUrlHashes = 6,
// Failed because url_hashes is not formatted correctly. The length of the
// string must be divisible by the size of a URL hash because the url_hashes
// string contains the concatenated hashes of allowlisted URLs.
kFailedDanglingHash = 7,
// Skip populating the new allowlist because the version id is old. If this
// happens, we will use the allowlist that was generated from the resource
// file.
kSkippedOldVersionId = 8,
// Skip populating the new allowlist because the version id did not change.
// This means that the contents of the "new" allowlist would be the same as
// the allowlist that has already been generated.
kSkippedEqualVersionId = 9,
// Skip populating the new allowlist because the scheme id has changed,
// which means the format of the binary pb is incompatible. If this happens,
// we will use the allowlist that was generated from the resource file.
kSkippedInvalidSchemeId = 10,
// Failed because the length of the concatenated hashes exceeds the maximum
// length we can work with.
kFailedHashLengthExceedsMax = 11,
// Failed because there are not enough URL hashes provided to generate the
// new allowlist. The minimum number of URL hashes required for populating
// is 100, but this number can be changed for testing.
kFailedTooFewAllowlistEntries = 12,
kMaxValue = kFailedTooFewAllowlistEntries,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class IsInAllowlistResult {
kNotInAllowlist = 0,
kInAllowlist = 1,
kAllowlistUnavailable = 2,
kMaxValue = kAllowlistUnavailable,
};
virtual ~RealTimeUrlChecksAllowlist();
static RealTimeUrlChecksAllowlist* GetInstance(); // Singleton
static void SetInstanceForTesting(
RealTimeUrlChecksAllowlist* instance_for_testing);
// Updates the internal allowlist from a binary proto fetched from the
// component updater.
virtual void PopulateFromDynamicUpdate(const std::string& binary_pb);
// Returns whether the provided URL has a match in the local allowlist.
IsInAllowlistResult IsInAllowlist(const GURL& url);
mutable base::Lock lock_;
protected:
RealTimeUrlChecksAllowlist();
private:
friend class RealTimeUrlChecksAllowlistResourceFileTest;
friend struct RealTimeUrlChecksAllowlistSingletonTrait;
friend class RealTimeUrlChecksAllowlistTest;
// Updates the internal allowlist from the local resource file.
void PopulateFromResourceBundle();
// Validate the binary_pb contents and if valid, update the allowlist
// URL hashes and version.
virtual PopulateResult PopulateAllowlistFromBinaryPb(std::string binary_pb);
// Searches the allowlist_patterns_for URL hash.
IsInAllowlistResult IsInAllowlistInternal(const GURL& url);
// Sets the minimum_hash_entry_count_ value so that we don't need an
// allowlist with 100+ entries for testing.
void SetMinimumEntryCountForTesting(size_t new_hash_entry_count);
// Record UMA data relevant for populating the allowlist.
virtual void RecordPopulateMetrics(PopulateResult result,
const std::string& src_name);
// Record UMA data relevant for checking the allowlist for a URL.
virtual void RecordAllowlistUrlCheckMetrics(IsInAllowlistResult result,
const std::string& src_name);
static RealTimeUrlChecksAllowlist* instance_for_testing_;
// Set of URL hash prefixes in the safe browsing allowlist.
// We are not using a flat_set because these are ideal for small sets, but
// the allowlist contains roughly 2,000 strings so we are using std::set.
std::set<std::string> allowlist_patterns_;
// Version of the allowlist, same as version_id in realtimeallowlist.proto.
int version_id_;
// Scheme id of the allowlist, same as scheme_id in realtimeallowlist.proto.
// This attribute is used for backwards compatibility. If there are breaking
// changes to the code, then the kValidSchemeId value (the default scheme id)
// should be modified in the code.
int scheme_id_;
// Minimum number of hash entries required for the allowlist to be valid.
size_t minimum_hash_entry_count_;
// True if we have successfully fetched the dynamic resource for the allowlist
// and populated the allowlist with it.
bool is_using_component_updater_version_ = false;
};
} // namespace safe_browsing
#endif // COMPONENTS_SAFE_BROWSING_ANDROID_REAL_TIME_URL_CHECKS_ALLOWLIST_H_
|