2023-12-07 11:21:04 +00:00
package appsec_rule
import "testing"
func TestVPatchRuleString ( t * testing . T ) {
tests := [ ] struct {
name string
rule CustomRule
expected string
} {
2024-01-12 13:30:08 +00:00
{
name : "Collection count" ,
rule : CustomRule {
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "eq" , Value : "1" } ,
2024-01-12 13:30:08 +00:00
Transform : [ ] string { "count" } ,
} ,
expected : ` SecRule &ARGS_GET:foo "@eq 1" "id:853070236,phase:2,deny,log,msg:'Collection count',tag:'crowdsec-Collection count'" ` ,
} ,
2023-12-07 11:21:04 +00:00
{
name : "Base Rule" ,
rule : CustomRule {
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "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" ` ,
} ,
2024-01-12 09:11:13 +00:00
{
name : "One zone, multi var" ,
rule : CustomRule {
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" , "bar" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2024-01-12 09:11:13 +00:00
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" ` ,
} ,
2024-01-03 16:19:48 +00:00
{
name : "Base Rule #2" ,
rule : CustomRule {
Zones : [ ] string { "METHOD" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "startsWith" , Value : "toto" } ,
2024-01-03 16:19:48 +00:00
} ,
expected : ` SecRule REQUEST_METHOD "@beginsWith toto" "id:2759779019,phase:2,deny,log,msg:'Base Rule #2',tag:'crowdsec-Base Rule #2'" ` ,
} ,
{
name : "Base Negative Rule" ,
rule : CustomRule {
Zones : [ ] string { "METHOD" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "startsWith" , Value : "toto" , Not : true } ,
2024-01-03 16:19:48 +00:00
} ,
expected : ` SecRule REQUEST_METHOD "!@beginsWith toto" "id:3966251995,phase:2,deny,log,msg:'Base Negative Rule',tag:'crowdsec-Base Negative Rule'" ` ,
} ,
2023-12-07 11:21:04 +00:00
{
name : "Multiple Zones" ,
rule : CustomRule {
Zones : [ ] string { "ARGS" , "BODY_ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "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" ` ,
} ,
2024-01-12 09:11:13 +00:00
{
name : "Multiple Zones Multi Var" ,
rule : CustomRule {
Zones : [ ] string { "ARGS" , "BODY_ARGS" } ,
Variables : [ ] string { "foo" , "bar" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2024-01-12 09:11:13 +00:00
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" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2024-01-12 09:11:13 +00:00
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" ` ,
} ,
2023-12-07 11:21:04 +00:00
{
name : "Basic AND" ,
rule : CustomRule {
And : [ ] CustomRule {
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "lowercase" } ,
} ,
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "bar" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "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" ,
rule : CustomRule {
Or : [ ] CustomRule {
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "lowercase" } ,
} ,
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "bar" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "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" ,
rule : CustomRule {
And : [ ] CustomRule {
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "lowercase" } ,
Or : [ ] CustomRule {
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "foo" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "lowercase" } ,
} ,
{
Zones : [ ] string { "ARGS" } ,
Variables : [ ] string { "bar" } ,
2024-01-16 10:39:23 +00:00
Match : Match { Type : "regex" , Value : "[^a-zA-Z]" } ,
2023-12-07 11:21:04 +00:00
Transform : [ ] string { "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" ` ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
actual , _ , err := tt . rule . Convert ( ModsecurityRuleType , tt . name )
if err != nil {
t . Errorf ( "Error converting rule: %s" , err )
}
if actual != tt . expected {
t . Errorf ( "Expected:\n%s\nGot:\n%s" , tt . expected , actual )
}
} )
}
}