Commit bd501480 authored by Marc-André (MAD) Decoste's avatar Marc-André (MAD) Decoste Committed by Chromium LUCI CQ

Add support for enabling subset of security events

Bug: 1163668
Change-Id: If5d37113d20e44b719f0e0162ed079e25853b833
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2612932Reviewed-by: default avatarDaniel Rubery <drubery@chromium.org>
Reviewed-by: default avatarOwen Min <zmin@chromium.org>
Reviewed-by: default avatarDominique Fauteux-Chapleau <domfc@chromium.org>
Commit-Queue: Marc-André Decoste <mad@chromium.org>
Auto-Submit: Marc-André Decoste <mad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843191}
parent 5be1bd85
......@@ -28,6 +28,7 @@ constexpr char kKeyBlockPasswordProtected[] = "block_password_protected";
constexpr char kKeyBlockLargeFiles[] = "block_large_files";
constexpr char kKeyBlockUnsupportedFileTypes[] = "block_unsupported_file_types";
constexpr char kKeyMinimumDataSize[] = "minimum_data_size";
constexpr char kKeyEnabledEventNames[] = "enabled_event_names";
enum class ReportingConnector {
SECURITY_EVENT,
......@@ -74,6 +75,7 @@ struct ReportingSettings {
~ReportingSettings();
GURL reporting_url;
std::set<std::string> enabled_event_names;
std::string dm_token;
// Indicates if the report should be made for the profile, or the browser if
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/enterprise/connectors/reporting_service_settings.h"
#include "chrome/browser/enterprise/connectors/service_provider_config.h"
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
#include "components/policy/core/browser/url_util.h"
namespace enterprise_connectors {
......@@ -23,6 +24,29 @@ ReportingServiceSettings::ReportingServiceSettings(
service_provider_ =
service_provider_config.GetServiceProvider(*service_provider_name);
}
const base::Value* enabled_event_name_list_value =
settings_value.FindListKey(kKeyEnabledEventNames);
if (enabled_event_name_list_value) {
for (const base::Value& enabled_event_name_value :
enabled_event_name_list_value->GetList()) {
if (enabled_event_name_value.is_string())
enabled_event_names_.insert(enabled_event_name_value.GetString());
else
DVLOG(1) << "Enabled event name list contains a non string value!";
}
} else {
// When the list of enabled event names is not set, we assume all events are
// enabled. This is to support the feature of selecting the "All always on"
// option in the policy UI, which means to always enable all events, even
// when new events may be added in the future. And this is also to support
// existing customer policies that were created before we introduced the
// concept of enabling/disabling events.
for (auto* event_name :
extensions::SafeBrowsingPrivateEventRouter::kAllEvents) {
enabled_event_names_.insert(event_name);
}
}
}
base::Optional<ReportingSettings>
......@@ -35,12 +59,16 @@ ReportingServiceSettings::GetReportingSettings() const {
settings.reporting_url = GURL(service_provider_->reporting_url());
DCHECK(settings.reporting_url.is_valid());
settings.enabled_event_names.insert(enabled_event_names_.begin(),
enabled_event_names_.end());
return settings;
}
bool ReportingServiceSettings::IsValid() const {
// The settings are valid only if a provider was given.
return service_provider_;
// The settings are valid only if a provider was given, and events are
// enabled. The list could be empty. The absence of a list means "all events",
// but the presence of an empty list means "no events".
return service_provider_ && !enabled_event_names_.empty();
}
ReportingServiceSettings::ReportingServiceSettings(ReportingServiceSettings&&) =
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_REPORTING_SERVICE_SETTINGS_H_
#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_REPORTING_SERVICE_SETTINGS_H_
#include <set>
#include <string>
#include "base/optional.h"
......@@ -36,6 +37,9 @@ class ReportingServiceSettings {
// implies that a corresponding service provider doesn't exist and that these
// settings are not valid.
const ServiceProviderConfig::ServiceProvider* service_provider_ = nullptr;
// The events that are enabled for the current service provider.
std::set<std::string> enabled_event_names_;
};
} // namespace enterprise_connectors
......
......@@ -22,17 +22,28 @@ struct TestParam {
ReportingSettings* expected_settings;
};
constexpr char kNormalSettings[] = R"({ "service_provider": "google" })";
constexpr char kNoProviderSettings[] = "{}";
ReportingSettings* NormalSettings() {
constexpr char kNormalSettingsWithoutEvents[] =
R"({ "service_provider": "google" })";
constexpr char kNormalSettingsWithEvents[] =
R"({ "service_provider": "google",
"enabled_event_names" : ["event 1", "event 2", "event 3"]
})";
ReportingSettings* NoSettings() {
return nullptr;
}
ReportingSettings* NormalSettingsWithoutEvents() {
static base::NoDestructor<ReportingSettings> settings;
return settings.get();
}
ReportingSettings* NoSettings() {
return nullptr;
ReportingSettings* NormalSettingsWithEvents() {
static base::NoDestructor<ReportingSettings> settings;
return settings.get();
}
} // namespace
......@@ -41,11 +52,16 @@ class ReportingServiceSettingsTest : public testing::TestWithParam<TestParam> {
public:
const char* settings_value() const { return GetParam().settings_value; }
ReportingSettings* expected_settings() const {
// Set the GURL field dynamically to avoid static initialization issues.
if (GetParam().expected_settings == NormalSettings() &&
// Set the settings fields dynamically to avoid static initialization issue.
if (GetParam().expected_settings == NormalSettingsWithoutEvents() &&
!GetParam().expected_settings->reporting_url.is_valid()) {
GetParam().expected_settings->reporting_url =
GURL("https://chromereporting-pa.googleapis.com/v1/events");
} else if (GetParam().expected_settings == NormalSettingsWithEvents() &&
GetParam().expected_settings->enabled_event_names.empty()) {
GetParam().expected_settings->enabled_event_names.insert("event 1");
GetParam().expected_settings->enabled_event_names.insert("event 2");
GetParam().expected_settings->enabled_event_names.insert("event 3");
}
return GetParam().expected_settings;
}
......@@ -64,17 +80,25 @@ TEST_P(ReportingServiceSettingsTest, Test) {
auto reporting_settings = service_settings.GetReportingSettings();
ASSERT_EQ((expected_settings() != nullptr), reporting_settings.has_value());
if (reporting_settings.has_value()) {
ASSERT_EQ(expected_settings(), NormalSettings());
if (expected_settings() == NormalSettingsWithoutEvents()) {
ASSERT_TRUE(reporting_settings->reporting_url.is_valid());
ASSERT_EQ(expected_settings()->reporting_url,
reporting_settings.value().reporting_url);
} else if (expected_settings() == NormalSettingsWithEvents()) {
ASSERT_FALSE(reporting_settings->enabled_event_names.empty());
ASSERT_EQ(expected_settings()->enabled_event_names,
reporting_settings.value().enabled_event_names);
} else {
ASSERT_EQ(expected_settings(), NoSettings());
}
}
INSTANTIATE_TEST_CASE_P(
,
ReportingServiceSettingsTest,
testing::Values(TestParam(kNormalSettings, NormalSettings()),
TestParam(kNoProviderSettings, NoSettings())));
testing::Values(
TestParam(kNoProviderSettings, NoSettings()),
TestParam(kNormalSettingsWithoutEvents, NormalSettingsWithoutEvents()),
TestParam(kNormalSettingsWithEvents, NormalSettingsWithEvents())));
} // namespace enterprise_connectors
......@@ -147,6 +147,7 @@ const char SafeBrowsingPrivateEventRouter::kKeyMalwareCategory[] =
const char SafeBrowsingPrivateEventRouter::kKeyEvidenceLockerFilePath[] =
"evidenceLockerFilepath";
// All new event names should be added to the kAllEvents array below!
const char SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent[] =
"passwordReuseEvent";
const char SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent[] =
......@@ -159,6 +160,16 @@ const char SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent[] =
"sensitiveDataEvent";
const char SafeBrowsingPrivateEventRouter::kKeyUnscannedFileEvent[] =
"unscannedFileEvent";
// All new event names should be added to this array!
const char* SafeBrowsingPrivateEventRouter::kAllEvents[6] = {
SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent,
SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent,
SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent,
SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent,
SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent,
SafeBrowsingPrivateEventRouter::kKeyUnscannedFileEvent,
};
const char SafeBrowsingPrivateEventRouter::kKeyUnscannedReason[] =
"unscannedReason";
......@@ -207,8 +218,10 @@ void SafeBrowsingPrivateEventRouter::OnPolicySpecifiedPasswordReuseDetected(
}
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyPasswordReuseEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyPasswordReuseEvent, std::move(settings.value()),
......@@ -243,8 +256,10 @@ void SafeBrowsingPrivateEventRouter::OnPolicySpecifiedPasswordChanged(
}
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyPasswordChangedEvent) == 0) {
return;
}
ReportRealtimeEvent(kKeyPasswordChangedEvent, std::move(settings.value()),
base::BindOnce(
......@@ -286,8 +301,10 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDownloadOpened(
}
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyDangerousDownloadEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyDangerousDownloadEvent, std::move(settings.value()),
......@@ -345,8 +362,10 @@ void SafeBrowsingPrivateEventRouter::OnSecurityInterstitialShown(
}
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyInterstitialEvent) == 0) {
return;
}
PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs();
auto event_result =
......@@ -402,8 +421,10 @@ void SafeBrowsingPrivateEventRouter::OnSecurityInterstitialProceeded(
}
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyInterstitialEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyInterstitialEvent, std::move(settings.value()),
......@@ -461,8 +482,10 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDeepScanningResult(
const std::string& malware_category,
const std::string& evidence_locker_filepath) {
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyDangerousDownloadEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyDangerousDownloadEvent, std::move(settings.value()),
......@@ -522,8 +545,10 @@ void SafeBrowsingPrivateEventRouter::OnSensitiveDataEvent(
const int64_t content_size,
safe_browsing::EventResult event_result) {
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeySensitiveDataEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeySensitiveDataEvent, std::move(settings.value()),
......@@ -579,8 +604,10 @@ void SafeBrowsingPrivateEventRouter::OnAnalysisConnectorWarningBypassed(
const enterprise_connectors::ContentAnalysisResponse::Result& result,
const int64_t content_size) {
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeySensitiveDataEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeySensitiveDataEvent, std::move(settings.value()),
......@@ -636,8 +663,10 @@ void SafeBrowsingPrivateEventRouter::OnUnscannedFileEvent(
const int64_t content_size,
safe_browsing::EventResult event_result) {
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyUnscannedFileEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyUnscannedFileEvent, std::move(settings.value()),
......@@ -686,8 +715,10 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDownloadEvent(
const int64_t content_size,
safe_browsing::EventResult event_result) {
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyDangerousDownloadEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyDangerousDownloadEvent, std::move(settings.value()),
......@@ -730,8 +761,10 @@ void SafeBrowsingPrivateEventRouter::OnDangerousDownloadWarningBypassed(
const std::string& mime_type,
const int64_t content_size) {
auto settings = GetReportingSettings();
if (!settings.has_value())
if (!settings.has_value() ||
settings->enabled_event_names.count(kKeyDangerousDownloadEvent) == 0) {
return;
}
ReportRealtimeEvent(
kKeyDangerousDownloadEvent, std::move(settings.value()),
......@@ -989,6 +1022,19 @@ void SafeBrowsingPrivateEventRouter::ReportRealtimeEvent(
const std::string& name,
enterprise_connectors::ReportingSettings settings,
EventBuilder event_builder) {
#ifndef NDEBUG
// Make sure that the event is included in the kAllEvents array.
bool found = false;
for (auto* known_event_name :
extensions::SafeBrowsingPrivateEventRouter::kAllEvents) {
if (name == known_event_name) {
found = true;
break;
}
}
DCHECK(found);
#endif
// Copy the DM token since |settings| is about to move.
std::string dm_token = settings.dm_token;
IfAuthorized(dm_token,
......
......@@ -92,6 +92,8 @@ class SafeBrowsingPrivateEventRouter
static const char kKeyInterstitialEvent[];
static const char kKeySensitiveDataEvent[];
static const char kKeyUnscannedFileEvent[];
static const char* kAllEvents[6];
static const char kKeyUnscannedReason[];
// String constants for the "trigger" event field. This corresponds to
......
......@@ -4,6 +4,7 @@
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
#include <memory>
#include <set>
#include <utility>
#include "base/bind.h"
......@@ -231,8 +232,11 @@ class SafeBrowsingPrivateEventRouterTest : public testing::Test {
"filePasswordProtected", 12345, result);
}
void SetReportingPolicy(bool enabled) {
safe_browsing::SetOnSecurityEventReporting(profile_->GetPrefs(), enabled);
void SetReportingPolicy(bool enabled,
const std::set<std::string>& enabled_event_names =
std::set<std::string>()) {
safe_browsing::SetOnSecurityEventReporting(profile_->GetPrefs(), enabled,
enabled_event_names);
// If we are not enabling reporting, or if the client has already been
// set for testing, just return.
......@@ -246,14 +250,16 @@ class SafeBrowsingPrivateEventRouterTest : public testing::Test {
->SetBrowserCloudPolicyClientForTesting(client_.get());
}
void SetUpRouters(bool realtime_reporting_enable = true,
bool authorized = true) {
void SetUpRouters(bool authorized = true,
bool realtime_reporting_enable = true,
const std::set<std::string>& enabled_event_names =
std::set<std::string>()) {
event_router_ = extensions::CreateAndUseTestEventRouter(profile_);
SafeBrowsingPrivateEventRouterFactory::GetInstance()->SetTestingFactory(
profile_,
base::BindRepeating(&BuildSafeBrowsingPrivateEventRouter, authorized));
SetReportingPolicy(realtime_reporting_enable);
SetReportingPolicy(realtime_reporting_enable, enabled_event_names);
}
protected:
......@@ -576,7 +582,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, PolicyControlOnToOffIsDynamic) {
}
TEST_F(SafeBrowsingPrivateEventRouterTest, PolicyControlOffToOnIsDynamic) {
SetUpRouters(/*realtime_reporting_enable=*/false);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnSecurityInterstitialShown::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -595,7 +601,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, PolicyControlOffToOnIsDynamic) {
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestUnauthorizedOnReuseDetected) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnPolicySpecifiedPasswordReuseDetected::
kEventName);
......@@ -612,7 +618,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestUnauthorizedOnReuseDetected) {
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestUnauthorizedOnPasswordChanged) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnPolicySpecifiedPasswordChanged::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -629,7 +635,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestUnauthorizedOnPasswordChanged) {
TEST_F(SafeBrowsingPrivateEventRouterTest,
TestUnauthorizedOnDangerousDownloadOpened) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnDangerousDownloadOpened::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -646,7 +652,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest,
TEST_F(SafeBrowsingPrivateEventRouterTest,
TestUnauthorizedOnSecurityInterstitialProceeded) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnSecurityInterstitialProceeded::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -663,7 +669,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest,
TEST_F(SafeBrowsingPrivateEventRouterTest,
TestUnauthorizedOnSecurityInterstitialShown) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnSecurityInterstitialShown::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -680,7 +686,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest,
TEST_F(SafeBrowsingPrivateEventRouterTest,
TestUnauthorizedOnDangerousDownloadWarning) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnDangerousDownloadOpened::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -697,7 +703,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest,
TEST_F(SafeBrowsingPrivateEventRouterTest,
TestUnauthorizedOnDangerousDownloadWarningBypass) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/false);
SetUpRouters(/*authorized=*/false);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnDangerousDownloadOpened::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -713,7 +719,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest,
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnSensitiveDataEvent_Allowed) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true);
SetUpRouters(/*authorized=*/true);
base::Value report;
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _))
......@@ -763,7 +769,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnSensitiveDataEvent_Allowed) {
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnSensitiveDataEvent_Blocked) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true);
SetUpRouters();
base::Value report;
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _))
......@@ -813,7 +819,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnSensitiveDataEvent_Blocked) {
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnUnscannedFileEvent_Allowed) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true);
SetUpRouters();
base::Value report;
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _))
......@@ -857,7 +863,7 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnUnscannedFileEvent_Allowed) {
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestOnUnscannedFileEvent_Blocked) {
SetUpRouters(/*realtime_reporting_enable=*/true, /*authorized=*/true);
SetUpRouters();
base::Value report;
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _))
......@@ -938,6 +944,142 @@ TEST_F(SafeBrowsingPrivateEventRouterTest, TestProfileUsername) {
captured_args.FindKey("userName")->GetString());
}
// This next series of tests validate that we get the expected number of events
// reported when a given event name is enabled and we only trigger the related
// events (some events like interstiaial and dangerous downloads have multiple
// triggers for the same event name).
TEST_F(SafeBrowsingPrivateEventRouterTest, TestPasswordChangedEnabled) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(
SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnPolicySpecifiedPasswordChanged::kEventName);
event_router_->AddEventObserver(&event_observer);
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1);
TriggerOnPolicySpecifiedPasswordChangedEvent();
base::RunLoop().RunUntilIdle();
// Assert the event actually did fire.
ASSERT_EQ(1u, event_observer.PassEventArgs().GetList().size());
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestPasswordReuseEnabled) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(
SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnPolicySpecifiedPasswordReuseDetected::
kEventName);
event_router_->AddEventObserver(&event_observer);
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1);
TriggerOnPolicySpecifiedPasswordReuseDetectedEvent();
base::RunLoop().RunUntilIdle();
// Assert the event actually did fire.
ASSERT_EQ(1u, event_observer.PassEventArgs().GetList().size());
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestDangerousDownloadEnabled) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(
SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnDangerousDownloadOpened::kEventName);
event_router_->AddEventObserver(&event_observer);
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(3);
TriggerOnDangerousDownloadEvent();
TriggerOnDangerousDownloadEventBypass();
TriggerOnDangerousDownloadOpenedEvent();
base::RunLoop().RunUntilIdle();
// Assert the event actually did fire.
ASSERT_EQ(1u, event_observer.PassEventArgs().GetList().size());
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestInterstitialEnabled) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(
SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
SafeBrowsingEventObserver event_observer1(
api::safe_browsing_private::OnSecurityInterstitialShown::kEventName);
SafeBrowsingEventObserver event_observer2(
api::safe_browsing_private::OnSecurityInterstitialProceeded::kEventName);
event_router_->AddEventObserver(&event_observer1);
event_router_->AddEventObserver(&event_observer2);
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(2);
TriggerOnSecurityInterstitialShownEvent();
TriggerOnSecurityInterstitialProceededEvent();
base::RunLoop().RunUntilIdle();
// Assert the event actually did fire.
ASSERT_EQ(1u, event_observer1.PassEventArgs().GetList().size());
ASSERT_EQ(1u, event_observer2.PassEventArgs().GetList().size());
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestSensitiveDataEnabled) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(
SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1);
TriggerOnSensitiveDataEvent(safe_browsing::EventResult::BLOCKED);
base::RunLoop().RunUntilIdle();
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
TEST_F(SafeBrowsingPrivateEventRouterTest, TestUnscannedFileEnabled) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(
SafeBrowsingPrivateEventRouter::kKeyUnscannedFileEvent);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _)).Times(1);
TriggerOnUnscannedFileEvent(safe_browsing::EventResult::ALLOWED);
base::RunLoop().RunUntilIdle();
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
// Tests to make sure the feature flag and policy control real-time reporting
// as expected. The parameter for these tests is a tuple of bools:
//
......@@ -1031,7 +1173,7 @@ TEST_P(SafeBrowsingIsRealtimeReportingEnabledTest, CheckRealtimeReport) {
// In production, the router won't actually be authorized unless it was
// initialized. The second argument to SetUpRouters() takes this into
// account.
SetUpRouters(is_policy_enabled_, should_init() && is_authorized_);
SetUpRouters(should_init() && is_authorized_, is_policy_enabled_);
SafeBrowsingEventObserver event_observer(
api::safe_browsing_private::OnPolicySpecifiedPasswordChanged::kEventName);
event_router_->AddEventObserver(&event_observer);
......@@ -1055,7 +1197,7 @@ TEST_P(SafeBrowsingIsRealtimeReportingEnabledTest, CheckRealtimeReport) {
TriggerOnPolicySpecifiedPasswordChangedEvent();
base::RunLoop().RunUntilIdle();
// Asser the triggered actually did fire.
// Assert the trigger actually did fire.
EXPECT_EQ(1u, event_observer.PassEventArgs().GetList().size());
// Make sure UploadSecurityEventReport was called the expected number of
......@@ -1071,4 +1213,98 @@ INSTANTIATE_TEST_SUITE_P(All,
testing::Bool(),
testing::Bool()));
// Tests to make sure only the enabled events are reported.
//
// std::string: the name of the event to enable.
// int: How many triggers use this event name.
class SafeBrowsingIsRealtimeReportingEventDisabledTest
: public SafeBrowsingPrivateEventRouterTest,
public testing::WithParamInterface<testing::tuple<std::string, int>> {
public:
SafeBrowsingIsRealtimeReportingEventDisabledTest()
: event_name_(testing::get<0>(GetParam())),
num_triggers_(testing::get<1>(GetParam())) {}
protected:
const std::string event_name_;
const int num_triggers_;
};
// Tests above confirm the 1:n relation between enabled event name and expected
// triggers, when only these triggers are fired. Here we make sure none of the
// unexpected events are enabled when we trigger all of them.
TEST_P(SafeBrowsingIsRealtimeReportingEventDisabledTest,
TryAllButOnlyTriggerExpectedNumberOfTimesForGivenEvent) {
std::set<std::string> enabled_event_names;
enabled_event_names.insert(event_name_);
SetUpRouters(/*authorized=*/true, /*realtime_reporting_enable=*/true,
enabled_event_names);
SafeBrowsingEventObserver event_observer1(
api::safe_browsing_private::OnPolicySpecifiedPasswordChanged::kEventName);
SafeBrowsingEventObserver event_observer2(
api::safe_browsing_private::OnPolicySpecifiedPasswordReuseDetected::
kEventName);
SafeBrowsingEventObserver event_observer3(
api::safe_browsing_private::OnDangerousDownloadOpened::kEventName);
SafeBrowsingEventObserver event_observer4(
api::safe_browsing_private::OnSecurityInterstitialShown::kEventName);
SafeBrowsingEventObserver event_observer5(
api::safe_browsing_private::OnSecurityInterstitialProceeded::kEventName);
event_router_->AddEventObserver(&event_observer1);
event_router_->AddEventObserver(&event_observer2);
event_router_->AddEventObserver(&event_observer3);
event_router_->AddEventObserver(&event_observer4);
event_router_->AddEventObserver(&event_observer5);
// Only 1 of the 9 triggers should make it to an upload.
EXPECT_CALL(*client_, UploadSecurityEventReport_(_, _, _, _))
.Times(num_triggers_);
TriggerOnPolicySpecifiedPasswordChangedEvent();
TriggerOnPolicySpecifiedPasswordReuseDetectedEvent();
TriggerOnDangerousDownloadOpenedEvent();
TriggerOnSecurityInterstitialShownEvent();
TriggerOnSecurityInterstitialProceededEvent();
TriggerOnDangerousDownloadEvent();
TriggerOnDangerousDownloadEventBypass();
TriggerOnSensitiveDataEvent(safe_browsing::EventResult::BLOCKED);
TriggerOnUnscannedFileEvent(safe_browsing::EventResult::ALLOWED);
base::RunLoop().RunUntilIdle();
// Assert the events with triggers actually did fire.
EXPECT_EQ(1u, event_observer1.PassEventArgs().GetList().size());
EXPECT_EQ(1u, event_observer2.PassEventArgs().GetList().size());
EXPECT_EQ(1u, event_observer3.PassEventArgs().GetList().size());
EXPECT_EQ(1u, event_observer4.PassEventArgs().GetList().size());
EXPECT_EQ(1u, event_observer5.PassEventArgs().GetList().size());
// Make sure UploadSecurityEventReport was called the expected number of
// times.
Mock::VerifyAndClearExpectations(client_.get());
}
INSTANTIATE_TEST_SUITE_P(
All,
SafeBrowsingIsRealtimeReportingEventDisabledTest,
testing::Values(
testing::make_tuple(
SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent,
1),
testing::make_tuple(
SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent,
1),
testing::make_tuple(
SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent,
3),
testing::make_tuple(
SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent,
2),
testing::make_tuple(
SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent,
1),
testing::make_tuple(
SafeBrowsingPrivateEventRouter::kKeyUnscannedFileEvent,
1)));
} // namespace extensions
......@@ -365,8 +365,10 @@ void SetAnalysisConnector(PrefService* prefs,
machine_scope ? policy::POLICY_SCOPE_MACHINE : policy::POLICY_SCOPE_USER);
}
void SetOnSecurityEventReporting(PrefService* prefs,
void SetOnSecurityEventReporting(
PrefService* prefs,
bool enabled,
const std::set<std::string>& enabled_event_names,
bool machine_scope) {
ListPrefUpdate settings_list(prefs,
enterprise_connectors::kOnSecurityEventPref);
......@@ -377,6 +379,14 @@ void SetOnSecurityEventReporting(PrefService* prefs,
settings.SetKey(enterprise_connectors::kKeyServiceProvider,
base::Value("google"));
if (!enabled_event_names.empty()) {
base::Value enabled_event_name_list(base::Value::Type::LIST);
for (const auto& enabled_event_name : enabled_event_names) {
enabled_event_name_list.Append(enabled_event_name);
}
settings.SetKey(enterprise_connectors::kKeyEnabledEventNames,
std::move(enabled_event_name_list));
}
settings_list->Append(std::move(settings));
}
prefs->SetInteger(enterprise_connectors::kOnSecurityEventScopePref,
......
......@@ -150,8 +150,10 @@ void SetAnalysisConnector(PrefService* prefs,
enterprise_connectors::AnalysisConnector connector,
const std::string& pref_value,
bool machine_scope = true);
void SetOnSecurityEventReporting(PrefService* prefs,
void SetOnSecurityEventReporting(
PrefService* prefs,
bool enabled,
const std::set<std::string>& enabled_event_names = std::set<std::string>(),
bool machine_scope = true);
void ClearAnalysisConnector(PrefService* prefs,
enterprise_connectors::AnalysisConnector connector);
......
......@@ -21804,11 +21804,16 @@
'type': 'object',
'properties': {
'service_provider': { 'type': 'string' },
'enabled_event_names': {
'type': 'array',
'items': { 'type': 'string' },
},
},
},
},
'example_value': [{
'service_provider': 'Google',
'enabled_event_names': ['passwordChangedEvent', 'sensitiveDataEvent'],
}],
'features': {
'dynamic_refresh': True,
......@@ -21822,7 +21827,7 @@
'tags': [],
'desc': '''List of Chrome Enterprise Connectors services settings to be applied to the <ph name="ON_SECURITY_EVENT_ENTERPRISE_CONNECTOR">OnSecurityEvent</ph> Enterprise Connector, which triggers when a security event occurs in Chrome. This includes negative verdicts from analysis Enterprise Connectors, password reuse, navigations to unsafe pages and other security sensitive user actions.
The <ph name="ENTERPRISE_CONNECTOR_SERVICE_PROVIDER_FIELD">service_provider</ph> field identifies which reporting service provider the settings correspond to.
The <ph name="ENTERPRISE_CONNECTOR_SERVICE_PROVIDER_FIELD">service_provider</ph> field identifies which reporting service provider the settings correspond to and the <ph name="ENTERPRISE_CONNECTOR_ENABLED_EVENT_NAMES_FIELD">enabled_event_names</ph> field identifies which events are enabled for this provider.
This policy can only be set from the Google Admin console.'''
},
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment