diff --git a/server/modules/elastalert/elastalert.go b/server/modules/elastalert/elastalert.go index 7a847af8..f2b085d7 100644 --- a/server/modules/elastalert/elastalert.go +++ b/server/modules/elastalert/elastalert.go @@ -1806,12 +1806,12 @@ func (e *ElastAlertEngine) wrapRule(det *model.Detection, rule string) (string, Filter: []map[string]interface{}{{"eql": rule}}, } - if licensing.IsEnabled(licensing.FEAT_NTF) { - if slices.Contains(det.Tags, "so.notification") { - // This is a detection for sending notifications only, do not add a new alert to Security Onion. - wrapper.Alert = nil - } + if slices.Contains(det.Tags, "so.notification") { + // This is a detection for sending notifications only, do not add a new alert to Security Onion. + wrapper.Alert = nil + } + if licensing.IsEnabled(licensing.FEAT_NTF) { // Add any custom alerters to the rule. for _, alerter := range alerters { alerter = strings.TrimSpace(alerter) @@ -1833,6 +1833,14 @@ func (e *ElastAlertEngine) wrapRule(det *model.Detection, rule string) (string, } } + if len(wrapper.Alert) == 0 { + log.WithFields(log.Fields{ + "detectionPublicId": det.PublicID, + "severity": string(det.Severity), + }).Debug("Disabling ElastAlert rule due to no valid alerters") + strYaml += "\nis_enabled: False\n" + } + return strYaml, nil } diff --git a/server/modules/elastalert/elastalert_test.go b/server/modules/elastalert/elastalert_test.go index 5cb4abc3..cd2c76fc 100644 --- a/server/modules/elastalert/elastalert_test.go +++ b/server/modules/elastalert/elastalert_test.go @@ -519,6 +519,70 @@ foo: bar assert.YAMLEq(t, expected, wrappedRule) } +func TestSigmaToElastAlertNotificationOnlyUnlicensed(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + iom := mock.NewMockIOManager(ctrl) + + iom.EXPECT().ExecCommand(gomock.Cond(func(x any) bool { + cmd := x.(*exec.Cmd) + + if !strings.HasSuffix(cmd.Path, "sigma") { + return false + } + + if !slices.Contains(cmd.Args, "convert") { + return false + } + + if cmd.Stdin == nil { + return false + } + + return true + })).Return([]byte(""), 0, time.Duration(0), nil) + + engine := ElastAlertEngine{ + IOManager: iom, + additionalAlerters: []string{"email", "slack"}, + additionalAlerterParams: "foo: bar", + } + + det := &model.Detection{ + PublicID: "00000000-0000-0000-0000-000000000000", + Content: "totally good sigma", + Title: "Test Detection", + Tags: []string{"so.notification"}, + Severity: model.SeverityHigh, + } + + licensing.Shutdown() + query, err := engine.sigmaToElastAlert(context.Background(), det) + assert.NoError(t, err) + + wrappedRule, err := engine.wrapRule(det, query) + assert.NoError(t, err) + + expected := `detection_title: Test Detection +detection_public_id: 00000000-0000-0000-0000-000000000000 +event.module: sigma +event.dataset: sigma.alert +event.severity: 4 +sigma_level: high +alert: [] +index: .ds-logs-* +name: Test Detection -- 00000000-0000-0000-0000-000000000000 +type: any +realert: + seconds: 0 +filter: + - eql: +is_enabled: False +` + assert.YAMLEq(t, expected, wrappedRule) +} + func TestAdditionalAlertersSev0(t *testing.T) { engine := ElastAlertEngine{ additionalAlerters: []string{"email", "slack"},