blob: 16db0e1279db3330c60484acd8f5cd86113f8925 [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 "chrome/browser/extensions/omaha_attributes_handler.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "extensions/browser/blocklist_extension_prefs.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/test/extension_state_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
namespace {
// Extension ids used during testing.
constexpr char kTestExtensionId[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
} // namespace
// Test suite to test Omaha attribute handler.
using OmahaAttributesHandlerUnitTest = ExtensionServiceTestBase;
TEST_F(OmahaAttributesHandlerUnitTest, LogPolicyViolationUWSMetrics) {
base::HistogramTester histograms;
InitializeGoodInstalledExtensionService();
service()->Init();
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_policy_violation", true);
attributes.SetBoolKey("_potentially_uws", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
histograms.ExpectBucketCount(
"Extensions.ExtensionDisabledRemotely2",
/*sample=*/ExtensionUpdateCheckDataKey::kPotentiallyUWS,
/*expected_count=*/1);
histograms.ExpectBucketCount(
"Extensions.ExtensionAddDisabledRemotelyReason2",
/*sample=*/ExtensionUpdateCheckDataKey::kPotentiallyUWS,
/*expected_count=*/1);
histograms.ExpectBucketCount(
"Extensions.ExtensionDisabledRemotely2",
/*sample=*/ExtensionUpdateCheckDataKey::kPolicyViolation,
/*expected_count=*/1);
histograms.ExpectBucketCount(
"Extensions.ExtensionAddDisabledRemotelyReason2",
/*sample=*/ExtensionUpdateCheckDataKey::kPolicyViolation,
/*expected_count=*/1);
}
TEST_F(OmahaAttributesHandlerUnitTest, LogMalwareMetrics) {
base::HistogramTester histograms;
InitializeGoodInstalledExtensionService();
service()->Init();
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_malware", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The re-enabled metric should not be logged if the extension is not disabled
// previously.
histograms.ExpectBucketCount("Extensions.ExtensionReenabledRemotely",
/*sample=*/ExtensionUpdateCheckDataKey::kMalware,
/*expected_count=*/0);
histograms.ExpectBucketCount("Extensions.ExtensionDisabledRemotely2",
/*sample=*/ExtensionUpdateCheckDataKey::kNoKey,
/*expected_count=*/1);
attributes.SetBoolKey("_malware", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
histograms.ExpectBucketCount("Extensions.ExtensionDisabledRemotely2",
/*sample=*/ExtensionUpdateCheckDataKey::kMalware,
/*expected_count=*/1);
histograms.ExpectBucketCount("Extensions.ExtensionAddDisabledRemotelyReason2",
/*sample=*/ExtensionUpdateCheckDataKey::kMalware,
/*expected_count=*/1);
attributes.SetBoolKey("_malware", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
histograms.ExpectBucketCount("Extensions.ExtensionReenabledRemotely",
/*sample=*/ExtensionUpdateCheckDataKey::kMalware,
/*expected_count=*/1);
histograms.ExpectBucketCount("Extensions.ExtensionDisabledRemotely2",
/*sample=*/ExtensionUpdateCheckDataKey::kNoKey,
/*expected_count=*/2);
}
TEST_F(OmahaAttributesHandlerUnitTest, DisableRemotelyForPolicyViolation) {
base::HistogramTester histograms;
InitializeGoodInstalledExtensionService();
service()->Init();
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_policy_violation", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
prefs));
// Remove extensions from greylist.
attributes.SetBoolKey("_policy_violation", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The extension is re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
EXPECT_FALSE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
prefs));
histograms.ExpectBucketCount(
"Extensions.ExtensionReenabledRemotelyForPolicyViolation",
/*sample=*/1,
/*expected_count=*/1);
histograms.ExpectBucketCount(
"Extensions.ExtensionReenabledRemotelyForPotentiallyUWS",
/*sample=*/1,
/*expected_count=*/0);
}
TEST_F(OmahaAttributesHandlerUnitTest, DisableRemotelyForPotentiallyUws) {
base::HistogramTester histograms;
InitializeGoodInstalledExtensionService();
service()->Init();
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_potentially_uws", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED,
prefs));
// Remove extensions from greylist.
attributes.SetBoolKey("_potentially_uws", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The extension is re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
EXPECT_FALSE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED,
prefs));
histograms.ExpectBucketCount(
"Extensions.ExtensionReenabledRemotelyForPotentiallyUWS",
/*sample=*/1,
/*expected_count=*/1);
histograms.ExpectBucketCount(
"Extensions.ExtensionReenabledRemotelyForPolicyViolation",
/*sample=*/1,
/*expected_count=*/0);
}
TEST_F(OmahaAttributesHandlerUnitTest, MultipleGreylistStates) {
InitializeGoodInstalledExtensionService();
service()->Init();
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_policy_violation", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
// Now user enables kTestExtensionId.
service()->EnableExtension(kTestExtensionId);
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
// Another greylist state is added to Omaha attribute.
attributes.SetBoolKey("_potentially_uws", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The extension should be disabled again.
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
// Remove extensions from the first greylist state.
attributes.SetBoolKey("_policy_violation", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The extension should still be disabled, because it is still in the
// potentially unwanted state.
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
EXPECT_FALSE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
prefs));
EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED,
prefs));
// Remove the other greylist state.
attributes.SetBoolKey("_potentially_uws", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The extension is re-enabled.
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
EXPECT_FALSE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED,
prefs));
}
TEST_F(OmahaAttributesHandlerUnitTest, KeepDisabledWhenMalwareRemoved) {
InitializeGoodInstalledExtensionService();
service()->Init();
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_malware", true);
attributes.SetBoolKey("_policy_violation", true);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
EXPECT_TRUE(state_tester.ExpectBlocklisted(kTestExtensionId));
EXPECT_TRUE(blocklist_prefs::HasOmahaBlocklistState(
kTestExtensionId, BitMapBlocklistState::BLOCKLISTED_MALWARE, prefs));
EXPECT_EQ(disable_reason::DISABLE_GREYLIST,
prefs->GetDisableReasons(kTestExtensionId));
// Remove malware.
attributes.SetBoolKey("_malware", false);
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
// The extension is not enabled because the policy violation bit is not
// cleared, but it is no longer blocklisted (instead just disabled).
EXPECT_TRUE(state_tester.ExpectDisabledWithSingleReason(
kTestExtensionId, disable_reason::DISABLE_GREYLIST));
}
TEST_F(OmahaAttributesHandlerUnitTest, ExtensionUninstalledBeforeNotified) {
InitializeGoodInstalledExtensionService();
service()->Init();
ExtensionStateTester state_tester(profile());
EXPECT_TRUE(state_tester.ExpectEnabled(kTestExtensionId));
service()->UninstallExtension(kTestExtensionId, UNINSTALL_REASON_FOR_TESTING,
nullptr);
base::Value attributes(base::Value::Type::DICTIONARY);
attributes.SetBoolKey("_malware", true);
// kTestExtensionId is already uninstalled. Performing action on it should
// not crash. Regression test for https://crbug.com/1305490.
service()->PerformActionBasedOnOmahaAttributes(kTestExtensionId, attributes);
}
} // namespace extensions