blob: bbf454549c6bd455842b927a117b7655bd2008c8 [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/omaha_attributes_handler.h"
#include "base/metrics/histogram_functions.h"
#include "base/values.h"
#include "chrome/browser/extensions/blocklist_extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/blocklist_state.h"
#include "extensions/common/extension_features.h"
namespace extensions {
// static
void OmahaAttributesHandler::ReportExtensionDisabledRemotely(
bool should_be_remotely_disabled,
ExtensionUpdateCheckDataKey reason) {
// Report that the extension is newly disabled due to Omaha attributes.
if (should_be_remotely_disabled)
base::UmaHistogramEnumeration("Extensions.ExtensionDisabledRemotely2",
reason);
// Report that the extension has added a new disable reason.
base::UmaHistogramEnumeration(
"Extensions.ExtensionAddDisabledRemotelyReason2", reason);
}
// static
void OmahaAttributesHandler::ReportNoUpdateCheckKeys() {
base::UmaHistogramEnumeration("Extensions.ExtensionDisabledRemotely2",
ExtensionUpdateCheckDataKey::kNoKey);
}
// static
void OmahaAttributesHandler::ReportReenableExtension(
ExtensionUpdateCheckDataKey reason) {
const char* histogram = nullptr;
switch (reason) {
case ExtensionUpdateCheckDataKey::kMalware:
histogram = "Extensions.ExtensionReenabledRemotely";
break;
case ExtensionUpdateCheckDataKey::kPotentiallyUWS:
histogram = "Extensions.ExtensionReenabledRemotelyForPotentiallyUWS";
break;
case ExtensionUpdateCheckDataKey::kPolicyViolation:
histogram = "Extensions.ExtensionReenabledRemotelyForPolicyViolation";
break;
case ExtensionUpdateCheckDataKey::kNoKey:
NOTREACHED();
}
base::UmaHistogramCounts100(histogram, 1);
}
// static
bool OmahaAttributesHandler::HasOmahaBlocklistStateInAttributes(
const base::Value& attributes,
BitMapBlocklistState state) {
const base::Value* state_value = nullptr;
switch (state) {
case BitMapBlocklistState::BLOCKLISTED_MALWARE:
state_value = attributes.FindKey("_malware");
break;
case BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION:
state_value = attributes.FindKey("_policy_violation");
break;
case BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED:
state_value = attributes.FindKey("_potentially_uws");
break;
case BitMapBlocklistState::NOT_BLOCKLISTED:
case BitMapBlocklistState::BLOCKLISTED_SECURITY_VULNERABILITY:
NOTREACHED()
<< "The other states are not applicable in Omaha attributes.";
state_value = nullptr;
break;
}
return state_value && state_value->GetBool();
}
OmahaAttributesHandler::OmahaAttributesHandler(
ExtensionPrefs* extension_prefs,
ExtensionService* extension_service)
: extension_prefs_(extension_prefs),
extension_service_(extension_service) {}
void OmahaAttributesHandler::PerformActionBasedOnOmahaAttributes(
const ExtensionId& extension_id,
const base::Value& attributes) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
HandleGreylistOmahaAttribute(
extension_id, attributes,
extensions_features::kDisablePolicyViolationExtensionsRemotely,
BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION,
ExtensionUpdateCheckDataKey::kPolicyViolation);
HandleGreylistOmahaAttribute(
extension_id, attributes,
extensions_features::kDisablePotentiallyUwsExtensionsRemotely,
BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED,
ExtensionUpdateCheckDataKey::kPotentiallyUWS);
}
void OmahaAttributesHandler::HandleGreylistOmahaAttribute(
const ExtensionId& extension_id,
const base::Value& attributes,
const base::Feature& feature_flag,
BitMapBlocklistState greylist_state,
ExtensionUpdateCheckDataKey reason) {
bool has_attribute_value =
HasOmahaBlocklistStateInAttributes(attributes, greylist_state);
bool has_omaha_blocklist_state = blocklist_prefs::HasOmahaBlocklistState(
extension_id, greylist_state, extension_prefs_);
if (!base::FeatureList::IsEnabled(feature_flag) || !has_attribute_value) {
if (has_omaha_blocklist_state) {
blocklist_prefs::RemoveOmahaBlocklistState(extension_id, greylist_state,
extension_prefs_);
ReportReenableExtension(reason);
}
extension_service_->ClearGreylistedAcknowledgedStateAndMaybeReenable(
extension_id);
return;
}
ReportExtensionDisabledRemotely(
/*should_be_remotely_disabled=*/!has_omaha_blocklist_state, reason);
blocklist_prefs::AddOmahaBlocklistState(extension_id, greylist_state,
extension_prefs_);
extension_service_->MaybeDisableGreylistedExtension(extension_id,
greylist_state);
}
} // namespace extensions