This commit is contained in:
Sebastien Blot 2023-11-29 22:02:38 +01:00
parent 5f254769ae
commit eed9ff0c46
No known key found for this signature in database
GPG key ID: DFC2902F40449F6A
3 changed files with 24 additions and 20 deletions

View file

@ -16,7 +16,7 @@ func TestVPatchRuleString(t *testing.T) {
Match: match{Type: "regex", Value: "[^a-zA-Z]"},
Transform: []string{"lowercase"},
},
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:1136235475,phase:2,deny,log,msg:'Base Rule',t:lowercase"`,
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: "Multiple Zones",
@ -26,7 +26,7 @@ func TestVPatchRuleString(t *testing.T) {
Match: match{Type: "regex", Value: "[^a-zA-Z]"},
Transform: []string{"lowercase"},
},
expected: `SecRule ARGS_GET:foo|ARGS_POST:foo "@rx [^a-zA-Z]" "id:2088895799,phase:2,deny,log,msg:'Multiple Zones',t:lowercase"`,
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: "Basic AND",
@ -47,8 +47,8 @@ func TestVPatchRuleString(t *testing.T) {
},
},
},
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:2323451654,phase:2,deny,log,msg:'Basic AND_and_0',t:lowercase,chain"
SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:2075918819,phase:2,deny,log,msg:'Basic AND_and_1',t:lowercase"`,
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:4145519614,phase:2,deny,log,msg:'Basic AND',tag:'crowdsec-Basic AND',t:lowercase,chain"
SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:1865217529,phase:2,deny,log,msg:'Basic AND',tag:'crowdsec-Basic AND',t:lowercase"`,
},
{
name: "Basic OR",
@ -68,8 +68,8 @@ SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:2075918819,phase:2,deny,log,msg:'Basic
},
},
},
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:2720972114,phase:2,deny,log,msg:'Basic OR_or_0',t:lowercase,skip:1"
SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:2638639999,phase:2,deny,log,msg:'Basic OR_or_1',t:lowercase"`,
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:651140804,phase:2,deny,log,msg:'Basic OR',tag:'crowdsec-Basic OR',t:lowercase,skip:1"
SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:271441587,phase:2,deny,log,msg:'Basic OR',tag:'crowdsec-Basic OR',t:lowercase"`,
},
{
name: "OR AND mix",
@ -97,8 +97,9 @@ SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:2638639999,phase:2,deny,log,msg:'Basic
},
},
},
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:2720972114,phase:2,deny,log,msg:'Basic OR_or_0',t:lowercase,skip:1"
SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:2638639999,phase:2,deny,log,msg:'Basic OR_or_1',t:lowercase"`,
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:1714963250,phase:2,deny,log,msg:'OR AND mix',tag:'crowdsec-OR AND mix',t:lowercase,skip:1"
SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:1519945803,phase:2,deny,log,msg:'OR AND mix',tag:'crowdsec-OR AND mix',t:lowercase"
SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:1519945803,phase:2,deny,log,msg:'OR AND mix',tag:'crowdsec-OR AND mix',t:lowercase"`,
},
}

View file

@ -52,7 +52,7 @@ var bodyTypeMatch map[string]string = map[string]string{
func (m *ModsecurityRule) Build(rule *CustomRule, waapRuleName string) (string, []uint32, error) {
rules, err := m.buildRules(rule, waapRuleName, false, 0)
rules, err := m.buildRules(rule, waapRuleName, false, 0, 0)
if err != nil {
return "", nil, err
@ -62,11 +62,12 @@ func (m *ModsecurityRule) Build(rule *CustomRule, waapRuleName string) (string,
return strings.Join(rules, "\n"), m.ids, nil
}
func (m *ModsecurityRule) generateRuleID(rule *CustomRule, waapRuleName string) uint32 {
func (m *ModsecurityRule) generateRuleID(rule *CustomRule, waapRuleName string, depth int) uint32 {
h := fnv.New32a()
h.Write([]byte(waapRuleName))
h.Write([]byte(rule.Match.Type))
h.Write([]byte(rule.Match.Value))
h.Write([]byte(fmt.Sprintf("%d", depth)))
for _, zone := range rule.Zones {
h.Write([]byte(zone))
}
@ -78,14 +79,15 @@ func (m *ModsecurityRule) generateRuleID(rule *CustomRule, waapRuleName string)
return id
}
func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and bool, toSkip int) ([]string, error) {
func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and bool, toSkip int, depth int) ([]string, error) {
ret := make([]string, 0)
if rule.And != nil {
for c, andRule := range rule.And {
subName := fmt.Sprintf("%s_and_%d", waapRuleName, c)
depth++
//subName := fmt.Sprintf("%s_and_%d", waapRuleName, c)
lastRule := c == len(rule.And)-1 // || len(rule.Or) == 0
rules, err := m.buildRules(&andRule, subName, !lastRule, 0)
rules, err := m.buildRules(&andRule, waapRuleName, !lastRule, 0, depth)
if err != nil {
return nil, err
}
@ -95,9 +97,10 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and
if rule.Or != nil {
for c, orRule := range rule.Or {
subName := fmt.Sprintf("%s_or_%d", waapRuleName, c)
depth++
//subName := fmt.Sprintf("%s_or_%d", waapRuleName, c)
skip := len(rule.Or) - c - 1
rules, err := m.buildRules(&orRule, subName, false, skip)
rules, err := m.buildRules(&orRule, waapRuleName, false, skip, depth)
if err != nil {
return nil, err
}
@ -140,7 +143,7 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, waapRuleName string, and
}
//Should phase:2 be configurable?
r.WriteString(fmt.Sprintf(` "id:%d,phase:2,deny,log,msg:'%s'`, m.generateRuleID(rule, waapRuleName), waapRuleName))
r.WriteString(fmt.Sprintf(` "id:%d,phase:2,deny,log,msg:'%s',tag:'crowdsec-%s'`, m.generateRuleID(rule, waapRuleName, depth), waapRuleName, waapRuleName))
if rule.Transform != nil {
for _, transform := range rule.Transform {

View file

@ -34,10 +34,10 @@ func GetExprWAFOptions(ctx map[string]interface{}) []expr.Option {
func GetOnLoadEnv(w *WaapRuntimeConfig) map[string]interface{} {
//FIXME: use expr.Function instead of this
return map[string]interface{}{
"DisableInBandRuleByID": w.DisableInBandRuleByID,
"DisableOutBandRuleByID": w.DisableOutBandRuleByID,
"DisableInBandRuleByTag": w.DisableInBandRuleByTag,
"DisableOutBandRuleByTag": w.DisableOutBandRuleByTag,
"RemoveInBandRuleByID": w.DisableInBandRuleByID,
"RemoveOutBandRuleByID": w.DisableOutBandRuleByID,
"RemoveInBandRuleByTag": w.DisableInBandRuleByTag,
"RemoveOutBandRuleByTag": w.DisableOutBandRuleByTag,
}
}