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 k, vr := range request.Headers {
|
||||||
for _, v := range vr {
|
for _, v := range vr {
|
||||||
|
@ -150,7 +150,11 @@ func (r *WaapRunner) processRequest(tx waf.ExtendedTransaction, request *waf.Par
|
||||||
|
|
||||||
if in != nil {
|
if in != nil {
|
||||||
r.logger.Debugf("rules matched for body : %d", in.RuleID)
|
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
|
return nil
|
||||||
|
|
|
@ -26,6 +26,7 @@ type Hook struct {
|
||||||
const (
|
const (
|
||||||
hookOnLoad = iota
|
hookOnLoad = iota
|
||||||
hookPreEval
|
hookPreEval
|
||||||
|
hookPostEval
|
||||||
hookOnMatch
|
hookOnMatch
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ func (h *Hook) Build(hookStage int) error {
|
||||||
ctx = GetOnLoadEnv(&WaapRuntimeConfig{})
|
ctx = GetOnLoadEnv(&WaapRuntimeConfig{})
|
||||||
case hookPreEval:
|
case hookPreEval:
|
||||||
ctx = GetPreEvalEnv(&WaapRuntimeConfig{}, &ParsedRequest{})
|
ctx = GetPreEvalEnv(&WaapRuntimeConfig{}, &ParsedRequest{})
|
||||||
|
case hookPostEval:
|
||||||
|
ctx = GetPostEvalEnv(&WaapRuntimeConfig{}, &ParsedRequest{})
|
||||||
case hookOnMatch:
|
case hookOnMatch:
|
||||||
ctx = GetOnMatchEnv(&WaapRuntimeConfig{}, &ParsedRequest{}, types.Event{})
|
ctx = GetOnMatchEnv(&WaapRuntimeConfig{}, &ParsedRequest{}, types.Event{})
|
||||||
}
|
}
|
||||||
|
@ -83,6 +86,7 @@ type WaapRuntimeConfig struct {
|
||||||
DefaultRemediation string
|
DefaultRemediation string
|
||||||
CompiledOnLoad []Hook
|
CompiledOnLoad []Hook
|
||||||
CompiledPreEval []Hook
|
CompiledPreEval []Hook
|
||||||
|
CompiledPostEval []Hook
|
||||||
CompiledOnMatch []Hook
|
CompiledOnMatch []Hook
|
||||||
CompiledVariablesTracking []*regexp.Regexp
|
CompiledVariablesTracking []*regexp.Regexp
|
||||||
Config *WaapConfig
|
Config *WaapConfig
|
||||||
|
@ -107,6 +111,7 @@ type WaapConfig struct {
|
||||||
PassedHTTPCode int `yaml:"passed_http_code"`
|
PassedHTTPCode int `yaml:"passed_http_code"`
|
||||||
OnLoad []Hook `yaml:"on_load"`
|
OnLoad []Hook `yaml:"on_load"`
|
||||||
PreEval []Hook `yaml:"pre_eval"`
|
PreEval []Hook `yaml:"pre_eval"`
|
||||||
|
PostEval []Hook `yaml:"post_eval"`
|
||||||
OnMatch []Hook `yaml:"on_match"`
|
OnMatch []Hook `yaml:"on_match"`
|
||||||
VariablesTracking []string `yaml:"variables_tracking"`
|
VariablesTracking []string `yaml:"variables_tracking"`
|
||||||
InbandOptions WaapSubEngineOpts `yaml:"inband_options"`
|
InbandOptions WaapSubEngineOpts `yaml:"inband_options"`
|
||||||
|
@ -239,6 +244,14 @@ func (wc *WaapConfig) Build() (*WaapRuntimeConfig, error) {
|
||||||
ret.CompiledPreEval = append(ret.CompiledPreEval, hook)
|
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 {
|
for _, hook := range wc.OnMatch {
|
||||||
err := hook.Build(hookOnMatch)
|
err := hook.Build(hookOnMatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -268,7 +281,7 @@ func (w *WaapRuntimeConfig) ProcessOnLoadRules() error {
|
||||||
switch t := output.(type) {
|
switch t := output.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
if !t {
|
if !t {
|
||||||
log.Infof("filter didnt match")
|
log.Debugf("filter didnt match")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -298,7 +311,7 @@ func (w *WaapRuntimeConfig) ProcessOnMatchRules(request *ParsedRequest, evt type
|
||||||
switch t := output.(type) {
|
switch t := output.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
if !t {
|
if !t {
|
||||||
log.Infof("filter didnt match")
|
log.Debugf("filter didnt match")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -327,7 +340,7 @@ func (w *WaapRuntimeConfig) ProcessPreEvalRules(request *ParsedRequest) error {
|
||||||
switch t := output.(type) {
|
switch t := output.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
if !t {
|
if !t {
|
||||||
log.Infof("filter didnt match")
|
log.Debugf("filter didnt match")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -348,6 +361,37 @@ func (w *WaapRuntimeConfig) ProcessPreEvalRules(request *ParsedRequest) error {
|
||||||
return nil
|
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
|
/* @sbl / @tko
|
||||||
add the helpers to:
|
add the helpers to:
|
||||||
- remove by id-range
|
- 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{} {
|
func GetOnMatchEnv(w *WaapRuntimeConfig, request *ParsedRequest, evt types.Event) map[string]interface{} {
|
||||||
//FIXME: use expr.Function instead of this
|
//FIXME: use expr.Function instead of this
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
|
|
Loading…
Reference in a new issue