From adba4e2a2ff8953a031009c7b9d92140b71a5d76 Mon Sep 17 00:00:00 2001 From: "Thibault \"bui\" Koechlin" Date: Fri, 12 Jan 2024 10:11:13 +0100 Subject: [PATCH] fix multizone multivar (#2727) --- pkg/appsec/appsec_rule/modsec_rule_test.go | 29 ++++++++++++++++++++++ pkg/appsec/appsec_rule/modsecurity.go | 5 +++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/pkg/appsec/appsec_rule/modsec_rule_test.go b/pkg/appsec/appsec_rule/modsec_rule_test.go index a11bfd214..3c790cfb9 100644 --- a/pkg/appsec/appsec_rule/modsec_rule_test.go +++ b/pkg/appsec/appsec_rule/modsec_rule_test.go @@ -18,6 +18,16 @@ func TestVPatchRuleString(t *testing.T) { }, expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:2203944045,phase:2,deny,log,msg:'Base Rule',tag:'crowdsec-Base Rule',t:lowercase"`, }, + { + name: "One zone, multi var", + rule: CustomRule{ + Zones: []string{"ARGS"}, + Variables: []string{"foo", "bar"}, + Match: match{Type: "regex", Value: "[^a-zA-Z]"}, + Transform: []string{"lowercase"}, + }, + expected: `SecRule ARGS_GET:foo|ARGS_GET:bar "@rx [^a-zA-Z]" "id:385719930,phase:2,deny,log,msg:'One zone, multi var',tag:'crowdsec-One zone, multi var',t:lowercase"`, + }, { name: "Base Rule #2", rule: CustomRule{ @@ -44,6 +54,25 @@ func TestVPatchRuleString(t *testing.T) { }, expected: `SecRule ARGS_GET:foo|ARGS_POST:foo "@rx [^a-zA-Z]" "id:3387135861,phase:2,deny,log,msg:'Multiple Zones',tag:'crowdsec-Multiple Zones',t:lowercase"`, }, + { + name: "Multiple Zones Multi Var", + rule: CustomRule{ + Zones: []string{"ARGS", "BODY_ARGS"}, + Variables: []string{"foo", "bar"}, + Match: match{Type: "regex", Value: "[^a-zA-Z]"}, + Transform: []string{"lowercase"}, + }, + expected: `SecRule ARGS_GET:foo|ARGS_GET:bar|ARGS_POST:foo|ARGS_POST:bar "@rx [^a-zA-Z]" "id:1119773585,phase:2,deny,log,msg:'Multiple Zones Multi Var',tag:'crowdsec-Multiple Zones Multi Var',t:lowercase"`, + }, + { + name: "Multiple Zones No Vars", + rule: CustomRule{ + Zones: []string{"ARGS", "BODY_ARGS"}, + Match: match{Type: "regex", Value: "[^a-zA-Z]"}, + Transform: []string{"lowercase"}, + }, + expected: `SecRule ARGS_GET|ARGS_POST "@rx [^a-zA-Z]" "id:2020110336,phase:2,deny,log,msg:'Multiple Zones No Vars',tag:'crowdsec-Multiple Zones No Vars',t:lowercase"`, + }, { name: "Basic AND", rule: CustomRule{ diff --git a/pkg/appsec/appsec_rule/modsecurity.go b/pkg/appsec/appsec_rule/modsecurity.go index e9f131b5f..1b30cd87e 100644 --- a/pkg/appsec/appsec_rule/modsecurity.go +++ b/pkg/appsec/appsec_rule/modsecurity.go @@ -123,6 +123,9 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, appsecRuleName string, an } for idx, zone := range rule.Zones { + if idx > 0 { + r.WriteByte('|') + } mappedZone, ok := zonesMap[zone] if !ok { return nil, fmt.Errorf("unknown zone '%s'", zone) @@ -131,7 +134,7 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, appsecRuleName string, an r.WriteString(mappedZone) } else { for j, variable := range rule.Variables { - if idx > 0 || j > 0 { + if j > 0 { r.WriteByte('|') } r.WriteString(fmt.Sprintf("%s:%s", mappedZone, variable))