File: check_client_download_request_base.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (259 lines) | stat: -rw-r--r-- 10,948 bytes parent folder | download | duplicates (3)
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// 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.

#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 <optional>
#include <string>
#include <vector>

#include "base/callback_list.h"
#include "base/cancelable_callback.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.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/download_request_maker.h"
#include "chrome/browser/safe_browsing/download_protection/file_analyzer.h"
#include "components/history/core/browser/history_service.h"
#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
#include "components/safe_browsing/content/browser/ui_manager.h"
#include "components/safe_browsing/core/browser/db/database_manager.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"

namespace network {
class SimpleURLLoader;
}

namespace safe_browsing {

class DownloadProtectionService;

#if !BUILDFLAG(IS_ANDROID)
class SafeBrowsingTokenFetcher;
#endif

class CheckClientDownloadRequestBase {
 public:
  CheckClientDownloadRequestBase(
      GURL source_url,
      base::FilePath target_file_path,
      content::BrowserContext* browser_context,
      CheckDownloadCallback callback,
      DownloadProtectionService* service,
      scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
      std::unique_ptr<DownloadRequestMaker> download_request_maker);

  CheckClientDownloadRequestBase(const CheckClientDownloadRequestBase&) =
      delete;
  CheckClientDownloadRequestBase& operator=(
      const CheckClientDownloadRequestBase&) = delete;

  virtual ~CheckClientDownloadRequestBase();

  void Start();

  DownloadProtectionService* service() const { return service_; }

  virtual download::DownloadItem* item() const = 0;

  CheckDownloadCallback TakeCallback() { return std::move(callback_); }

 protected:
  // 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 ShouldSampleAllowlistedDownload();
  bool ShouldSampleUnsupportedFile(const base::FilePath& filename);
  bool IsDownloadManuallyBlocklisted(const ClientDownloadRequest& request);

  void OnUrlAllowlistCheckDone(bool is_allowlisted);
  void OnRequestBuilt(DownloadRequestMaker::RequestCreationDetails details,
                      std::unique_ptr<ClientDownloadRequest> request_proto);

  // Give the DownloadProtectionDelegate a chance to modify the request proto
  // in various ways before serializing and sending it. This is a two-phase
  // process because the individual modifications may be asynchronous.
  // First, `StartModificationsFromDelegate()` solicits a number of pending
  // modifications from the delegate, in the form of callbacks, which it
  // kicks off to evaluate the modifications (potentially simultaneously and
  // asynchronously). Then, `ApplyModificationsAndSendRequest` is run when the
  // modifications have all been computed, to apply the modifications and
  // continue with the request flow. There are no ordering guarantees on the
  // modifications that ultimately get run.
  void StartModificationsFromDelegate();
  void ApplyModificationsAndSendRequest(
      std::vector<ClientDownloadRequestModification> modifications);

  void StartTimeout();
  void SendRequest();
  void OnURLLoaderComplete(std::unique_ptr<std::string> response_body);

  // If we need to perform additional prompting (e.g. deep scanning, local
  // password decryption) due to the response, this method will update `result`
  // and `reason` appropriately. This method also performs logging related to
  // these additional prompts. If both prompts are allowed, deep scanning will
  // be prioritized.
  void GetAdditionalPromptResult(const ClientDownloadResponse& response,
                                 DownloadCheckResult* result,
                                 DownloadCheckResultReason* reason,
                                 std::string* token) const;

  // Returns enum value indicating whether `item` is eligible for
  // CheckClientDownloadRequest. If return value is not kMayCheckDownload, then
  // `reason` will be populated with the reason why.
  // TODO(chlily): Rename this method since it does not return a bool.
  virtual MayCheckDownloadResult IsSupportedDownload(
      DownloadCheckResultReason* reason) = 0;

  virtual content::BrowserContext* GetBrowserContext() const = 0;
  virtual bool IsCancelled() = 0;
  virtual base::WeakPtr<CheckClientDownloadRequestBase> GetWeakPtr() = 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 client download response as returned by the server, if one
  // was returned and the returned verdict is unsafe (i.e. not safe or unknown).
  virtual void SetDownloadProtectionData(
      const std::string& token,
      const ClientDownloadResponse::Verdict& verdict,
      const ClientDownloadResponse::TailoredVerdict& tailored_verdict) = 0;

  // TODO(crbug.com/397407934): Download feedback is not supported on Android
  // yet, but it will be.
#if !BUILDFLAG(IS_ANDROID)
  // Called when a valid response has been received from the server.
  virtual void MaybeBeginFeedbackForDownload(
      DownloadCheckResult result,
      bool upload_requested,
      const std::string& request_data,
      const std::string& response_body) = 0;
#endif

  // 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 std::nullopt if it should not.
  virtual std::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(
      DownloadCheckResult result,
      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
  // immediately start deep scanning or not.
  virtual bool ShouldImmediatelyDeepScan(bool server_requests_prompt) const = 0;

  // Called when finishing the download, to decide whether to prompt the user
  // for deep scanning or not.
  virtual bool ShouldPromptForDeepScanning(
      bool server_requests_prompt) const = 0;

  // Called when finishing the download, to decide whether to prompt the user
  // for local decryption or not.
  virtual bool ShouldPromptForLocalDecryption(
      bool server_requests_prompt) const = 0;

#if !BUILDFLAG(IS_ANDROID)
  // Called when |token_fetcher_| has finished fetching the access token.
  void OnGotAccessToken(const std::string& access_token);
#endif

  // Called at the request start to determine if we should bailout due to the
  // file being allowlisted by policy
  virtual bool IsAllowlistedByPolicy() const = 0;

  // For sampled unsupported file types, replaces all URLs in
  // |client_download_request_| with their origin.
  void SanitizeRequest();

  // Called when we decide whether or not to show a deep scanning prompt
  virtual void LogDeepScanningPrompt(bool did_prompt) const = 0;

  // Returns whether we should skip sending a ping to Safe Browsing because the
  // provided password was incorrect.
  virtual bool ShouldPromptForIncorrectPassword() const = 0;

  // Returns whether we should skip sending a ping to Safe Browsing because
  // extraction failed in a way that makes the data useless (e.g. disk write
  // failure).
  virtual bool ShouldShowScanFailure() const = 0;

  // Source URL being downloaded from. This should 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_;

  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::unique_ptr<ClientDownloadRequest> client_download_request_;
  std::string client_download_request_data_;

  const raw_ptr<DownloadProtectionService> service_;
  const scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
  const bool pingback_enabled_;
  base::TimeTicks start_time_ = base::TimeTicks::Now();  // Used for stats.
  base::TimeTicks timeout_start_time_;
  base::TimeTicks request_start_time_;
  bool skipped_url_allowlist_ = false;
  bool skipped_certificate_allowlist_ = false;
  bool sampled_unsupported_file_ = false;

  bool is_extended_reporting_ = false;
  bool is_incognito_ = false;
  bool is_enhanced_protection_ = false;

#if !BUILDFLAG(IS_ANDROID)
  // 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_;
#endif

  // Used to create the download request proto.
  std::unique_ptr<DownloadRequestMaker> download_request_maker_;
  // Records details about the DownloadRequestMaker run.
  DownloadRequestMaker::RequestCreationDetails request_creation_details_;
};  // namespace safe_browsing

}  // namespace safe_browsing

#endif  // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_CHECK_CLIENT_DOWNLOAD_REQUEST_BASE_H_