blob: 71b3a0e19d6ca6777b7038600854f09f2d63f75a [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_CHECK_CLIENT_DOWNLOAD_REQUEST_BASE_H_
#define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_CHECK_CLIENT_DOWNLOAD_REQUEST_BASE_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/callback_list.h"
#include "base/cancelable_callback.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
#include "chrome/browser/safe_browsing/download_protection/file_analyzer.h"
#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "chrome/common/safe_browsing/binary_feature_extractor.h"
#include "chrome/services/file_util/public/cpp/sandboxed_rar_analyzer.h"
#include "chrome/services/file_util/public/cpp/sandboxed_zip_analyzer.h"
#include "components/history/core/browser/history_service.h"
#include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h"
#include "components/safe_browsing/core/db/database_manager.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"
#if defined(OS_MAC)
#include "chrome/common/safe_browsing/disk_image_type_sniffer_mac.h"
#include "chrome/services/file_util/public/cpp/sandboxed_dmg_analyzer_mac.h"
#endif
namespace network {
class SimpleURLLoader;
}
namespace safe_browsing {
class CheckClientDownloadRequestBase {
public:
// URL and referrer of the window the download was started from.
struct TabUrls {
GURL url;
GURL referrer;
};
CheckClientDownloadRequestBase(
GURL source_url,
base::FilePath target_file_path,
base::FilePath full_path,
TabUrls tab_urls,
std::string mime_type,
std::string hash,
content::BrowserContext* browser_context,
CheckDownloadCallback callback,
DownloadProtectionService* service,
scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor);
virtual ~CheckClientDownloadRequestBase();
void Start();
DownloadProtectionService* service() const { return service_; }
protected:
// Prepares URLs to be put into a ping message. Currently this just shortens
// data: URIs, other URLs are included verbatim. If this is a sampled binary,
// we'll send a light-ping which strips PII from the URL.
std::string SanitizeUrl(const GURL& url) const;
// Subclasses can call this method to mark the request as finished (for
// example because the download was cancelled) before the safe browsing
// check has completed. This method can end up deleting |this|.
void FinishRequest(DownloadCheckResult result,
DownloadCheckResultReason reason);
private:
using ArchivedBinaries =
google::protobuf::RepeatedPtrField<ClientDownloadRequest_ArchivedBinary>;
bool ShouldSampleWhitelistedDownload();
bool ShouldSampleUnsupportedFile(const base::FilePath& filename);
bool IsDownloadManuallyBlacklisted(const ClientDownloadRequest& request);
void OnUrlWhitelistCheckDone(bool is_whitelisted);
// Performs file feature extraction and SafeBrowsing ping for downloads that
// don't match the URL whitelist.
void AnalyzeFile();
void OnFileFeatureExtractionDone(FileAnalyzer::Results results);
void StartTimeout();
void OnCertificateWhitelistCheckDone(bool is_whitelisted);
void GetTabRedirects();
void OnGotTabRedirects(history::RedirectList redirect_list);
void SendRequest();
void OnURLLoaderComplete(std::unique_ptr<std::string> response_body);
virtual bool IsSupportedDownload(
DownloadCheckResultReason* reason,
ClientDownloadRequest::DownloadType* type) = 0;
virtual content::BrowserContext* GetBrowserContext() const = 0;
virtual bool IsCancelled() = 0;
virtual base::WeakPtr<CheckClientDownloadRequestBase> GetWeakPtr() = 0;
// Called to populate any data in the request that is specific for the type of
// check being done. Most importantly this method is expected to set the hash
// and size of the download, add DOWNLOAD_URL and DOWNLOAD_REDIRECT
// resources to the request, and set the referrer chain.
virtual void PopulateRequest(ClientDownloadRequest* request) = 0;
// Called right before a network request is send to the server.
virtual void NotifySendRequest(const ClientDownloadRequest* request) = 0;
// TODO(mek): The following three methods are all called after receiving a
// response from the server. Perhaps these should be combined into one hook
// for concrete sub classes to implement, rather than having three separate
// hooks with slightly different logic when they are called.
// Called with the download ping token as returned by the server, if one was
// returned.
virtual void SetDownloadPingToken(const std::string& token) = 0;
// Called when a valid response has been received from the server.
virtual void MaybeStorePingsForDownload(DownloadCheckResult result,
bool upload_requested,
const std::string& request_data,
const std::string& response_body) = 0;
// Returns whether or not the file should be uploaded to Safe Browsing for
// deep scanning. Returns the settings to apply for analysis if the file
// should be uploaded for deep scanning, or base::nullopt if it should not.
virtual base::Optional<enterprise_connectors::AnalysisSettings>
ShouldUploadBinary(DownloadCheckResultReason reason) = 0;
// If ShouldUploadBinary returns settings, actually performs the upload to
// Safe Browsing for deep scanning.
virtual void UploadBinary(
DownloadCheckResultReason reason,
enterprise_connectors::AnalysisSettings settings) = 0;
// Called whenever a request has completed.
virtual void NotifyRequestFinished(DownloadCheckResult result,
DownloadCheckResultReason reason) = 0;
// Called when finishing the download, to decide whether to prompt the user
// for deep scanning or not.
virtual bool ShouldPromptForDeepScanning(
DownloadCheckResultReason reason) const = 0;
// Called when |token_fetcher_| has finished fetching the access token.
void OnGotAccessToken(
base::Optional<signin::AccessTokenInfo> access_token_info);
// Called at the request start to determine if we should bailout due to the
// file being whitelisted by policy
virtual bool IsWhitelistedByPolicy() const = 0;
// Source URL being downloaded from. This shuold always be set, but could be
// for example an artificial blob: URL if there is no source URL.
const GURL source_url_;
const base::FilePath target_file_path_;
const base::FilePath full_path_;
// URL and referrer of the window the download was started from.
const GURL tab_url_;
const GURL tab_referrer_url_;
// URL chain of redirects leading to (but not including) |tab_url|.
std::vector<GURL> tab_redirects_;
CheckDownloadCallback callback_;
// A cancelable closure used to track the timeout. If we decide to upload the
// file for deep scanning, we want to cancel the timeout so it doesn't trigger
// in the middle of scanning.
base::CancelableOnceClosure timeout_closure_;
std::unique_ptr<network::SimpleURLLoader> loader_;
std::string client_download_request_data_;
bool archived_executable_ = false;
FileAnalyzer::ArchiveValid archive_is_valid_ =
FileAnalyzer::ArchiveValid::UNSET;
#if defined(OS_MAC)
std::unique_ptr<std::vector<uint8_t>> disk_image_signature_;
google::protobuf::RepeatedPtrField<
ClientDownloadRequest_DetachedCodeSignature>
detached_code_signatures_;
#endif
ClientDownloadRequest_SignatureInfo signature_info_;
std::unique_ptr<ClientDownloadRequest_ImageHeaders> image_headers_;
ArchivedBinaries archived_binaries_;
DownloadProtectionService* const service_;
const scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_;
const scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
const bool pingback_enabled_;
const std::unique_ptr<FileAnalyzer> file_analyzer_ =
std::make_unique<FileAnalyzer>(binary_feature_extractor_);
ClientDownloadRequest::DownloadType type_ =
ClientDownloadRequest::WIN_EXECUTABLE;
base::CancelableTaskTracker request_tracker_; // For HistoryService lookup.
base::TimeTicks start_time_ = base::TimeTicks::Now(); // Used for stats.
base::TimeTicks timeout_start_time_;
base::TimeTicks request_start_time_;
bool skipped_url_whitelist_ = false;
bool skipped_certificate_whitelist_ = false;
bool is_extended_reporting_ = false;
bool is_incognito_ = false;
bool is_under_advanced_protection_ = false;
bool is_enhanced_protection_ = false;
int file_count_;
int directory_count_;
// The mime type of the download, if known.
std::string mime_type_;
// The hash of the download, if known.
std::string hash_;
// The token fetcher used to attach OAuth access tokens to requests for
// appropriately consented users.
std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher_;
// The OAuth access token for the user profile, if needed in the request.
std::string access_token_;
DISALLOW_COPY_AND_ASSIGN(CheckClientDownloadRequestBase);
}; // namespace safe_browsing
} // namespace safe_browsing
#endif // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_CHECK_CLIENT_DOWNLOAD_REQUEST_BASE_H_