From 946fbbb8a2d57c2538cd835350429d1a7227dc94 Mon Sep 17 00:00:00 2001 From: Sebastien Blot Date: Fri, 24 Nov 2023 15:57:49 +0100 Subject: [PATCH] up --- pkg/waf/env.go | 44 ------------------- pkg/waf/tx.go | 26 ++++++++++++ pkg/waf/waap.go | 94 ++++++++++++++++++++++++++++++++--------- pkg/waf/waf_expr_lib.go | 6 +++ pkg/waf/waf_helpers.go | 34 +++++++++++++++ 5 files changed, 139 insertions(+), 65 deletions(-) delete mode 100644 pkg/waf/env.go create mode 100644 pkg/waf/tx.go diff --git a/pkg/waf/env.go b/pkg/waf/env.go deleted file mode 100644 index 2322a6e43..000000000 --- a/pkg/waf/env.go +++ /dev/null @@ -1,44 +0,0 @@ -package waf - -import ( - "github.com/crowdsecurity/coraza/v3" - "github.com/crowdsecurity/coraza/v3/experimental" -) - -type ExtendedTransaction struct { - Tx experimental.FullTransaction -} - -func NewExtendedTransaction(engine coraza.WAF, uuid string) ExtendedTransaction { - inBoundTx := engine.NewTransactionWithID(uuid) - expTx := inBoundTx.(experimental.FullTransaction) - tx := NewTransaction(expTx) - return tx -} - -func NewTransaction(tx experimental.FullTransaction) ExtendedTransaction { - return ExtendedTransaction{Tx: tx} -} - -func (t *ExtendedTransaction) RemoveRuleByIDWithError(id int) error { - t.Tx.RemoveRuleByID(id) - return nil -} - -// simply used to ease the compilation & runtime of the hooks -func GetHookEnv(w *WaapRuntimeConfig, request ParsedRequest) map[string]interface{} { - return map[string]interface{}{ - "inband_rules": w.InBandRules, - "outband_rules": w.OutOfBandRules, - "req": request, - "RemoveInbandRuleByID": w.RemoveInbandRuleByID, - "RemoveOutbandRuleByID": w.RemoveOutbandRuleByID, - "SetAction": w.SetAction, - "SetActionByTag": w.SetActionByTag, - "SetHTTPCode": w.SetHTTPCode, - "SetActionByID": w.SetActionByID, - "CancelEvent": w.CancelEvent, - "IsInBand": request.IsInBand, - "IsOutBand": request.IsOutBand, - } -} diff --git a/pkg/waf/tx.go b/pkg/waf/tx.go new file mode 100644 index 000000000..416ad953e --- /dev/null +++ b/pkg/waf/tx.go @@ -0,0 +1,26 @@ +package waf + +import ( + "github.com/crowdsecurity/coraza/v3" + "github.com/crowdsecurity/coraza/v3/experimental" +) + +type ExtendedTransaction struct { + Tx experimental.FullTransaction +} + +func NewExtendedTransaction(engine coraza.WAF, uuid string) ExtendedTransaction { + inBoundTx := engine.NewTransactionWithID(uuid) + expTx := inBoundTx.(experimental.FullTransaction) + tx := NewTransaction(expTx) + return tx +} + +func NewTransaction(tx experimental.FullTransaction) ExtendedTransaction { + return ExtendedTransaction{Tx: tx} +} + +func (t *ExtendedTransaction) RemoveRuleByIDWithError(id int) error { + t.Tx.RemoveRuleByID(id) + return nil +} diff --git a/pkg/waf/waap.go b/pkg/waf/waap.go index 25aef729a..449920508 100644 --- a/pkg/waf/waap.go +++ b/pkg/waf/waap.go @@ -47,6 +47,7 @@ type WaapTempResponse struct { Action string //allow, deny, captcha, log HTTPResponseCode int SendEvent bool //do we send an internal event on rule match + SendAlert bool //do we send an alert on rule match } type WaapSubEngineOpts struct { @@ -240,7 +241,7 @@ func (wc *WaapConfig) Build() (*WaapRuntimeConfig, error) { func (w *WaapRuntimeConfig) ProcessOnLoadRules() error { for _, rule := range w.CompiledOnLoad { if rule.FilterExpr != nil { - output, err := expr.Run(rule.FilterExpr, GetHookEnv(w, ParsedRequest{})) + output, err := expr.Run(rule.FilterExpr, GetOnLoadEnv(w)) if err != nil { return fmt.Errorf("unable to run filter %s : %w", rule.Filter, err) } @@ -256,7 +257,7 @@ func (w *WaapRuntimeConfig) ProcessOnLoadRules() error { } } for _, applyExpr := range rule.ApplyExpr { - _, err := expr.Run(applyExpr, GetHookEnv(w, ParsedRequest{})) + _, err := expr.Run(applyExpr, GetOnLoadEnv(w)) if err != nil { log.Errorf("unable to apply filter: %s", err) continue @@ -270,7 +271,7 @@ func (w *WaapRuntimeConfig) ProcessOnMatchRules(request ParsedRequest) error { for _, rule := range w.CompiledOnMatch { if rule.FilterExpr != nil { - output, err := expr.Run(rule.FilterExpr, GetHookEnv(w, request)) + output, err := expr.Run(rule.FilterExpr, GetOnMatchEnv(w, request)) if err != nil { return fmt.Errorf("unable to run filter %s : %w", rule.Filter, err) } @@ -286,7 +287,7 @@ func (w *WaapRuntimeConfig) ProcessOnMatchRules(request ParsedRequest) error { } } for _, applyExpr := range rule.ApplyExpr { - _, err := expr.Run(applyExpr, GetHookEnv(w, request)) + _, err := expr.Run(applyExpr, GetOnMatchEnv(w, request)) if err != nil { log.Errorf("unable to apply filter: %s", err) continue @@ -299,7 +300,7 @@ func (w *WaapRuntimeConfig) ProcessOnMatchRules(request ParsedRequest) error { func (w *WaapRuntimeConfig) ProcessPreEvalRules(request ParsedRequest) error { for _, rule := range w.CompiledPreEval { if rule.FilterExpr != nil { - output, err := expr.Run(rule.FilterExpr, GetHookEnv(w, request)) + output, err := expr.Run(rule.FilterExpr, GetPreEvalEnv(w, request)) if err != nil { return fmt.Errorf("unable to run filter %s : %w", rule.Filter, err) } @@ -316,7 +317,7 @@ func (w *WaapRuntimeConfig) ProcessPreEvalRules(request ParsedRequest) error { } // here means there is no filter or the filter matched for _, applyExpr := range rule.ApplyExpr { - _, err := expr.Run(applyExpr, GetHookEnv(w, request)) + _, err := expr.Run(applyExpr, GetPreEvalEnv(w, request)) if err != nil { log.Errorf("unable to apply filter: %s", err) continue @@ -335,31 +336,80 @@ add the helpers to: */ -func (w *WaapRuntimeConfig) RemoveInbandRuleByID(id int) error { - return w.InBandTx.RemoveRuleByIDWithError(id) +// func (w *WaapRuntimeConfig) RemoveInbandRuleByID(id int) error { +func (w *WaapRuntimeConfig) RemoveInbandRuleByID(params ...any) (any, error) { + id := params[0].(int) + _ = w.InBandTx.RemoveRuleByIDWithError(id) + return nil, nil } -func (w *WaapRuntimeConfig) CancelEvent() error { +func (w *WaapRuntimeConfig) CancelEvent(params ...any) (any, error) { w.Response.SendEvent = false - return nil + return nil, nil } -func (w *WaapRuntimeConfig) SetActionByTag(tag string, action string) error { +// func (w *WaapRuntimeConfig) DisableInBandRuleByID(id int) error { +func (w *WaapRuntimeConfig) DisableInBandRuleByID(params ...any) (any, error) { panic("not implemented") - return nil + return nil, nil } -func (w *WaapRuntimeConfig) SetActionByID(id int, action string) error { +// func (w *WaapRuntimeConfig) DisableInBandRuleByTag(id int) error { +func (w *WaapRuntimeConfig) DisableInBandRuleByTag(params ...any) (any, error) { panic("not implemented") - return nil + return nil, nil } -func (w *WaapRuntimeConfig) RemoveOutbandRuleByID(id int) error { - return w.OutOfBandTx.RemoveRuleByIDWithError(id) +// func (w *WaapRuntimeConfig) DisableOutBandRuleByID(tag string) error { +func (w *WaapRuntimeConfig) DisableOutBandRuleByID(params ...any) (any, error) { + panic("not implemented") + return nil, nil } -func (w *WaapRuntimeConfig) SetAction(action string) error { +// func (w *WaapRuntimeConfig) DisableOutBandRuleByTag(tag string) error { +func (w *WaapRuntimeConfig) DisableOutBandRuleByTag(params ...any) (any, error) { + panic("not implemented") + return nil, nil +} + +func (w *WaapRuntimeConfig) SendEvent(params ...any) (any, error) { + w.Response.SendEvent = true + return nil, nil +} + +func (w *WaapRuntimeConfig) SendAlert(params ...any) (any, error) { + w.Response.SendAlert = true + return nil, nil +} + +func (w *WaapRuntimeConfig) CancelAlert(params ...any) (any, error) { + w.Response.SendAlert = false + return nil, nil +} + +// func (w *WaapRuntimeConfig) SetActionByTag(tag string, action string) error { +func (w *WaapRuntimeConfig) SetActionByTag(params ...any) (any, error) { + panic("not implemented") + return nil, nil +} + +// func (w *WaapRuntimeConfig) SetActionByID(id int, action string) error { +func (w *WaapRuntimeConfig) SetActionByID(params ...any) (any, error) { + panic("not implemented") + return nil, nil +} + +// func (w *WaapRuntimeConfig) RemoveOutbandRuleByID(id int) error { +func (w *WaapRuntimeConfig) RemoveOutbandRuleByID(params ...any) (any, error) { + id := params[0].(int) + _ = w.OutOfBandTx.RemoveRuleByIDWithError(id) + return nil, nil +} + +// func (w *WaapRuntimeConfig) SetAction(action string) error { +func (w *WaapRuntimeConfig) SetAction(params ...any) (any, error) { //log.Infof("setting to %s", action) + action := params[0].(string) switch action { case "allow": w.Response.Action = action @@ -375,15 +425,17 @@ func (w *WaapRuntimeConfig) SetAction(action string) error { w.Response.Action = action w.Response.HTTPResponseCode = w.Config.BlockedHTTPCode default: - return fmt.Errorf("unknown action %s", action) + return nil, fmt.Errorf("unknown action %s", action) } - return nil + return nil, nil } -func (w *WaapRuntimeConfig) SetHTTPCode(code int) error { +// func (w *WaapRuntimeConfig) SetHTTPCode(code int) error { +func (w *WaapRuntimeConfig) SetHTTPCode(params ...any) (any, error) { + code := params[0].(int) w.Response.HTTPResponseCode = code - return nil + return nil, nil } type BodyResponse struct { diff --git a/pkg/waf/waf_expr_lib.go b/pkg/waf/waf_expr_lib.go index 33dd1f4e4..48685957d 100644 --- a/pkg/waf/waf_expr_lib.go +++ b/pkg/waf/waf_expr_lib.go @@ -8,6 +8,12 @@ type exprCustomFunc struct { signature []interface{} } +var onLoadExprFuncs = []exprCustomFunc{} + +var preEvalExprFuncs = []exprCustomFunc{} + +var onMatchExprFuncs = []exprCustomFunc{} + var exprFuncs = []exprCustomFunc{ /*{ name: "SetRulesToInband", diff --git a/pkg/waf/waf_helpers.go b/pkg/waf/waf_helpers.go index 97b1f30f0..22a35a8b9 100644 --- a/pkg/waf/waf_helpers.go +++ b/pkg/waf/waf_helpers.go @@ -30,3 +30,37 @@ func GetExprWAFOptions(ctx map[string]interface{}) []expr.Option { } return baseHelpers } + +func GetOnLoadEnv(w *WaapRuntimeConfig) map[string]interface{} { + return map[string]interface{}{ + "DisableInBandRuleByID": w.DisableInBandRuleByID, + "DisableOutBandRuleByID": w.DisableOutBandRuleByID, + "DisableInBandRuleByTag": w.DisableInBandRuleByTag, + "DisableOutBandRuleByTag": w.DisableOutBandRuleByTag, + } +} + +func GetPreEvalEnv(w *WaapRuntimeConfig, request ParsedRequest) map[string]interface{} { + return map[string]interface{}{ + "IsInBand": request.IsInBand, + "IsOutBand": request.IsOutBand, + "RemoveInBandRuleByID": w.RemoveInbandRuleByID, + "RemoveOutBandRuleByID": w.RemoveOutbandRuleByID, + "SetRemediationByTag": w.SetActionByTag, + "SetRemdiationByID": w.SetActionByID, + } +} + +func GetOnMatchEnv(w *WaapRuntimeConfig, request ParsedRequest) map[string]interface{} { + return map[string]interface{}{ + "req": request, + "IsInBand": request.IsInBand, + "IsOutBand": request.IsOutBand, + "SetRemediation": w.SetAction, + "SetReturnCode": w.SetHTTPCode, + "CancelEvent": w.CancelEvent, + "SendEvent": w.SendEvent, + "CancelAlert": w.CancelAlert, + "SendAlert": w.SendAlert, + } +}