start to split and add outofband rules support
This commit is contained in:
parent
71a912857f
commit
b98e03d218
|
@ -30,6 +30,7 @@ type appsecRuleTest struct {
|
||||||
name string
|
name string
|
||||||
expected_load_ok bool
|
expected_load_ok bool
|
||||||
inband_rules []appsec_rule.CustomRule
|
inband_rules []appsec_rule.CustomRule
|
||||||
|
outofband_rules []appsec_rule.CustomRule
|
||||||
on_load []appsec.Hook
|
on_load []appsec.Hook
|
||||||
pre_eval []appsec.Hook
|
pre_eval []appsec.Hook
|
||||||
post_eval []appsec.Hook
|
post_eval []appsec.Hook
|
||||||
|
@ -38,63 +39,15 @@ type appsecRuleTest struct {
|
||||||
output_asserts func(events []types.Event, responses []appsec.AppsecTempResponse)
|
output_asserts func(events []types.Event, responses []appsec.AppsecTempResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppsec(t *testing.T) {
|
func TestAppsecPreEvalHooks(t *testing.T) {
|
||||||
|
/*
|
||||||
|
[x] basic working hook
|
||||||
|
[x] basic failing hook
|
||||||
|
[ ] test the "OnSuccess" feature
|
||||||
|
[ ] test multiple competing hooks
|
||||||
|
[ ] test the variety of helpers
|
||||||
|
*/
|
||||||
tests := []appsecRuleTest{
|
tests := []appsecRuleTest{
|
||||||
{
|
|
||||||
name: "Basic matching rule",
|
|
||||||
expected_load_ok: true,
|
|
||||||
inband_rules: []appsec_rule.CustomRule{
|
|
||||||
{
|
|
||||||
Name: "rule1",
|
|
||||||
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"}},
|
|
||||||
},
|
|
||||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
|
||||||
require.Equal(t, len(events), 2, "Expected 2 event")
|
|
||||||
require.Equal(t, events[0].Type, types.LOG, "Expected log event")
|
|
||||||
require.Equal(t, events[0].Appsec.HasInBandMatches, true, "Expected inband match")
|
|
||||||
require.Equal(t, len(events[0].Appsec.MatchedRules), 1, "Expected 1 rule match")
|
|
||||||
require.Equal(t, events[0].Appsec.MatchedRules[0]["msg"], "rule1", " rule name")
|
|
||||||
require.Equal(t, events[1].Type, types.APPSEC, "Expected appsec event")
|
|
||||||
require.Equal(t, len(responses), 1, "Expected 1 response")
|
|
||||||
require.Equal(t, responses[0].InBandInterrupt, true, "Expected deny action")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Basic non-matching rule",
|
|
||||||
expected_load_ok: true,
|
|
||||||
inband_rules: []appsec_rule.CustomRule{
|
|
||||||
{
|
|
||||||
Name: "rule1",
|
|
||||||
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{"tutu"}},
|
|
||||||
},
|
|
||||||
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
|
||||||
require.Equal(t, 0, len(events))
|
|
||||||
require.Equal(t, 1, len(responses))
|
|
||||||
require.Equal(t, responses[0].InBandInterrupt, false)
|
|
||||||
require.Equal(t, responses[0].OutOfBandInterrupt, false)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Basic on_load hook to disable rule",
|
name: "Basic on_load hook to disable rule",
|
||||||
expected_load_ok: true,
|
expected_load_ok: true,
|
||||||
|
@ -163,6 +116,71 @@ func TestAppsec(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func TestAppsecRuleMatches(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []appsecRuleTest{
|
||||||
|
{
|
||||||
|
name: "Basic matching rule",
|
||||||
|
expected_load_ok: true,
|
||||||
|
inband_rules: []appsec_rule.CustomRule{
|
||||||
|
{
|
||||||
|
Name: "rule1",
|
||||||
|
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"}},
|
||||||
|
},
|
||||||
|
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||||
|
require.Equal(t, len(events), 2, "Expected 2 event")
|
||||||
|
require.Equal(t, events[0].Type, types.LOG, "Expected log event")
|
||||||
|
require.Equal(t, events[0].Appsec.HasInBandMatches, true, "Expected inband match")
|
||||||
|
require.Equal(t, len(events[0].Appsec.MatchedRules), 1, "Expected 1 rule match")
|
||||||
|
require.Equal(t, events[0].Appsec.MatchedRules[0]["msg"], "rule1", " rule name")
|
||||||
|
require.Equal(t, events[1].Type, types.APPSEC, "Expected appsec event")
|
||||||
|
require.Equal(t, len(responses), 1, "Expected 1 response")
|
||||||
|
require.Equal(t, responses[0].InBandInterrupt, true, "Expected deny action")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Basic non-matching rule",
|
||||||
|
expected_load_ok: true,
|
||||||
|
inband_rules: []appsec_rule.CustomRule{
|
||||||
|
{
|
||||||
|
Name: "rule1",
|
||||||
|
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{"tutu"}},
|
||||||
|
},
|
||||||
|
output_asserts: func(events []types.Event, responses []appsec.AppsecTempResponse) {
|
||||||
|
require.Equal(t, 0, len(events))
|
||||||
|
require.Equal(t, 1, len(responses))
|
||||||
|
require.Equal(t, responses[0].InBandInterrupt, false)
|
||||||
|
require.Equal(t, responses[0].OutOfBandInterrupt, false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
loadAppSecEngine(test, t)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
||||||
if testing.Verbose() {
|
if testing.Verbose() {
|
||||||
|
@ -171,6 +189,7 @@ func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
||||||
log.SetLevel(log.WarnLevel)
|
log.SetLevel(log.WarnLevel)
|
||||||
}
|
}
|
||||||
inbandRules := []string{}
|
inbandRules := []string{}
|
||||||
|
outofbandRules := []string{}
|
||||||
InChan := make(chan appsec.ParsedRequest)
|
InChan := make(chan appsec.ParsedRequest)
|
||||||
OutChan := make(chan types.Event)
|
OutChan := make(chan types.Event)
|
||||||
|
|
||||||
|
@ -185,6 +204,13 @@ func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
||||||
inbandRules = append(inbandRules, strRule)
|
inbandRules = append(inbandRules, strRule)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
for ridx, rule := range test.outofband_rules {
|
||||||
|
strRule, _, err := rule.Convert(appsec_rule.ModsecurityRuleType, rule.Name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed compilation of rule %d/%d of %s : %s", ridx, len(test.outofband_rules), test.name, err)
|
||||||
|
}
|
||||||
|
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}
|
||||||
AppsecRuntime, err := appsecCfg.Build()
|
AppsecRuntime, err := appsecCfg.Build()
|
||||||
|
@ -192,6 +218,7 @@ func loadAppSecEngine(test appsecRuleTest, t *testing.T) {
|
||||||
t.Fatalf("unable to build appsec runtime : %s", err)
|
t.Fatalf("unable to build appsec runtime : %s", err)
|
||||||
}
|
}
|
||||||
AppsecRuntime.InBandRules = []appsec.AppsecCollection{{Rules: inbandRules}}
|
AppsecRuntime.InBandRules = []appsec.AppsecCollection{{Rules: inbandRules}}
|
||||||
|
AppsecRuntime.OutOfBandRules = []appsec.AppsecCollection{{Rules: outofbandRules}}
|
||||||
appsecRunnerUUID := uuid.New().String()
|
appsecRunnerUUID := uuid.New().String()
|
||||||
//we copy AppsecRutime for each runner
|
//we copy AppsecRutime for each runner
|
||||||
wrt := *AppsecRuntime
|
wrt := *AppsecRuntime
|
||||||
|
|
Loading…
Reference in a new issue