github.com/crowdsecurity/crowdsec@v1.6.1/pkg/appsec/appsec_rule/modsec_rule_test.go (about)

     1  package appsec_rule
     2  
     3  import "testing"
     4  
     5  func TestVPatchRuleString(t *testing.T) {
     6  	tests := []struct {
     7  		name     string
     8  		rule     CustomRule
     9  		expected string
    10  	}{
    11  		{
    12  			name: "Collection count",
    13  			rule: CustomRule{
    14  				Zones:     []string{"ARGS"},
    15  				Variables: []string{"foo"},
    16  				Match:     Match{Type: "eq", Value: "1"},
    17  				Transform: []string{"count"},
    18  			},
    19  			expected: `SecRule &ARGS_GET:foo "@eq 1" "id:853070236,phase:2,deny,log,msg:'Collection count',tag:'crowdsec-Collection count'"`,
    20  		},
    21  		{
    22  			name: "Base Rule",
    23  			rule: CustomRule{
    24  				Zones:     []string{"ARGS"},
    25  				Variables: []string{"foo"},
    26  				Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
    27  				Transform: []string{"lowercase"},
    28  			},
    29  			expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:2203944045,phase:2,deny,log,msg:'Base Rule',tag:'crowdsec-Base Rule',t:lowercase"`,
    30  		},
    31  		{
    32  			name: "One zone, multi var",
    33  			rule: CustomRule{
    34  				Zones:     []string{"ARGS"},
    35  				Variables: []string{"foo", "bar"},
    36  				Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
    37  				Transform: []string{"lowercase"},
    38  			},
    39  			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"`,
    40  		},
    41  		{
    42  			name: "Base Rule #2",
    43  			rule: CustomRule{
    44  				Zones: []string{"METHOD"},
    45  				Match: Match{Type: "startsWith", Value: "toto"},
    46  			},
    47  			expected: `SecRule REQUEST_METHOD "@beginsWith toto" "id:2759779019,phase:2,deny,log,msg:'Base Rule #2',tag:'crowdsec-Base Rule #2'"`,
    48  		},
    49  		{
    50  			name: "Base Negative Rule",
    51  			rule: CustomRule{
    52  				Zones: []string{"METHOD"},
    53  				Match: Match{Type: "startsWith", Value: "toto", Not: true},
    54  			},
    55  			expected: `SecRule REQUEST_METHOD "!@beginsWith toto" "id:3966251995,phase:2,deny,log,msg:'Base Negative Rule',tag:'crowdsec-Base Negative Rule'"`,
    56  		},
    57  		{
    58  			name: "Multiple Zones",
    59  			rule: CustomRule{
    60  				Zones:     []string{"ARGS", "BODY_ARGS"},
    61  				Variables: []string{"foo"},
    62  				Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
    63  				Transform: []string{"lowercase"},
    64  			},
    65  			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"`,
    66  		},
    67  		{
    68  			name: "Multiple Zones Multi Var",
    69  			rule: CustomRule{
    70  				Zones:     []string{"ARGS", "BODY_ARGS"},
    71  				Variables: []string{"foo", "bar"},
    72  				Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
    73  				Transform: []string{"lowercase"},
    74  			},
    75  			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"`,
    76  		},
    77  		{
    78  			name: "Multiple Zones No Vars",
    79  			rule: CustomRule{
    80  				Zones:     []string{"ARGS", "BODY_ARGS"},
    81  				Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
    82  				Transform: []string{"lowercase"},
    83  			},
    84  			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"`,
    85  		},
    86  		{
    87  			name: "Basic AND",
    88  			rule: CustomRule{
    89  				And: []CustomRule{
    90  					{
    91  
    92  						Zones:     []string{"ARGS"},
    93  						Variables: []string{"foo"},
    94  						Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
    95  						Transform: []string{"lowercase"},
    96  					},
    97  					{
    98  						Zones:     []string{"ARGS"},
    99  						Variables: []string{"bar"},
   100  						Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
   101  						Transform: []string{"lowercase"},
   102  					},
   103  				},
   104  			},
   105  			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"
   106  SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:1865217529,phase:2,deny,log,msg:'Basic AND',tag:'crowdsec-Basic AND',t:lowercase"`,
   107  		},
   108  		{
   109  			name: "Basic OR",
   110  			rule: CustomRule{
   111  				Or: []CustomRule{
   112  					{
   113  						Zones:     []string{"ARGS"},
   114  						Variables: []string{"foo"},
   115  						Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
   116  						Transform: []string{"lowercase"},
   117  					},
   118  					{
   119  						Zones:     []string{"ARGS"},
   120  						Variables: []string{"bar"},
   121  						Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
   122  						Transform: []string{"lowercase"},
   123  					},
   124  				},
   125  			},
   126  			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"
   127  SecRule ARGS_GET:bar "@rx [^a-zA-Z]" "id:271441587,phase:2,deny,log,msg:'Basic OR',tag:'crowdsec-Basic OR',t:lowercase"`,
   128  		},
   129  		{
   130  			name: "OR AND mix",
   131  			rule: CustomRule{
   132  				And: []CustomRule{
   133  					{
   134  						Zones:     []string{"ARGS"},
   135  						Variables: []string{"foo"},
   136  						Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
   137  						Transform: []string{"lowercase"},
   138  						Or: []CustomRule{
   139  							{
   140  								Zones:     []string{"ARGS"},
   141  								Variables: []string{"foo"},
   142  								Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
   143  								Transform: []string{"lowercase"},
   144  							},
   145  							{
   146  								Zones:     []string{"ARGS"},
   147  								Variables: []string{"bar"},
   148  								Match:     Match{Type: "regex", Value: "[^a-zA-Z]"},
   149  								Transform: []string{"lowercase"},
   150  							},
   151  						},
   152  					},
   153  				},
   154  			},
   155  			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"
   156  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"
   157  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"`,
   158  		},
   159  	}
   160  
   161  	for _, tt := range tests {
   162  		t.Run(tt.name, func(t *testing.T) {
   163  			actual, _, err := tt.rule.Convert(ModsecurityRuleType, tt.name)
   164  
   165  			if err != nil {
   166  				t.Errorf("Error converting rule: %s", err)
   167  			}
   168  			if actual != tt.expected {
   169  				t.Errorf("Expected:\n%s\nGot:\n%s", tt.expected, actual)
   170  			}
   171  		})
   172  	}
   173  }