|  | // Copyright (c) 2012 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. | 
|  |  | 
|  | #include "chrome/browser/download/download_danger_prompt.h" | 
|  |  | 
|  | #include "base/macros.h" | 
|  | #include "base/metrics/histogram_functions.h" | 
|  | #include "base/strings/stringprintf.h" | 
|  | #include "chrome/browser/browser_process.h" | 
|  | #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" | 
|  | #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" | 
|  | #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 
|  | #include "components/download/public/common/download_danger_type.h" | 
|  | #include "components/download/public/common/download_item.h" | 
|  | #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" | 
|  | #include "components/safe_browsing/content/common/file_type_policies.h" | 
|  | #include "components/safe_browsing/core/common/proto/csd.pb.h" | 
|  | #include "content/public/browser/browser_task_traits.h" | 
|  | #include "content/public/browser/browser_thread.h" | 
|  | #include "content/public/browser/download_item_utils.h" | 
|  |  | 
|  | using safe_browsing::ClientDownloadResponse; | 
|  | using safe_browsing::ClientSafeBrowsingReportRequest; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | const char kDownloadDangerPromptPrefix[] = "Download.DownloadDangerPrompt"; | 
|  |  | 
|  | // Converts DownloadDangerType into their corresponding string. | 
|  | const char* GetDangerTypeString( | 
|  | const download::DownloadDangerType& danger_type) { | 
|  | switch (danger_type) { | 
|  | case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: | 
|  | return "DangerousFile"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: | 
|  | return "DangerousURL"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: | 
|  | return "DangerousContent"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: | 
|  | return "DangerousHost"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: | 
|  | return "UncommonContent"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: | 
|  | return "PotentiallyUnwanted"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING: | 
|  | return "AsyncScanning"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_BLOCKED_PASSWORD_PROTECTED: | 
|  | return "BlockedPasswordProtected"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_BLOCKED_TOO_LARGE: | 
|  | return "BlockedTooLarge"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING: | 
|  | return "SensitiveContentWarning"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK: | 
|  | return "SensitiveContentBlock"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE: | 
|  | return "DeepScannedSafe"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS: | 
|  | return "DeepScannedOpenedDangerous"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING: | 
|  | return "PromptForScanning"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_BLOCKED_UNSUPPORTED_FILETYPE: | 
|  | return "BlockedUnsupportedFiletype"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE: | 
|  | return "DangerousAccountCompromise"; | 
|  | case download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: | 
|  | case download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: | 
|  | case download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED: | 
|  | case download::DOWNLOAD_DANGER_TYPE_ALLOWLISTED_BY_POLICY: | 
|  | case download::DOWNLOAD_DANGER_TYPE_MAX: | 
|  | break; | 
|  | } | 
|  | NOTREACHED(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | void DownloadDangerPrompt::SendSafeBrowsingDownloadReport( | 
|  | ClientSafeBrowsingReportRequest::ReportType report_type, | 
|  | bool did_proceed, | 
|  | const download::DownloadItem& download) { | 
|  | safe_browsing::SafeBrowsingService* sb_service = | 
|  | g_browser_process->safe_browsing_service(); | 
|  | Profile* profile = Profile::FromBrowserContext( | 
|  | content::DownloadItemUtils::GetBrowserContext(&download)); | 
|  | auto report = std::make_unique<ClientSafeBrowsingReportRequest>(); | 
|  | report->set_type(report_type); | 
|  | ClientDownloadResponse::Verdict download_verdict = | 
|  | safe_browsing::DownloadDangerTypeToDownloadResponseVerdict( | 
|  | download.GetDangerType()); | 
|  | if (download_verdict == ClientDownloadResponse::SAFE) { | 
|  | // Don't send report if the verdict is SAFE. | 
|  | return; | 
|  | } | 
|  | report->set_download_verdict(download_verdict); | 
|  | report->set_url(download.GetURL().spec()); | 
|  | report->set_did_proceed(did_proceed); | 
|  | std::string token = | 
|  | safe_browsing::DownloadProtectionService::GetDownloadPingToken(&download); | 
|  | if (!token.empty()) | 
|  | report->set_token(token); | 
|  | std::string serialized_report; | 
|  | if (report->SerializeToString(&serialized_report)) { | 
|  | sb_service->SendSerializedDownloadReport(profile, serialized_report); | 
|  |  | 
|  | // The following is to log this ClientSafeBrowsingReportRequest on any open | 
|  | // chrome://safe-browsing pages. | 
|  | content::GetUIThreadTaskRunner({})->PostTask( | 
|  | FROM_HERE, | 
|  | base::BindOnce( | 
|  | &safe_browsing::WebUIInfoSingleton::AddToCSBRRsSent, | 
|  | base::Unretained(safe_browsing::WebUIInfoSingleton::GetInstance()), | 
|  | std::move(report))); | 
|  | } else { | 
|  | DLOG(ERROR) << "Unable to serialize the threat report."; | 
|  | } | 
|  | } | 
|  |  | 
|  | void DownloadDangerPrompt::RecordDownloadDangerPrompt( | 
|  | bool did_proceed, | 
|  | const download::DownloadItem& download) { | 
|  | int64_t file_type_uma_value = | 
|  | safe_browsing::FileTypePolicies::GetInstance()->UmaValueForFile( | 
|  | download.GetTargetFilePath()); | 
|  | download::DownloadDangerType danger_type = download.GetDangerType(); | 
|  |  | 
|  | base::UmaHistogramSparse( | 
|  | base::StringPrintf("%s.%s.Shown", kDownloadDangerPromptPrefix, | 
|  | GetDangerTypeString(danger_type)), | 
|  | file_type_uma_value); | 
|  | if (did_proceed) { | 
|  | base::UmaHistogramSparse( | 
|  | base::StringPrintf("%s.%s.Proceed", kDownloadDangerPromptPrefix, | 
|  | GetDangerTypeString(danger_type)), | 
|  | file_type_uma_value); | 
|  | } | 
|  | } |