File: download_protection_delegate_desktop.cc

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 (169 lines) | stat: -rw-r--r-- 7,211 bytes parent folder | download | duplicates (5)
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
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/safe_browsing/download_protection/download_protection_delegate_desktop.h"

#include "base/strings/escape.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/download_protection/check_client_download_request.h"
#include "chrome/browser/safe_browsing/download_protection/check_file_system_access_write_request.h"
#include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
#include "chrome/common/safe_browsing/download_type_util.h"
#include "components/download/public/common/download_item.h"
#include "components/safe_browsing/content/common/file_type_policies.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/file_system_access_write_item.h"
#include "google_apis/google_api_keys.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/resource_request.h"

namespace safe_browsing {
namespace {

const char kDownloadRequestUrl[] =
    "https://sb-ssl.google.com/safebrowsing/clientreport/download";

// Content-Type HTTP header field for the request.
const char kCheckClientDownloadRequestContentType[] =
    "application/octet-stream";

// We sample 1% of allowlisted downloads to still send out download pings.
const double kAllowlistDownloadSampleRate = 0.01;

// The API key should not change so we can construct this GURL once and cache
// it.
GURL ConstructDownloadRequestUrl() {
  GURL url(kDownloadRequestUrl);
  std::string api_key = google_apis::GetAPIKey();
  if (!api_key.empty()) {
    url = url.Resolve("?key=" +
                      base::EscapeQueryParamValue(api_key, /*use_plus=*/true));
  }
  return url;
}

bool IsSafeBrowsingEnabledForDownloadProfile(download::DownloadItem* item) {
  Profile* profile = Profile::FromBrowserContext(
      content::DownloadItemUtils::GetBrowserContext(item));
  return profile && IsSafeBrowsingEnabled(*profile->GetPrefs());
}

}  // namespace

DownloadProtectionDelegateDesktop::DownloadProtectionDelegateDesktop()
    : download_request_url_(ConstructDownloadRequestUrl()) {
  CHECK(download_request_url_.is_valid());
}

DownloadProtectionDelegateDesktop::~DownloadProtectionDelegateDesktop() =
    default;

bool DownloadProtectionDelegateDesktop::ShouldCheckDownloadUrl(
    download::DownloadItem* item) const {
  return IsSafeBrowsingEnabledForDownloadProfile(item);
}

bool DownloadProtectionDelegateDesktop::MayCheckClientDownload(
    download::DownloadItem* item) const {
  if (!IsSafeBrowsingEnabledForDownloadProfile(item)) {
    return false;
  }
  return IsSupportedDownload(*item, item->GetTargetFilePath()) !=
         MayCheckDownloadResult::kMayNotCheckDownload;
}

bool DownloadProtectionDelegateDesktop::MayCheckFileSystemAccessWrite(
    content::FileSystemAccessWriteItem* item) const {
  Profile* profile = Profile::FromBrowserContext(item->browser_context);
  if (!profile || !IsSafeBrowsingEnabled(*profile->GetPrefs())) {
    return false;
  }
  DownloadCheckResultReason ignored_reason = REASON_MAX;
  return CheckFileSystemAccessWriteRequest::IsSupportedDownload(
             item->target_file_path, &ignored_reason) !=
         MayCheckDownloadResult::kMayNotCheckDownload;
}

MayCheckDownloadResult DownloadProtectionDelegateDesktop::IsSupportedDownload(
    download::DownloadItem& item,
    const base::FilePath& target_path) const {
  // TODO(nparker): Remove the CRX check here once can support
  // UNKNOWN types properly.  http://crbug.com/581044
  if (download_type_util::GetDownloadType(target_path) ==
      ClientDownloadRequest::CHROME_EXTENSION) {
    return MayCheckDownloadResult::kMayNotCheckDownload;
  }
  DownloadCheckResultReason ignored_reason = REASON_MAX;
  return CheckClientDownloadRequest::IsSupportedDownload(item, target_path,
                                                         &ignored_reason);
}

void DownloadProtectionDelegateDesktop::FinalizeResourceRequest(
    network::ResourceRequest& resource_request) {
  resource_request.headers.SetHeader(net::HttpRequestHeaders::kContentType,
                                     kCheckClientDownloadRequestContentType);
}

const GURL& DownloadProtectionDelegateDesktop::GetDownloadRequestUrl() const {
  return download_request_url_;
}

net::NetworkTrafficAnnotationTag DownloadProtectionDelegateDesktop::
    CompleteClientDownloadRequestTrafficAnnotation(
        const net::PartialNetworkTrafficAnnotationTag&
            partial_traffic_annotation) const {
  return net::BranchedCompleteNetworkTrafficAnnotation(
      "client_download_request_desktop", "client_download_request_for_platform",
      partial_traffic_annotation, R"(
          semantics {
            description:
              "Chromium checks whether a given download is likely to be "
              "dangerous by sending this client download request to Google's "
              "Safe Browsing servers. Safe Browsing server will respond to "
              "this request by sending back a verdict, indicating if this "
              "download is safe or the danger type of this download (e.g. "
              "dangerous content, uncommon content, potentially harmful, etc)."
            trigger:
              "This request is triggered when a download is about to complete, "
              "the download is not allowlisted, and its file extension is "
              "supported by download protection service (e.g. executables, "
              "archives). Please refer to https://cs.chromium.org/chromium/src/"
              "chrome/browser/resources/safe_browsing/"
              "download_file_types.asciipb for the complete list of supported "
              "files."
            data:
              "URL of the file to be downloaded, its referrer chain, digest "
              "and other features extracted from the downloaded file. Refer to "
              "ClientDownloadRequest message in https://cs.chromium.org/"
              "chromium/src/components/safe_browsing/csd.proto for all "
              "submitted features."
            user_data {
              type: SENSITIVE_URL
              type: WEB_CONTENT
            }
            last_reviewed: "2025-02-25"
          })");
}

float DownloadProtectionDelegateDesktop::GetAllowlistedDownloadSampleRate()
    const {
  return kAllowlistDownloadSampleRate;
}

float DownloadProtectionDelegateDesktop::GetUnsupportedFileSampleRate(
    const base::FilePath& filename) const {
  // If this extension is specifically marked as SAMPLED_PING (as are
  // all "unknown" extensions), we may want to sample it. Sampling it means
  // we'll send a "light ping" with private info removed, and we won't
  // use the verdict.
  const FileTypePolicies* policies = FileTypePolicies::GetInstance();
  return policies->PingSettingForFile(filename) ==
                 DownloadFileType::SAMPLED_PING
             ? policies->SampledPingProbability()
             : 0.0;
}

}  // namespace safe_browsing