From 685006508c8717e2311938ff8b73e423c933097a Mon Sep 17 00:00:00 2001 From: bui Date: Tue, 24 Oct 2023 13:43:27 +0200 Subject: [PATCH] make waap rules generate crowdsec events (again) --- pkg/acquisition/modules/waap/utils.go | 46 ++++++++++----------- pkg/acquisition/modules/waap/waap_runner.go | 33 +++++++++------ 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/pkg/acquisition/modules/waap/utils.go b/pkg/acquisition/modules/waap/utils.go index 4bae89b45..8353239fe 100644 --- a/pkg/acquisition/modules/waap/utils.go +++ b/pkg/acquisition/modules/waap/utils.go @@ -5,7 +5,6 @@ import ( "time" "github.com/crowdsecurity/coraza/v3/collection" - "github.com/crowdsecurity/coraza/v3/experimental" "github.com/crowdsecurity/coraza/v3/types/variables" "github.com/crowdsecurity/crowdsec/pkg/types" "github.com/crowdsecurity/crowdsec/pkg/waf" @@ -76,32 +75,23 @@ func LogWaapEvent(evt *types.Event, logger *log.Entry) { } -/* - how to configure variables to be kept: - 1) full collection : tx.* - 2) subvariables : tx.a* - -*/ - -// func LogWaapEvent(evt *types.Event) error { - -// return nil -// } - -func AccumulateTxToEvent(logger log.Entry, tx experimental.FullTransaction, kind string, evt *types.Event, wr *waf.WaapRuntimeConfig) error { - - if tx.IsInterrupted() { +func (r *WaapRunner) AccumulateTxToEvent(evt *types.Event, req waf.ParsedRequest) error { + if evt == nil { + //an error was already emitted, let's not spam the logs + return nil + } + if req.Tx.IsInterrupted() { if evt.Meta == nil { evt.Meta = map[string]string{} } - if kind == InBand { + if req.IsInBand { evt.Meta["waap_interrupted"] = "true" - evt.Meta["waap_action"] = tx.Interruption().Action + evt.Meta["waap_action"] = req.Tx.Interruption().Action evt.Parsed["inband_interrupted"] = "true" - evt.Parsed["inband_action"] = tx.Interruption().Action + evt.Parsed["inband_action"] = req.Tx.Interruption().Action } else { evt.Parsed["outofband_interrupted"] = "true" - evt.Parsed["outofband_action"] = tx.Interruption().Action + evt.Parsed["outofband_action"] = req.Tx.Interruption().Action } } @@ -109,7 +99,7 @@ func AccumulateTxToEvent(logger log.Entry, tx experimental.FullTransaction, kind evt.Waap.Vars = map[string]string{} } - tx.Variables().All(func(v variables.RuleVariable, col collection.Collection) bool { + req.Tx.Variables().All(func(v variables.RuleVariable, col collection.Collection) bool { for _, variable := range col.FindAll() { key := "" if variable.Key() == "" { @@ -120,23 +110,28 @@ func AccumulateTxToEvent(logger log.Entry, tx experimental.FullTransaction, kind if variable.Value() == "" { continue } - for _, collectionToKeep := range wr.CompiledVariablesTracking { + for _, collectionToKeep := range r.WaapRuntime.CompiledVariablesTracking { match := collectionToKeep.MatchString(key) if match { evt.Waap.Vars[key] = variable.Value() - logger.Debugf("%s.%s = %s", variable.Variable().Name(), variable.Key(), variable.Value()) + r.logger.Debugf("%s.%s = %s", variable.Variable().Name(), variable.Key(), variable.Value()) } else { - logger.Debugf("%s.%s != %s (%s) (not kept)", variable.Variable().Name(), variable.Key(), collectionToKeep, variable.Value()) + r.logger.Debugf("%s.%s != %s (%s) (not kept)", variable.Variable().Name(), variable.Key(), collectionToKeep, variable.Value()) } } } return true }) - for _, rule := range tx.MatchedRules() { + for _, rule := range req.Tx.MatchedRules() { if rule.Message() == "" { + r.logger.Tracef("discarding rule %d", rule.Rule().ID()) continue } + kind := "outofband" + if req.IsInBand { + kind = "inband" + } WafRuleHits.With(prometheus.Labels{"rule_id": fmt.Sprintf("%d", rule.Rule().ID()), "type": kind}).Inc() corazaRule := map[string]interface{}{ @@ -158,4 +153,5 @@ func AccumulateTxToEvent(logger log.Entry, tx experimental.FullTransaction, kind } return nil + } diff --git a/pkg/acquisition/modules/waap/waap_runner.go b/pkg/acquisition/modules/waap/waap_runner.go index ed52abebb..566eb4607 100644 --- a/pkg/acquisition/modules/waap/waap_runner.go +++ b/pkg/acquisition/modules/waap/waap_runner.go @@ -165,14 +165,22 @@ func (r *WaapRunner) Run(t *tomb.Tomb) error { r.logger.Errorf("unable to process PreEval rules: %s", err) continue } - log.Infof("now response is -> %s", r.WaapRuntime.Response.Action) //inband WAAP rules err = r.ProcessInBandRules(&request) if err != nil { r.logger.Errorf("unable to process InBand rules: %s", err) continue } - + //create the associated event for crowdsec itself + evt, err := EventFromRequest(request) + if err != nil { + //let's not interrupt the pipeline for this + r.logger.Errorf("unable to create event from request : %s", err) + } + err = r.AccumulateTxToEvent(&evt, request) + if err != nil { + r.logger.Errorf("unable to accumulate tx to event : %s", err) + } if in := request.Tx.Interruption(); in != nil { r.logger.Debugf("inband rules matched : %d", in.RuleID) r.WaapRuntime.Response.InBandInterrupt = true @@ -200,20 +208,21 @@ func (r *WaapRunner) Run(t *tomb.Tomb) error { r.logger.Errorf("unable to process OutOfBand rules: %s", err) continue } - + err = r.AccumulateTxToEvent(&evt, request) + if err != nil { + r.logger.Errorf("unable to accumulate tx to event : %s", err) + } if in := request.Tx.Interruption(); in != nil { r.logger.Debugf("outband rules matched : %d", in.RuleID) r.WaapRuntime.Response.OutOfBandInterrupt = true - } else { - continue + err = r.WaapRuntime.ProcessOnMatchRules(request) + if err != nil { + r.logger.Errorf("unable to process OnMatch rules: %s", err) + continue + } } - - err = r.WaapRuntime.ProcessOnMatchRules(request) - if err != nil { - r.logger.Errorf("unable to process OnMatch rules: %s", err) - continue - } - + r.logger.Debugf("sending event %p to outChan", &evt) + r.outChan <- evt } } }