blob: 32bada0e928f639e75661382b0f60b941b75642a [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/memory/raw_ptr.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_extension_prefs.h"
#include "extensions/browser/blocklist_state.h"
#include "extensions/test/extension_state_tester.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:
BlocklistStatesInteractionUnitTest() {
// Set this flag to true so the acknowledged bit is not automatically set
// by the extension error controller on the first run.
ExtensionPrefs::SetRunAlertsInFirstRunForTest();
}
void SetUp() override {
ExtensionServiceTestBase::SetUp();
InitializeGoodInstalledExtensionService();
test_blocklist_.Attach(service()->blocklist_);
service()->Init();
extension_prefs_ = ExtensionPrefs::Get(profile());
}
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);
}
ExtensionPrefs* extension_prefs() { return extension_prefs_; }
private:
TestBlocklist test_blocklist_;
raw_ptr<ExtensionPrefs> extension_prefs_;
};
// 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) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// kTestExtensionId should be kept in `blocklisted_extensions` because it is
// still in the Omaha attribute blocklist.
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// kTestExtensionId should be removed from the `blocklisted_extensions` and is
// re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
}
// 1. The extension is added to the Safe Browsing blocklist with
// BLOCKLISTED_MALWARE state.
// 2. The user has acknowledged the blocklist state.
// 3. The extension is added to the Omaha attribute blocklist with _malware
// attribute.
// 4. The extension is removed from the Safe Browsing blocklist.
// 5. The extension is removed from the Omaha attribute blocklist.
TEST_F(BlocklistStatesInteractionUnitTest,
SafeBrowsingMalwareAcknowledgedThenOmahaAttributeMalware) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
EXPECT_FALSE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE,
extension_prefs()));
blocklist_prefs::AddAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE,
extension_prefs());
EXPECT_TRUE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE,
extension_prefs()));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
// The acknowledged state should not be cleared because the user has already
// acknowledged.
EXPECT_TRUE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE,
extension_prefs()));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// kTestExtensionId should be kept in `blocklisted_extensions` because it is
// still in the Omaha attribute blocklist.
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
// The acknowledged state should not be cleared because it is still in the
// Omaha attribute blocklist.
EXPECT_TRUE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE,
extension_prefs()));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// kTestExtensionId should be removed from the `blocklisted_extensions` and is
// re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
// The acknowledged state should be cleared because it is removed from the
// blocklist.
EXPECT_FALSE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE,
extension_prefs()));
}
// 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) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// This extension is still blocklisted because the extension is still in the
// Safe Browsing blocklist.
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// kTestExtensionId should be removed from `blocklisted_extensions` and is
// re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(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) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_POTENTIALLY_UNWANTED);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
EXPECT_EQ(BitMapBlocklistState::BLOCKLISTED_MALWARE,
blocklist_prefs::GetExtensionBlocklistState(kTestExtensionId,
extension_prefs()));
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
EXPECT_TRUE(extension_prefs()->HasDisableReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
// The extension should be kept disabled because it's still in the Safe
// Browsing greylist.
EXPECT_EQ(BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED,
blocklist_prefs::GetExtensionBlocklistState(kTestExtensionId,
extension_prefs()));
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
}
// 1. The extension is added to the Safe Browsing blocklist with
// BLOCKLISTED_MALWARE state.
// 2. The extension is added to the Omaha attribute greylist with
// _policy_violation attribute.
// 3. The extension is removed from the Safe Browsing blocklist.
// 4. The extension is removed from the Omaha attribute greylist.
TEST_F(BlocklistStatesInteractionUnitTest,
SafeBrowsingMalwareThenOmahaAttributePolicyViolation) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_MALWARE);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
EXPECT_EQ(BitMapBlocklistState::BLOCKLISTED_MALWARE,
blocklist_prefs::GetSafeBrowsingExtensionBlocklistState(
kTestExtensionId, extension_prefs()));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
true);
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
extension_prefs()));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
// The extension should be kept disabled because it's still in the Omaha
// attribute greylist.
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
EXPECT_EQ(BitMapBlocklistState::NOT_BLOCKLISTED,
blocklist_prefs::GetSafeBrowsingExtensionBlocklistState(
kTestExtensionId, extension_prefs()));
EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
extension_prefs()));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
false);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
}
// 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) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_CWS_POLICY_VIOLATION);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
true);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
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_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
false);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
}
// 1. The extension is added to the Omaha attribute greylist with
// BLOCKLISTED_CWS_POLICY_VIOLATION state.
// 2. The extension is added to the Safe Browsing greylist with
// _policy_violation attribute.
// 3. The extension is removed from the Omaha attribute greylist.
// 4. The extension is removed from the Safe Browsing greylist.
TEST_F(BlocklistStatesInteractionUnitTest,
OmahaAttributePolicyViolationThenSafeBrowsingPolicyViolation) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
true);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_CWS_POLICY_VIOLATION);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
false);
// The extension should be kept disabled because it's still in the Safe
// Browsing greylist.
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
}
// 1. The extension is added to the Safe Browsing greylist with
// BLOCKLISTED_CWS_POLICY_VIOLATION state.
// 2. User re-enabled the extension.
// 3. The extension is added to the Omaha attribute greylist with
// _policy_violation attribute.
// 4. The extension is removed from the Safe Browsing greylist.
// 5. The extension is removed from the Omaha attribute greylist.
TEST_F(
BlocklistStatesInteractionUnitTest,
SafeBrowsingPolicyViolationThenOmahaAttributePolicyViolationWithUserAction) {
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
BLOCKLISTED_CWS_POLICY_VIOLATION);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
EXPECT_TRUE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
extension_prefs()));
// The extension is manually re-enabled.
service()->EnableExtension(kTestExtensionId);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
true);
// The extension is not disabled again, because it was previously manually
// re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId, NOT_BLOCKLISTED);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
// The acknowledged state should not be cleared yet, because it is still in
// the Omaha attribute greylist.
EXPECT_TRUE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
extension_prefs()));
SetOmahaBlocklistStateForExtension(kTestExtensionId, "_policy_violation",
false);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
// The acknowledged state should be removed now.
EXPECT_FALSE(blocklist_prefs::HasAcknowledgedBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
extension_prefs()));
}
} // namespace extensions
#endif