| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Utilities for the SafeBrowsing download protection code. |
| |
| #ifndef CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_DOWNLOAD_PROTECTION_UTIL_H_ |
| #define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_DOWNLOAD_PROTECTION_UTIL_H_ |
| |
| #include <optional> |
| |
| #include "base/callback_list.h" |
| #include "chrome/browser/enterprise/connectors/common.h" |
| #include "components/download/public/common/download_danger_type.h" |
| #include "components/download/public/common/download_item.h" |
| #include "components/safe_browsing/buildflags.h" |
| #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" |
| #include "components/safe_browsing/core/browser/download_check_result.h" |
| #include "components/safe_browsing/core/common/proto/csd.pb.h" |
| #include "content/public/browser/file_system_access_write_item.h" |
| #include "net/cert/x509_certificate.h" |
| |
| namespace safe_browsing { |
| |
| class DeepScanningMetadata; |
| |
| // Enum to keep track why a particular download verdict was chosen. |
| // Used for UMA metrics. Do not reorder. |
| // |
| // The UMA enum is called SBClientDownloadCheckDownloadStats. |
| enum DownloadCheckResultReason { |
| REASON_INVALID_URL = 0, |
| REASON_SB_DISABLED = 1, |
| REASON_ALLOWLISTED_URL = 2, |
| REASON_ALLOWLISTED_REFERRER = 3, |
| REASON_INVALID_REQUEST_PROTO = 4, |
| REASON_SERVER_PING_FAILED = 5, |
| REASON_INVALID_RESPONSE_PROTO = 6, |
| REASON_NOT_BINARY_FILE = 7, |
| REASON_REQUEST_CANCELED = 8, |
| REASON_DOWNLOAD_DANGEROUS = 9, |
| REASON_DOWNLOAD_SAFE = 10, |
| REASON_EMPTY_URL_CHAIN = 11, |
| DEPRECATED_REASON_HTTPS_URL = 12, |
| REASON_PING_DISABLED = 13, |
| REASON_TRUSTED_EXECUTABLE = 14, |
| REASON_OS_NOT_SUPPORTED = 15, |
| REASON_DOWNLOAD_UNCOMMON = 16, |
| REASON_DOWNLOAD_NOT_SUPPORTED = 17, |
| REASON_INVALID_RESPONSE_VERDICT = 18, |
| REASON_ARCHIVE_WITHOUT_BINARIES = 19, |
| REASON_DOWNLOAD_DANGEROUS_HOST = 20, |
| REASON_DOWNLOAD_POTENTIALLY_UNWANTED = 21, |
| REASON_UNSUPPORTED_URL_SCHEME = 22, |
| REASON_MANUAL_BLOCKLIST = 23, |
| REASON_LOCAL_FILE = 24, |
| REASON_REMOTE_FILE = 25, |
| REASON_SAMPLED_UNSUPPORTED_FILE = 26, |
| REASON_VERDICT_UNKNOWN = 27, |
| REASON_DOWNLOAD_DESTROYED = 28, |
| REASON_BLOCKED_PASSWORD_PROTECTED = 29, |
| REASON_BLOCKED_TOO_LARGE = 30, |
| REASON_SENSITIVE_CONTENT_WARNING = 31, |
| REASON_SENSITIVE_CONTENT_BLOCK = 32, |
| REASON_DEEP_SCANNED_SAFE = 33, |
| REASON_DEEP_SCAN_PROMPT = 34, |
| REASON_BLOCKED_UNSUPPORTED_FILE_TYPE = 35, |
| REASON_DOWNLOAD_DANGEROUS_ACCOUNT_COMPROMISE = 36, |
| REASON_LOCAL_DECRYPTION_PROMPT = 37, |
| REASON_LOCAL_DECRYPTION_FAILED = 38, |
| REASON_IMMEDIATE_DEEP_SCAN = 39, |
| REASON_IGNORED_VERDICT = 40, |
| REASON_MAX // Always add new values before this one. |
| }; |
| |
| // Enumerate for histogramming purposes. |
| // DO NOT CHANGE THE ORDERING OF THESE VALUES (different histogram data will |
| // be mixed together based on their values). |
| enum SBStatsType { |
| DOWNLOAD_URL_CHECKS_TOTAL, |
| DEPRECATED_DOWNLOAD_URL_CHECKS_CANCELED, |
| DOWNLOAD_URL_CHECKS_MALWARE, |
| |
| DEPRECATED_DOWNLOAD_HASH_CHECKS_TOTAL, |
| DEPRECATED_DOWNLOAD_HASH_CHECKS_MALWARE, |
| |
| // Memory space for histograms is determined by the max. |
| // ALWAYS ADD NEW VALUES BEFORE THIS ONE. |
| DOWNLOAD_CHECKS_MAX |
| }; |
| |
| enum AllowlistType { |
| NO_ALLOWLIST_MATCH, |
| URL_ALLOWLIST, |
| SIGNATURE_ALLOWLIST, |
| ALLOWLIST_TYPE_MAX |
| }; |
| |
| // Enum for events related to the deep scanning of a download. These values |
| // are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class DeepScanEvent { |
| kPromptShown = 0, |
| kPromptBypassed = 1, |
| kPromptAccepted = 2, |
| kScanCanceled = 3, |
| kScanCompleted = 4, |
| kScanFailed = 5, |
| kScanDeleted = 6, |
| kPromptAcceptedFromWebUI = 7, |
| kIncorrectPassword = 8, |
| kMaxValue = kIncorrectPassword, |
| }; |
| |
| // Describes whether a given download may send a download ping. |
| enum class MayCheckDownloadResult { |
| // The download may not send a ping. This may be due to properties of the |
| // download/file itself (see DownloadCheckResultReason) or due to other logic |
| // applied by DownloadProtection{Service,Delegate}. |
| kMayNotCheckDownload, |
| // The download may send a ping, but only a "light" ping may be sent if the |
| // download is sampled. |
| kMaySendSampledPingOnly, |
| // The download is fully supported for CheckClientDownload and may send a full |
| // download ping. |
| kMayCheckDownload, |
| }; |
| |
| void LogDeepScanEvent(download::DownloadItem* item, DeepScanEvent event); |
| void LogDeepScanEvent(const DeepScanningMetadata& metadata, |
| DeepScanEvent event); |
| void LogLocalDecryptionEvent(DeepScanEvent event); |
| |
| // Callback type which is invoked once the download request is done. |
| typedef base::OnceCallback<void(DownloadCheckResult)> CheckDownloadCallback; |
| |
| // Callback type which is invoked once the download request is done. This is |
| // used in cases where asynchronous scanning is allowed, so the callback is |
| // triggered multiple times (once when asynchronous scanning begins, once when |
| // the final result is ready). |
| typedef base::RepeatingCallback<void(DownloadCheckResult)> |
| CheckDownloadRepeatingCallback; |
| |
| // Callbacks run on the main thread when a ClientDownloadRequest has |
| // been formed for a download, or when one has not been formed for a supported |
| // download. |
| using ClientDownloadRequestCallbackList = |
| base::RepeatingCallbackList<void(download::DownloadItem*, |
| const ClientDownloadRequest*)>; |
| using ClientDownloadRequestCallback = |
| ClientDownloadRequestCallbackList::CallbackType; |
| |
| // Callbacks run on the main thread when a FileSystemAccessWriteRequest has been |
| // formed for a write operation. |
| using FileSystemAccessWriteRequestCallbackList = |
| base::RepeatingCallbackList<void(const ClientDownloadRequest*)>; |
| using FileSystemAccessWriteRequestCallback = |
| FileSystemAccessWriteRequestCallbackList::CallbackType; |
| |
| // Types used for the BarrierCallback mechanism in |
| // CheckClientDownloadRequestBase::StartModificationsFromDelegate(): |
| |
| // Callback that, when invoked, makes a modification to a ClientDownloadRequest. |
| using ClientDownloadRequestModification = |
| base::OnceCallback<void(ClientDownloadRequest*)>; |
| // Type of the helper callback that should be called exactly once for each |
| // ClientDownloadRequestModification that should be done. Calling the |
| // CollectModificationCallback collects a modification, i.e. registers the |
| // modification to be executed on the ClientDownloadRequest after all such |
| // modifications have been collected. |
| using CollectModificationCallback = |
| base::OnceCallback<void(ClientDownloadRequestModification)>; |
| // Callback that, when run, generates an appropriate |
| // ClientDownloadRequestModification that should be executed, and invokes |
| // the passed-in CollectModificationCallback with the desired modification. |
| using PendingClientDownloadRequestModification = |
| base::OnceCallback<void(CollectModificationCallback)>; |
| |
| // Returns a ClientDownloadRequestModification that is a no-op. |
| ClientDownloadRequestModification NoModificationToRequestProto(); |
| |
| // Given a certificate and its immediate issuer certificate, generates the |
| // list of strings that need to be checked against the download allowlist to |
| // determine whether the certificate is allowlisted. |
| void GetCertificateAllowlistStrings( |
| const net::X509Certificate& certificate, |
| const net::X509Certificate& issuer, |
| std::vector<std::string>* allowlist_strings); |
| |
| GURL GetFileSystemAccessDownloadUrl(const GURL& frame_url); |
| |
| // Determine which entries from `src_binaries` should be sent in the download |
| // ping. |
| google::protobuf::RepeatedPtrField<ClientDownloadRequest::ArchivedBinary> |
| SelectArchiveEntries(const google::protobuf::RepeatedPtrField< |
| ClientDownloadRequest::ArchivedBinary>& src_binaries); |
| |
| // Identify referrer chain info of a download. This function also |
| // records UMA stats of download attribution result. The referrer chain |
| // will include at most `user_gesture_limit` user gestures. |
| std::unique_ptr<ReferrerChainData> IdentifyReferrerChain( |
| const download::DownloadItem& item, |
| int user_gesture_limit); |
| |
| // Identify referrer chain info of a File System Access write. This |
| // function also records UMA stats of download attribution result. The |
| // referrer chain will include at most `user_gesture_limit` user |
| // gestures. |
| std::unique_ptr<ReferrerChainData> IdentifyReferrerChain( |
| const content::FileSystemAccessWriteItem& item, |
| int user_gesture_limit); |
| |
| // Returns the referrer chain based on download item for enterprise reporting. |
| // This function will identify and attach the referrer chain to the |
| // `DownloadItem` if it has not been previously identified. |
| ReferrerChain GetOrIdentifyReferrerChainForEnterprise( |
| download::DownloadItem& item); |
| |
| #if BUILDFLAG(SAFE_BROWSING_DOWNLOAD_PROTECTION) |
| // Returns true if dangerous download report should be sent. |
| bool ShouldSendDangerousDownloadReport( |
| download::DownloadItem* item, |
| ClientSafeBrowsingReportRequest::ReportType report_type); |
| #endif |
| |
| // If the item should be uploaded for deep scanning, this returns the content |
| // analysis settings to use. If the item should not be uploaded, this returns |
| // nullopt. |
| std::optional<enterprise_connectors::AnalysisSettings> |
| ShouldUploadBinaryForDeepScanning(download::DownloadItem* item); |
| |
| // Returns whether the filetype is eligible for a full download protection ping, |
| // based only on the file name extension. |
| bool IsFiletypeSupportedForFullDownloadProtection( |
| const base::FilePath& file_name); |
| |
| } // namespace safe_browsing |
| |
| #endif // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_DOWNLOAD_PROTECTION_UTIL_H_ |