add post_eval hook
This commit is contained in:
parent
d9355e8c3a
commit
60faeaa7d7
3 changed files with 62 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{}{
|
||||
|
|
Loading…
Reference in a new issue