// 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 "chrome/common/chrome_switches.h" #include "chrome/common/safe_browsing/download_protection_util.h" #include "components/variations/variations_associated_data.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace safe_browsing { namespace { const base::FilePath::CharType kSafeFilename[] = FILE_PATH_LITERAL("foo.txt"); const base::FilePath::CharType kHandledFilename[] = FILE_PATH_LITERAL("foo.exe"); using FieldTrialParameters = std::map; class ScopedFieldTrialState { public: ScopedFieldTrialState(const std::string& group_name, const FieldTrialParameters& parameters) : field_trial_list_(nullptr) { variations::testing::ClearAllVariationIDs(); variations::testing::ClearAllVariationParams(); if (!parameters.empty()) { EXPECT_TRUE(variations::AssociateVariationParams( kUnverifiedDownloadFieldTrialName, group_name, parameters)); } EXPECT_TRUE(base::FieldTrialList::CreateFieldTrial( kUnverifiedDownloadFieldTrialName, group_name)); } explicit ScopedFieldTrialState(const std::string& group_name) : ScopedFieldTrialState(group_name, FieldTrialParameters()) {} ~ScopedFieldTrialState() { variations::testing::ClearAllVariationIDs(); variations::testing::ClearAllVariationParams(); } private: base::FieldTrialList field_trial_list_; }; } // namespace // Verify some test assumptions. Namely, that kSafeFilename is not a supported // binary file and that kHandledFilename is. TEST(UnverifiedDownloadFieldTrialTest, Assumptions) { EXPECT_TRUE(download_protection_util::IsSupportedBinaryFile( base::FilePath(kHandledFilename))); EXPECT_FALSE(download_protection_util::IsSupportedBinaryFile( base::FilePath(kSafeFilename))); } // Verify that disallow-unchecked-dangerous-downloads command line switch causes // all dangerous file types to be blocked, and that safe files types are still // allowed. TEST(UnverifiedDownloadFieldTrialTest, CommandLine_DisallowDangerous) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kDisallowUncheckedDangerousDownloads); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); } // Verify that a wildcard blacklist matches all file types. TEST(UnverifiedDownloadFieldTrialTest, WildCardBlacklist) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = "*"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".xyz"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.xyz")))); } // Verify that allow-unchecked-dangerous-downloads command line option takes // precedence over a Finch trial specified blacklist. TEST(UnverifiedDownloadFieldTrialTest, BlacklistVsCommandline) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = "*"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".xyz"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kAllowUncheckedDangerousDownloads); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); } // Verify that disallow-unchecked-dangerous-downloads command line option takes // precedence over a Finch trial specified whitelist. TEST(UnverifiedDownloadFieldTrialTest, WhitelistVsCommandline) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".foo"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".exe"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kDisallowUncheckedDangerousDownloads); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.foo")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.exe")))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.txt")))); } // Verify that wildcards only work if they are specified by themselves. TEST(UnverifiedDownloadFieldTrialTest, WildcardOnlyByItself) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".foo,*"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".xyz"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.foo")))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.xyz")))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.txt")))); } // Verify that the blacklist takes precedence over whitelist. TEST(UnverifiedDownloadFieldTrialTest, WhitelistVsBlacklist) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".abc,.def"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".xyz"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.xyz")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.abc")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.def")))); } // Verify that nothing terrible happens if no parameters are specified. TEST(UnverifiedDownloadFieldTrialTest, MissingParameters) { ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); } // Verify that nothing terrible happens if the parameters set for a field trial // are malformed. TEST(UnverifiedDownloadFieldTrialTest, MalformedParameters) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = "abcasdfa#??# ~def"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = "Robert'); DROP TABLE FinchTrials;--"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); } // Verify that nothing terrible happens if the parameters set for a field trial // are empty. TEST(UnverifiedDownloadFieldTrialTest, DisableByParam_Empty) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ""; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ""; parameters[kUnverifiedDownloadFieldTrialBlockSBTypesParam] = ""; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); } // Verified that file types specified via white/blacklists are case insensitive. TEST(UnverifiedDownloadFieldTrialTest, CaseInsensitive) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".ABC,.xyz"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.abc")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("FOO.ABC")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("FOO.XYZ")))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("FOO.txt")))); } // Verify functionality when all parameters are specified. TEST(UnverifiedDownloadFieldTrialTest, WhitelistVsBlacklistVsSBTypes) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".abc,.def"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".xyz"; parameters[kUnverifiedDownloadFieldTrialBlockSBTypesParam] = "*"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.xyz")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.abc")))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.def")))); } // Verify that block_sb_types parameter being empty is equivalent to it not // being specified. TEST(UnverifiedDownloadFieldTrialTest, DisableSBTypesEmpty) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlockSBTypesParam] = ""; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); } // Verify that a whitelist is able to override the SafeBrowsing file type list. TEST(UnverifiedDownloadFieldTrialTest, ListsOverrideSBTypes) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".abc,.def"; parameters[kUnverifiedDownloadFieldTrialWhitelistParam] = ".exe"; parameters[kUnverifiedDownloadFieldTrialBlockSBTypesParam] = "*"; ScopedFieldTrialState field_trial( kUnverifiedDownloadFieldTrialDisableByParameter, parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.abc")))); } // Verify that the field trial is only sensitive to the prefix of the group // name. TEST(UnverifiedDownloadFieldTrialTest, FieldTrialGroupPrefix) { FieldTrialParameters parameters; parameters[kUnverifiedDownloadFieldTrialBlacklistParam] = ".abc,.def"; parameters[kUnverifiedDownloadFieldTrialBlockSBTypesParam] = "*"; ScopedFieldTrialState field_trial( std::string(kUnverifiedDownloadFieldTrialDisableByParameter) + "FooBar", parameters); EXPECT_TRUE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kSafeFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(kHandledFilename))); EXPECT_FALSE(IsUnverifiedDownloadAllowedByFieldTrial( base::FilePath(FILE_PATH_LITERAL("foo.abc")))); } } // namespace safe_browsing