diff --git a/pkg/acquisition/modules/waap/waap_runner.go b/pkg/acquisition/modules/waap/waap_runner.go index 935b32716..3590f417d 100644 --- a/pkg/acquisition/modules/waap/waap_runner.go +++ b/pkg/acquisition/modules/waap/waap_runner.go @@ -106,7 +106,7 @@ func (r *WaapRunner) processRequest(tx waf.ExtendedTransaction, request *waf.Par } } - request.Tx.ProcessURI(request.URI, request.Method, request.Proto) //TODO: The doc mentions that GET args needs to be added, but we never call AddArguments ? + request.Tx.ProcessURI(request.URI, request.Method, request.Proto) for k, vr := range request.Headers { for _, v := range vr { @@ -150,7 +150,11 @@ func (r *WaapRunner) processRequest(tx waf.ExtendedTransaction, request *waf.Par if in != nil { r.logger.Debugf("rules matched for body : %d", in.RuleID) - return nil + } + + err = r.WaapRuntime.ProcessPostEvalRules(request) + if err != nil { + r.logger.Errorf("unable to process PostEval rules: %s", err) } return nil diff --git a/pkg/waf/waap.go b/pkg/waf/waap.go index 7f7b198e2..f47f3312a 100644 --- a/pkg/waf/waap.go +++ b/pkg/waf/waap.go @@ -26,6 +26,7 @@ type Hook struct { const ( hookOnLoad = iota hookPreEval + hookPostEval hookOnMatch ) @@ -38,6 +39,8 @@ func (h *Hook) Build(hookStage int) error { ctx = GetOnLoadEnv(&WaapRuntimeConfig{}) case hookPreEval: ctx = GetPreEvalEnv(&WaapRuntimeConfig{}, &ParsedRequest{}) + case hookPostEval: + ctx = GetPostEvalEnv(&WaapRuntimeConfig{}, &ParsedRequest{}) case hookOnMatch: ctx = GetOnMatchEnv(&WaapRuntimeConfig{}, &ParsedRequest{}, types.Event{}) } @@ -83,6 +86,7 @@ type WaapRuntimeConfig struct { DefaultRemediation string CompiledOnLoad []Hook CompiledPreEval []Hook + CompiledPostEval []Hook CompiledOnMatch []Hook CompiledVariablesTracking []*regexp.Regexp Config *WaapConfig @@ -107,6 +111,7 @@ type WaapConfig struct { PassedHTTPCode int `yaml:"passed_http_code"` OnLoad []Hook `yaml:"on_load"` PreEval []Hook `yaml:"pre_eval"` + PostEval []Hook `yaml:"post_eval"` OnMatch []Hook `yaml:"on_match"` VariablesTracking []string `yaml:"variables_tracking"` InbandOptions WaapSubEngineOpts `yaml:"inband_options"` @@ -239,6 +244,14 @@ func (wc *WaapConfig) Build() (*WaapRuntimeConfig, error) { ret.CompiledPreEval = append(ret.CompiledPreEval, hook) } + for _, hook := range wc.PostEval { + err := hook.Build(hookPostEval) + if err != nil { + return nil, fmt.Errorf("unable to build post_eval hook : %s", err) + } + ret.CompiledPostEval = append(ret.CompiledPostEval, hook) + } + for _, hook := range wc.OnMatch { err := hook.Build(hookOnMatch) if err != nil { @@ -268,7 +281,7 @@ func (w *WaapRuntimeConfig) ProcessOnLoadRules() error { switch t := output.(type) { case bool: if !t { - log.Infof("filter didnt match") + log.Debugf("filter didnt match") continue } default: @@ -298,7 +311,7 @@ func (w *WaapRuntimeConfig) ProcessOnMatchRules(request *ParsedRequest, evt type switch t := output.(type) { case bool: if !t { - log.Infof("filter didnt match") + log.Debugf("filter didnt match") continue } default: @@ -327,7 +340,7 @@ func (w *WaapRuntimeConfig) ProcessPreEvalRules(request *ParsedRequest) error { switch t := output.(type) { case bool: if !t { - log.Infof("filter didnt match") + log.Debugf("filter didnt match") continue } default: @@ -348,6 +361,37 @@ func (w *WaapRuntimeConfig) ProcessPreEvalRules(request *ParsedRequest) error { return nil } +func (w *WaapRuntimeConfig) ProcessPostEvalRules(request *ParsedRequest) error { + for _, rule := range w.CompiledPostEval { + if rule.FilterExpr != nil { + output, err := exprhelpers.Run(rule.FilterExpr, GetPostEvalEnv(w, request), w.Logger, w.Logger.Level >= log.DebugLevel) + if err != nil { + return fmt.Errorf("unable to run waap post_eval filter %s : %w", rule.Filter, err) + } + switch t := output.(type) { + case bool: + if !t { + log.Debugf("filter didnt match") + continue + } + default: + log.Errorf("Filter must return a boolean, can't filter") + continue + } + } + // here means there is no filter or the filter matched + for _, applyExpr := range rule.ApplyExpr { + _, err := exprhelpers.Run(applyExpr, GetPostEvalEnv(w, request), w.Logger, w.Logger.Level >= log.DebugLevel) + if err != nil { + log.Errorf("unable to apply waap post_eval expr: %s", err) + continue + } + } + } + + return nil +} + /* @sbl / @tko add the helpers to: - remove by id-range diff --git a/pkg/waf/waf_helpers.go b/pkg/waf/waf_helpers.go index 83f33b795..d485d59aa 100644 --- a/pkg/waf/waf_helpers.go +++ b/pkg/waf/waf_helpers.go @@ -54,6 +54,15 @@ func GetPreEvalEnv(w *WaapRuntimeConfig, request *ParsedRequest) map[string]inte } } +func GetPostEvalEnv(w *WaapRuntimeConfig, request *ParsedRequest) map[string]interface{} { + //FIXME: use expr.Function instead of this + return map[string]interface{}{ + "IsInBand": request.IsInBand, + "IsOutBand": request.IsOutBand, + "DumpRequest": request.DumpRequest, + } +} + func GetOnMatchEnv(w *WaapRuntimeConfig, request *ParsedRequest, evt types.Event) map[string]interface{} { //FIXME: use expr.Function instead of this return map[string]interface{}{