1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/download/download_danger_prompt.h"
6
7 #include "base/macros.h"
8 #include "base/metrics/histogram_functions.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h"
12 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
13 #include "components/download/public/common/download_danger_type.h"
14 #include "components/download/public/common/download_item.h"
15 #include "components/safe_browsing/core/file_type_policies.h"
16 #include "content/public/browser/download_item_utils.h"
17
18 using safe_browsing::ClientDownloadResponse;
19 using safe_browsing::ClientSafeBrowsingReportRequest;
20
21 namespace {
22
23 const char kDownloadDangerPromptPrefix[] = "Download.DownloadDangerPrompt";
24
25 // Converts DownloadDangerType into their corresponding string.
GetDangerTypeString(const download::DownloadDangerType & danger_type)26 const char* GetDangerTypeString(
27 const download::DownloadDangerType& danger_type) {
28 switch (danger_type) {
29 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
30 return "DangerousFile";
31 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
32 return "DangerousURL";
33 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
34 return "DangerousContent";
35 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
36 return "DangerousHost";
37 case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
38 return "UncommonContent";
39 case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED:
40 return "PotentiallyUnwanted";
41 case download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING:
42 return "AsyncScanning";
43 case download::DOWNLOAD_DANGER_TYPE_BLOCKED_PASSWORD_PROTECTED:
44 return "BlockedPasswordProtected";
45 case download::DOWNLOAD_DANGER_TYPE_BLOCKED_TOO_LARGE:
46 return "BlockedTooLarge";
47 case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING:
48 return "SensitiveContentWarning";
49 case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK:
50 return "SensitiveContentBlock";
51 case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE:
52 return "DeepScannedSafe";
53 case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS:
54 return "DeepScannedOpenedDangerous";
55 case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING:
56 return "PromptForScanning";
57 case download::DOWNLOAD_DANGER_TYPE_BLOCKED_UNSUPPORTED_FILETYPE:
58 return "BlockedUnsupportedFiletype";
59 case download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
60 case download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
61 case download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
62 case download::DOWNLOAD_DANGER_TYPE_WHITELISTED_BY_POLICY:
63 case download::DOWNLOAD_DANGER_TYPE_MAX:
64 break;
65 }
66 NOTREACHED();
67 return nullptr;
68 }
69
70 } // namespace
71
SendSafeBrowsingDownloadReport(ClientSafeBrowsingReportRequest::ReportType report_type,bool did_proceed,const download::DownloadItem & download)72 void DownloadDangerPrompt::SendSafeBrowsingDownloadReport(
73 ClientSafeBrowsingReportRequest::ReportType report_type,
74 bool did_proceed,
75 const download::DownloadItem& download) {
76 safe_browsing::SafeBrowsingService* sb_service =
77 g_browser_process->safe_browsing_service();
78 Profile* profile = Profile::FromBrowserContext(
79 content::DownloadItemUtils::GetBrowserContext(&download));
80 ClientSafeBrowsingReportRequest report;
81 report.set_type(report_type);
82 switch (download.GetDangerType()) {
83 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
84 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
85 report.set_download_verdict(ClientDownloadResponse::DANGEROUS);
86 break;
87 case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT:
88 report.set_download_verdict(ClientDownloadResponse::UNCOMMON);
89 break;
90 case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED:
91 report.set_download_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED);
92 break;
93 case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
94 report.set_download_verdict(ClientDownloadResponse::DANGEROUS_HOST);
95 break;
96 default: // Don't send report for any other danger types.
97 return;
98 }
99 report.set_url(download.GetURL().spec());
100 report.set_did_proceed(did_proceed);
101 std::string token =
102 safe_browsing::DownloadProtectionService::GetDownloadPingToken(
103 &download);
104 if (!token.empty())
105 report.set_token(token);
106 std::string serialized_report;
107 if (report.SerializeToString(&serialized_report))
108 sb_service->SendSerializedDownloadReport(profile, serialized_report);
109 else
110 DLOG(ERROR) << "Unable to serialize the threat report.";
111 }
112
RecordDownloadDangerPrompt(bool did_proceed,const download::DownloadItem & download)113 void DownloadDangerPrompt::RecordDownloadDangerPrompt(
114 bool did_proceed,
115 const download::DownloadItem& download) {
116 int64_t file_type_uma_value =
117 safe_browsing::FileTypePolicies::GetInstance()->UmaValueForFile(
118 download.GetTargetFilePath());
119 download::DownloadDangerType danger_type = download.GetDangerType();
120
121 base::UmaHistogramSparse(
122 base::StringPrintf("%s.%s.Shown", kDownloadDangerPromptPrefix,
123 GetDangerTypeString(danger_type)),
124 file_type_uma_value);
125 if (did_proceed) {
126 base::UmaHistogramSparse(
127 base::StringPrintf("%s.%s.Proceed", kDownloadDangerPromptPrefix,
128 GetDangerTypeString(danger_type)),
129 file_type_uma_value);
130 }
131 }
132