Skip to content

Commit

Permalink
appsec: add files and cookies related zones (#2956)
Browse files Browse the repository at this point in the history
  • Loading branch information
blotus authored May 17, 2024
1 parent 1a4ac9d commit 20e44cd
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 12 deletions.
128 changes: 128 additions & 0 deletions pkg/acquisition/modules/appsec/appsec_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,134 @@ func TestAppsecRuleMatches(t *testing.T) {
require.Equal(t, appsec.AllowRemediation, appsecResponse.Action)
},
},
{
name: "Basic matching in cookies",
expected_load_ok: true,
inband_rules: []appsec_rule.CustomRule{
{
Name: "rule1",
Zones: []string{"COOKIES"},
Variables: []string{"foo"},
Match: appsec_rule.Match{Type: "regex", Value: "^toto"},
Transform: []string{"lowercase"},
},
},
input_request: appsec.ParsedRequest{
RemoteAddr: "1.2.3.4",
Method: "GET",
URI: "/urllll",
Headers: http.Header{"Cookie": []string{"foo=toto"}},
},
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
require.Len(t, events, 2)
require.Equal(t, types.APPSEC, events[0].Type)

require.Equal(t, types.LOG, events[1].Type)
require.True(t, events[1].Appsec.HasInBandMatches)
require.Len(t, events[1].Appsec.MatchedRules, 1)
require.Equal(t, "rule1", events[1].Appsec.MatchedRules[0]["msg"])

require.Len(t, responses, 1)
require.True(t, responses[0].InBandInterrupt)
},
},
{
name: "Basic matching in all cookies",
expected_load_ok: true,
inband_rules: []appsec_rule.CustomRule{
{
Name: "rule1",
Zones: []string{"COOKIES"},
Match: appsec_rule.Match{Type: "regex", Value: "^tutu"},
Transform: []string{"lowercase"},
},
},
input_request: appsec.ParsedRequest{
RemoteAddr: "1.2.3.4",
Method: "GET",
URI: "/urllll",
Headers: http.Header{"Cookie": []string{"foo=toto; bar=tutu"}},
},
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
require.Len(t, events, 2)
require.Equal(t, types.APPSEC, events[0].Type)

require.Equal(t, types.LOG, events[1].Type)
require.True(t, events[1].Appsec.HasInBandMatches)
require.Len(t, events[1].Appsec.MatchedRules, 1)
require.Equal(t, "rule1", events[1].Appsec.MatchedRules[0]["msg"])

require.Len(t, responses, 1)
require.True(t, responses[0].InBandInterrupt)
},
},
{
name: "Basic matching in cookie name",
expected_load_ok: true,
inband_rules: []appsec_rule.CustomRule{
{
Name: "rule1",
Zones: []string{"COOKIES_NAMES"},
Match: appsec_rule.Match{Type: "regex", Value: "^tutu"},
Transform: []string{"lowercase"},
},
},
input_request: appsec.ParsedRequest{
RemoteAddr: "1.2.3.4",
Method: "GET",
URI: "/urllll",
Headers: http.Header{"Cookie": []string{"bar=tutu; tututata=toto"}},
},
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
require.Len(t, events, 2)
require.Equal(t, types.APPSEC, events[0].Type)

require.Equal(t, types.LOG, events[1].Type)
require.True(t, events[1].Appsec.HasInBandMatches)
require.Len(t, events[1].Appsec.MatchedRules, 1)
require.Equal(t, "rule1", events[1].Appsec.MatchedRules[0]["msg"])

require.Len(t, responses, 1)
require.True(t, responses[0].InBandInterrupt)
},
},
{
name: "Basic matching in multipart file name",
expected_load_ok: true,
inband_rules: []appsec_rule.CustomRule{
{
Name: "rule1",
Zones: []string{"FILES"},
Match: appsec_rule.Match{Type: "regex", Value: "\\.php$"},
Transform: []string{"lowercase"},
},
},
input_request: appsec.ParsedRequest{
RemoteAddr: "1.2.3.4",
Method: "GET",
URI: "/urllll",
Headers: http.Header{"Content-Type": []string{"multipart/form-data; boundary=boundary"}},
Body: []byte(`
--boundary
Content-Disposition: form-data; name="foo"; filename="bar.php"
Content-Type: application/octet-stream
toto
--boundary--`),
},
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
require.Len(t, events, 2)
require.Equal(t, types.APPSEC, events[0].Type)

require.Equal(t, types.LOG, events[1].Type)
require.True(t, events[1].Appsec.HasInBandMatches)
require.Len(t, events[1].Appsec.MatchedRules, 1)
require.Equal(t, "rule1", events[1].Appsec.MatchedRules[0]["msg"])

require.Len(t, responses, 1)
require.True(t, responses[0].InBandInterrupt)
},
},
}

for _, test := range tests {
Expand Down
29 changes: 17 additions & 12 deletions pkg/appsec/appsec_rule/modsecurity.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,23 @@ type ModsecurityRule struct {
}

var zonesMap map[string]string = map[string]string{
"ARGS": "ARGS_GET",
"ARGS_NAMES": "ARGS_GET_NAMES",
"BODY_ARGS": "ARGS_POST",
"BODY_ARGS_NAMES": "ARGS_POST_NAMES",
"HEADERS_NAMES": "REQUEST_HEADERS_NAMES",
"HEADERS": "REQUEST_HEADERS",
"METHOD": "REQUEST_METHOD",
"PROTOCOL": "REQUEST_PROTOCOL",
"URI": "REQUEST_FILENAME",
"URI_FULL": "REQUEST_URI",
"RAW_BODY": "REQUEST_BODY",
"FILENAMES": "FILES",
"ARGS": "ARGS_GET",
"ARGS_NAMES": "ARGS_GET_NAMES",
"BODY_ARGS": "ARGS_POST",
"BODY_ARGS_NAMES": "ARGS_POST_NAMES",
"COOKIES": "REQUEST_COOKIES",
"COOKIES_NAMES": "REQUEST_COOKIES_NAMES",
"FILES": "FILES",
"FILES_NAMES": "FILES_NAMES",
"FILES_TOTAL_SIZE": "FILES_COMBINED_SIZE",
"HEADERS_NAMES": "REQUEST_HEADERS_NAMES",
"HEADERS": "REQUEST_HEADERS",
"METHOD": "REQUEST_METHOD",
"PROTOCOL": "REQUEST_PROTOCOL",
"URI": "REQUEST_FILENAME",
"URI_FULL": "REQUEST_URI",
"RAW_BODY": "REQUEST_BODY",
"FILENAMES": "FILES",
}

var transformMap map[string]string = map[string]string{
Expand Down

0 comments on commit 20e44cd

Please sign in to comment.