blob: b9a32e6d1150665338bb72f2938862f8cce982ca [file] [log] [blame]
// Copyright 2021 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/extensions/blocklist_extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/test_blocklist.h"
#include "components/safe_browsing/buildflags.h"
#include "extensions/browser/blocklist_state.h"
#include "testing/gtest/include/gtest/gtest.h"
// The interaction tests rely on the safe-browsing database.
#if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
namespace extensions {
namespace {
// Extension ids used during testing.
constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
} // namespace
// Test suite to test the interaction between Safe Browsing blocklist, Omaha
// attributes blocklist and user action. These tests verify that the extension
// is in the correct extension set under different circumstances.
class BlocklistStatesInteractionUnitTest : public ExtensionServiceTestBase {
public:
void SetUp() override {
InitializeGoodInstalledExtensionService();
test_blocklist_.Attach(service()->blocklist_);
service()->Init();
}
protected:
void SetSafeBrowsingBlocklistStateForExtension(
const std::string& extension_id,
BlocklistState state) {
// Reset cache in blocklist to make sure the latest blocklist state is
// fetched.
service()->blocklist_->ResetBlocklistStateCacheForTest();
test_blocklist_.SetBlocklistState(extension_id, state, true);
task_environment()->RunUntilIdle();
}
void SetOmahaBlocklistStateForExtension(const std::string& extension_id,
const std::string& omaha_attribute,
bool value) {
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey(omaha_attribute, value);
service()->PerformActionBasedOnOmahaAttributes(extension_id, attributes);
}
private:
TestBlocklist test_blocklist_;
};
// 1. The extension is added to the Safe Browsing blocklist with
// BLOCKLISTED_MALWARE state.
// 2. The extension is added to the Omaha attribute blocklist with _malware
// attribute.
// 3. The extension is removed from the Safe Browsing blocklist.
// 4. The extension is removed from the Omaha attribute blocklist.
TEST_F(BlocklistStatesInteractionUnitTest,
SafeBrowsingMalwareThenOmahaAttributeMalware) {
const ExtensionSet& blocklisted_extensions =
registry()->blocklisted_extensions();
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// kTestExtensionId should be kept in `blocklisted_extensions` because it is
// still in the Omaha attribute blocklist.
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// kTestExtensionId should be removed from the `blocklisted_extensions`.
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
}
// 1. The extension is added to the Omaha attribute blocklist with _malware
// attribute.
// 2. The extension is added to the Safe Browsing blocklist with
// BLOCKLISTED_MALWARE state.
// 3. The extension is removed from the Omaha attribute blocklist.
// 4. The extension is removed from the Safe Browsing blocklist.
TEST_F(BlocklistStatesInteractionUnitTest,
OmahaAttributeMalwareThenSafeBrowsingMalware) {
const ExtensionSet& blocklisted_extensions =
registry()->blocklisted_extensions();
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// TODO(crbug.com/1193695): Ideally this should be true because the extension
// is still in the Safe Browsing blocklist.
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
// The extension is added back to the blocklist after the Safe Browsing
// blocklist is refreshed.
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
// The extension should be kept in the `blocklisted_extensions` even if the
// Omaha attribute is still false.
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// kTestExtensionId should be removed from `blocklisted_extensions`.
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
}
// 1. The extension is added to the Safe Browsing greylist with
// BLOCKLISTED_POTENTIALLY_UNWANTED state.
// 2. The extension is added to the Omaha attribute blocklist with _malware
// attribute.
// 3. The extension is removed from the Omaha attribute blocklist.
// 4. The extension is removed from the Safe Browsing greylist.
TEST_F(BlocklistStatesInteractionUnitTest,
SafeBrowsingUwSThenOmahaAttributeMalware) {
const ExtensionSet& blocklisted_extensions =
registry()->blocklisted_extensions();
const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(enabled_extensions.Contains(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_POTENTIALLY_UNWANTED);
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_EQ(BLOCKLISTED_MALWARE,
ExtensionPrefs::Get(profile())->GetExtensionBlocklistState(
kTestExtensionId));
EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// TODO(crbug.com/1193695): Ideally this should be set to the original Safe
// Browsing greylist state BLOCKLISTED_POTENTIALLY_UNWANTED. However, this is
// not possible with the current implementation, because the Omaha blocklist
// state (malware) overrides the Safe Browsing blocklist state, and there is
// no way to preserve the original Safe Browsing greylist state (potentially
// unwanted). This should happen pretty rare - only when the extension is
// removed from the Omaha attribute blocklist but stays in the Safe Browsing
// greylist. It will be fixed after we decouple Safe Browsing blocklist state
// and Omaha attribute blocklist state.
EXPECT_EQ(NOT_BLOCKLISTED,
ExtensionPrefs::Get(profile())->GetExtensionBlocklistState(
kTestExtensionId));
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
// TODO(crbug.com/1193695): The extension is still disabled with
// DISABLE_GREYLIST reason even though the blocklist state is cleared. This
// should be fixed when we start to consume Omaha attribute greylist.
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
// The Safe Browsing greylist state should be set correctly after the Safe
// Browsing blocklist is refreshed.
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_POTENTIALLY_UNWANTED);
EXPECT_EQ(BLOCKLISTED_POTENTIALLY_UNWANTED,
ExtensionPrefs::Get(profile())->GetExtensionBlocklistState(
kTestExtensionId));
EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
// The extension should be kept disabled because it's still in the Safe
// Browsing greylist.
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
EXPECT_TRUE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_FALSE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
}
// 1. The extension is added to the Safe Browsing greylist with
// BLOCKLISTED_CWS_POLICY_VIOLATION state.
// 2. The extension is added to the Omaha attribute greylist with
// _policy_violation attribute.
// 3. The extension is removed from the Safe Browsing greylist.
// 4. The extension is removed from the Omaha attribute greylist.
TEST_F(BlocklistStatesInteractionUnitTest,
SafeBrowsingPolicyViolationThenOmahaAttributePolicyViolation) {
const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
EXPECT_TRUE(enabled_extensions.Contains(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_CWS_POLICY_VIOLATION);
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
// TODO(crbug.com/1180996): Call SetOmahaBlocklistStateForExtension directly
// once we start to consume the _policy_violation attribute.
blocklist_prefs::AddOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
ExtensionPrefs::Get(profile()));
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// The extension should be kept disabled because it's still in the Omaha
// attribute greylist.
EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
// TODO(crbug.com/1180996): Call SetOmahaBlocklistStateForExtension directly
// once we start to consume the _policy_violation attribute.
blocklist_prefs::RemoveOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
ExtensionPrefs::Get(profile()));
service()->ClearGreylistedAcknowledgedStateAndMaybeReenable(kTestExtensionId);
EXPECT_TRUE(enabled_extensions.Contains(kTestExtensionId));
EXPECT_FALSE(ExtensionPrefs::Get(profile())->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
}
#endif
} // namespace extensions