add some tests
This commit is contained in:
parent
32954a6e45
commit
c3474671f6
1 changed files with 122 additions and 35 deletions
|
@ -1,6 +1,7 @@
|
|||
package appsecacquisition
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -21,16 +22,19 @@ Missing tests (wip):
|
|||
*/
|
||||
|
||||
type appsecRuleTest struct {
|
||||
name string
|
||||
expected_load_ok bool
|
||||
inband_rules []appsec_rule.CustomRule
|
||||
outofband_rules []appsec_rule.CustomRule
|
||||
on_load []appsec.Hook
|
||||
pre_eval []appsec.Hook
|
||||
post_eval []appsec.Hook
|
||||
on_match []appsec.Hook
|
||||
input_request appsec.ParsedRequest
|
||||
output_asserts func(events []types.Event, responses []appsec.AppsecTempResponse)
|
||||
name string
|
||||
expected_load_ok bool
|
||||
inband_rules []appsec_rule.CustomRule
|
||||
outofband_rules []appsec_rule.CustomRule
|
||||
on_load []appsec.Hook
|
||||
pre_eval []appsec.Hook
|
||||
post_eval []appsec.Hook
|
||||
on_match []appsec.Hook
|
||||
BouncerBlockedHTTPCode int
|
||||
UserBlockedHTTPCode int
|
||||
DefaultRemediation string
|
||||
input_request appsec.ParsedRequest
|
||||
output_asserts func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int)
|
||||
}
|
||||
|
||||
func TestAppsecOnMatchHooks(t *testing.T) {
|
||||
|
@ -53,7 +57,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
@ -85,7 +89,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
@ -96,7 +100,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "on_match: change action to another standard one (log)",
|
||||
name: "on_match: change action to a non standard one (log)",
|
||||
expected_load_ok: true,
|
||||
inband_rules: []appsec_rule.CustomRule{
|
||||
{
|
||||
|
@ -116,7 +120,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
@ -145,7 +149,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
@ -154,7 +158,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "on_match: change action to another standard one (deny/ban/block)",
|
||||
name: "on_match: change action to another standard one (ban)",
|
||||
expected_load_ok: true,
|
||||
inband_rules: []appsec_rule.CustomRule{
|
||||
{
|
||||
|
@ -166,7 +170,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
},
|
||||
},
|
||||
on_match: []appsec.Hook{
|
||||
{Filter: "IsInBand == true", Apply: []string{"SetRemediation('deny')"}},
|
||||
{Filter: "IsInBand == true", Apply: []string{"SetRemediation('ban')"}},
|
||||
},
|
||||
input_request: appsec.ParsedRequest{
|
||||
RemoteAddr: "1.2.3.4",
|
||||
|
@ -174,7 +178,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, responses, 1)
|
||||
//note: SetAction normalizes deny, ban and block to ban
|
||||
require.Equal(t, "ban", responses[0].Action)
|
||||
|
@ -201,7 +205,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, responses, 1)
|
||||
//note: SetAction normalizes deny, ban and block to ban
|
||||
require.Equal(t, "captcha", responses[0].Action)
|
||||
|
@ -228,7 +232,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
@ -257,7 +261,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, events, 1)
|
||||
require.Equal(t, types.LOG, events[0].Type)
|
||||
require.Len(t, responses, 1)
|
||||
|
@ -285,7 +289,7 @@ func TestAppsecOnMatchHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, events, 1)
|
||||
require.Equal(t, types.APPSEC, events[0].Type)
|
||||
require.Len(t, responses, 1)
|
||||
|
@ -330,7 +334,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Empty(t, events)
|
||||
require.Len(t, responses, 1)
|
||||
require.False(t, responses[0].InBandInterrupt)
|
||||
|
@ -358,7 +362,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
||||
|
@ -393,7 +397,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Empty(t, events)
|
||||
require.Len(t, responses, 1)
|
||||
require.False(t, responses[0].InBandInterrupt)
|
||||
|
@ -421,7 +425,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Empty(t, events)
|
||||
require.Len(t, responses, 1)
|
||||
require.False(t, responses[0].InBandInterrupt)
|
||||
|
@ -449,7 +453,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Empty(t, events)
|
||||
require.Len(t, responses, 1)
|
||||
require.False(t, responses[0].InBandInterrupt)
|
||||
|
@ -474,7 +478,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, events, 1)
|
||||
require.Equal(t, types.LOG, events[0].Type)
|
||||
require.True(t, events[0].Appsec.HasOutBandMatches)
|
||||
|
@ -508,7 +512,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, events, 2)
|
||||
require.Len(t, responses, 1)
|
||||
require.Equal(t, "foobar", responses[0].Action)
|
||||
|
@ -535,7 +539,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, events, 2)
|
||||
require.Len(t, responses, 1)
|
||||
require.Equal(t, "foobar", responses[0].Action)
|
||||
|
@ -562,7 +566,7 @@ func TestAppsecPreEvalHooks(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Len(t, events, 2)
|
||||
require.Len(t, responses, 1)
|
||||
require.Equal(t, "foobar", responses[0].Action)
|
||||
|
@ -603,7 +607,7 @@ func TestAppsecRuleMatches(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
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)
|
||||
|
||||
|
@ -634,13 +638,94 @@ func TestAppsecRuleMatches(t *testing.T) {
|
|||
URI: "/urllll",
|
||||
Args: url.Values{"foo": []string{"tutu"}},
|
||||
},
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
require.Empty(t, events)
|
||||
require.Len(t, responses, 1)
|
||||
require.False(t, responses[0].InBandInterrupt)
|
||||
require.False(t, responses[0].OutOfBandInterrupt)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default remediation to allow",
|
||||
expected_load_ok: true,
|
||||
inband_rules: []appsec_rule.CustomRule{
|
||||
{
|
||||
Name: "rule42",
|
||||
Zones: []string{"ARGS"},
|
||||
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",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
DefaultRemediation: "allow",
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
spew.Dump(responses)
|
||||
require.Equal(t, "allow", responses[0].Action)
|
||||
require.Equal(t, http.StatusOK, statusCode)
|
||||
require.Equal(t, "allow", appsecResponse.Action)
|
||||
require.Equal(t, http.StatusOK, appsecResponse.HTTPStatus)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default remediation to captcha",
|
||||
expected_load_ok: true,
|
||||
inband_rules: []appsec_rule.CustomRule{
|
||||
{
|
||||
Name: "rule42",
|
||||
Zones: []string{"ARGS"},
|
||||
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",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
DefaultRemediation: "captcha",
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
spew.Dump(responses)
|
||||
require.Equal(t, "captcha", responses[0].Action)
|
||||
require.Equal(t, http.StatusForbidden, statusCode)
|
||||
require.Equal(t, "captcha", appsecResponse.Action)
|
||||
require.Equal(t, http.StatusForbidden, appsecResponse.HTTPStatus)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no default remediation / custom user HTTP code",
|
||||
expected_load_ok: true,
|
||||
inband_rules: []appsec_rule.CustomRule{
|
||||
{
|
||||
Name: "rule42",
|
||||
Zones: []string{"ARGS"},
|
||||
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",
|
||||
Args: url.Values{"foo": []string{"toto"}},
|
||||
},
|
||||
UserBlockedHTTPCode: 418,
|
||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse, appsecResponse appsec.BodyResponse, statusCode int) {
|
||||
spew.Dump(responses)
|
||||
require.Equal(t, "ban", responses[0].Action)
|
||||
require.Equal(t, http.StatusForbidden, statusCode)
|
||||
require.Equal(t, "ban", appsecResponse.Action)
|
||||
require.Equal(t, http.StatusTeapot, appsecResponse.HTTPStatus)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -680,7 +765,7 @@ func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
|||
outofbandRules = append(outofbandRules, strRule)
|
||||
}
|
||||
|
||||
appsecCfg := appsec.AppsecConfig{Logger: logger, OnLoad: test.on_load, PreEval: test.pre_eval, PostEval: test.post_eval, OnMatch: test.on_match}
|
||||
appsecCfg := appsec.AppsecConfig{Logger: logger, OnLoad: test.on_load, PreEval: test.pre_eval, PostEval: test.post_eval, OnMatch: test.on_match, BouncerBlockedHTTPCode: test.BouncerBlockedHTTPCode, UserBlockedHTTPCode: test.UserBlockedHTTPCode, DefaultRemediation: test.DefaultRemediation}
|
||||
AppsecRuntime, err := appsecCfg.Build()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to build appsec runtime : %s", err)
|
||||
|
@ -726,8 +811,10 @@ func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
|||
|
||||
runner.handleRequest(&input)
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
http_status, appsecResponse := AppsecRuntime.GenerateResponse(OutputResponses[0], logger)
|
||||
log.Infof("events : %s", spew.Sdump(OutputEvents))
|
||||
log.Infof("responses : %s", spew.Sdump(OutputResponses))
|
||||
test.output_asserts(OutputEvents, OutputResponses)
|
||||
test.output_asserts(OutputEvents, OutputResponses, appsecResponse, http_status)
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue