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
|
// Copyright 2015 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/safe_browsing/unverified_download_field_trial.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/safe_browsing/download_protection_util.h"
#include "components/variations/variations_associated_data.h"
namespace safe_browsing {
const char kUnverifiedDownloadFieldTrialName[] =
"SafeBrowsingUnverifiedDownloads";
const char kUnverifiedDownloadFieldTrialDisableByParameter[] =
"DisableByParameter";
const char kUnverifiedDownloadFieldTrialWhitelistParam[] = "whitelist";
const char kUnverifiedDownloadFieldTrialBlacklistParam[] = "blacklist";
const char kUnverifiedDownloadFieldTrialBlockSBTypesParam[] = "block_sb_types";
namespace {
bool MatchesExtensionList(const base::FilePath& needle,
const std::string& haystack) {
#if defined(OS_WIN)
const base::FilePath::StringType comma_separated_extensions =
base::UTF8ToUTF16(haystack);
#else
const base::FilePath::StringType& comma_separated_extensions = haystack;
#endif
std::vector<base::FilePath::StringPieceType> extension_list =
base::SplitStringPiece(comma_separated_extensions, FILE_PATH_LITERAL(","),
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
// A single '*' matches everything.
if (extension_list.size() == 1 && extension_list[0] == FILE_PATH_LITERAL("*"))
return true;
for (const auto& extension : extension_list) {
// This shouldn't happen, but check anyway in case the parameter is
// accidentally malformed. The underlying FilePath implementation expects
// the extension to begin with an extension separator.
if (extension.size() == 0 ||
extension[0] != base::FilePath::kExtensionSeparator)
continue;
if (needle.MatchesExtension(extension))
return true;
}
return false;
}
} // namespace
bool IsUnverifiedDownloadAllowedByFieldTrial(const base::FilePath& file) {
std::string group_name =
base::FieldTrialList::FindFullName(kUnverifiedDownloadFieldTrialName);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAllowUncheckedDangerousDownloads))
return true;
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisallowUncheckedDangerousDownloads) &&
download_protection_util::IsSupportedBinaryFile(file))
return false;
if (base::StartsWith(group_name,
kUnverifiedDownloadFieldTrialDisableByParameter,
base::CompareCase::SENSITIVE)) {
std::map<std::string, std::string> parameters;
variations::GetVariationParams(kUnverifiedDownloadFieldTrialName,
¶meters);
if (parameters.count(kUnverifiedDownloadFieldTrialBlacklistParam) &&
MatchesExtensionList(
file, parameters[kUnverifiedDownloadFieldTrialBlacklistParam]))
return false;
if (parameters.count(kUnverifiedDownloadFieldTrialWhitelistParam) &&
MatchesExtensionList(
file, parameters[kUnverifiedDownloadFieldTrialWhitelistParam]))
return true;
if (parameters.count(kUnverifiedDownloadFieldTrialBlockSBTypesParam) &&
!parameters[kUnverifiedDownloadFieldTrialBlockSBTypesParam].empty() &&
download_protection_util::IsSupportedBinaryFile(file))
return false;
}
return true;
}
} // namespace safe_browsing
|