From 8f88b8daebf6e8a00a05e4056d2e4b03b0193593 Mon Sep 17 00:00:00 2001 From: Eliott Bouhana Date: Wed, 18 Sep 2024 21:05:34 +0200 Subject: [PATCH] fix multiple bugs: * After recieving the order to stop appsec via RC we did not reset the ruleset to the default one * some code in http listeners where deduplicated for RASP SSRF making SSRF RASP span tags not working * its 'exclusions' but its 'exclusion_data' without an 's' Signed-off-by: Eliott Bouhana --- internal/appsec/appsec.go | 4 ++++ internal/appsec/config/config.go | 2 +- internal/appsec/config/rules_manager.go | 4 ++-- internal/appsec/listener/httpsec/http.go | 4 +--- internal/appsec/remoteconfig.go | 2 +- internal/appsec/remoteconfig_test.go | 14 +++++++------- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/internal/appsec/appsec.go b/internal/appsec/appsec.go index ae68d0d668..469a671cb0 100644 --- a/internal/appsec/appsec.go +++ b/internal/appsec/appsec.go @@ -199,6 +199,10 @@ func (a *appsec) stop() { a.wafHandle.Close() a.wafHandle = nil } + + // Reset rules edits received from the remote configuration + a.cfg.RulesManager, _ = config.NewRulesManager(nil) + // TODO: block until no more requests are using dyngo operations a.limiter.Stop() diff --git a/internal/appsec/config/config.go b/internal/appsec/config/config.go index e2a0b7736a..e2b8cef8cd 100644 --- a/internal/appsec/config/config.go +++ b/internal/appsec/config/config.go @@ -105,7 +105,7 @@ func NewConfig() (*Config, error) { return nil, err } - r, err := NewRulesManeger(rules) + r, err := NewRulesManager(rules) if err != nil { return nil, err } diff --git a/internal/appsec/config/rules_manager.go b/internal/appsec/config/rules_manager.go index 76e68c1430..e4e003eda1 100644 --- a/internal/appsec/config/rules_manager.go +++ b/internal/appsec/config/rules_manager.go @@ -68,10 +68,10 @@ func (f *RulesFragment) clone() (clone RulesFragment) { return } -// NewRulesManeger initializes and returns a new RulesManager using the provided rules. +// NewRulesManager initializes and returns a new RulesManager using the provided rules. // If no rules are provided (nil), the default rules are used instead. // If the provided rules are invalid, an error is returned -func NewRulesManeger(rules []byte) (*RulesManager, error) { +func NewRulesManager(rules []byte) (*RulesManager, error) { var f RulesFragment if rules == nil { f = DefaultRulesFragment() diff --git a/internal/appsec/listener/httpsec/http.go b/internal/appsec/listener/httpsec/http.go index c458931336..bb05947504 100644 --- a/internal/appsec/listener/httpsec/http.go +++ b/internal/appsec/listener/httpsec/http.go @@ -114,9 +114,7 @@ func (l *wafEventListener) onEvent(op *types.Operation, args types.HandlerOperat } if SSRFAddressesPresent(l.addresses) { - dyngo.On(op, shared.MakeWAFRunListener(&op.SecurityEventsHolder, wafCtx, l.limiter, func(args types.RoundTripOperationArgs) waf.RunAddressData { - return waf.RunAddressData{Ephemeral: map[string]any{ServerIoNetURLAddr: args.URL}} - })) + RegisterRoundTripperListener(op, &op.SecurityEventsHolder, wafCtx, l.limiter) } if ossec.OSAddressesPresent(l.addresses) { diff --git a/internal/appsec/remoteconfig.go b/internal/appsec/remoteconfig.go index c5485a92d1..bff6517c32 100644 --- a/internal/appsec/remoteconfig.go +++ b/internal/appsec/remoteconfig.go @@ -288,7 +288,7 @@ func mergeRulesData(u remoteconfig.ProductUpdate) (config.RulesFragment, map[str continue } - if exclusionData, ok := parsedUpdate["exclusions_data"]; ok { + if exclusionData, ok := parsedUpdate["exclusion_data"]; ok { mergeUpdateEntry(mergedExclusionData, exclusionData) } diff --git a/internal/appsec/remoteconfig_test.go b/internal/appsec/remoteconfig_test.go index f7208f1c8c..56273cfd22 100644 --- a/internal/appsec/remoteconfig_test.go +++ b/internal/appsec/remoteconfig_test.go @@ -192,7 +192,7 @@ func TestMergeRulesData(t *testing.T) { { name: "single-exclusions-value", update: map[string][]byte{ - "some/path": []byte(`{"exclusions_data":[{"id":"test","type":"data_with_expiration","data":[{"expiration":3494138481,"value":"user1"}]}]}`), + "some/path": []byte(`{"exclusion_data":[{"id":"test","type":"data_with_expiration","data":[{"expiration":3494138481,"value":"user1"}]}]}`), }, expected: config.RulesFragment{ExclusionData: []config.DataEntry{{ID: "test", Type: "data_with_expiration", Data: []rc.ASMDataRuleDataEntry{ {Expiration: 3494138481, Value: "user1"}, @@ -202,7 +202,7 @@ func TestMergeRulesData(t *testing.T) { { name: "multiple-exclusions-values", update: map[string][]byte{ - "some/path": []byte(`{"exclusions_data":[{"id":"test","type":"data_with_expiration","data":[{"expiration":3494138481,"value":"user1"},{"expiration":3494138441,"value":"user2"}]}]}`), + "some/path": []byte(`{"exclusion_data":[{"id":"test","type":"data_with_expiration","data":[{"expiration":3494138481,"value":"user1"},{"expiration":3494138441,"value":"user2"}]}]}`), }, expected: config.RulesFragment{ExclusionData: []config.DataEntry{{ID: "test", Type: "data_with_expiration", Data: []rc.ASMDataRuleDataEntry{ {Expiration: 3494138481, Value: "user1"}, @@ -213,7 +213,7 @@ func TestMergeRulesData(t *testing.T) { { name: "multiple-exclusions-entries", update: map[string][]byte{ - "some/path": []byte(`{"exclusions_data":[{"id":"test1","type":"data_with_expiration","data":[{"expiration":3494138444,"value":"user3"}]},{"id":"test2","type":"data_with_expiration","data":[{"expiration":3495138481,"value":"user4"}]}]}`), + "some/path": []byte(`{"exclusion_data":[{"id":"test1","type":"data_with_expiration","data":[{"expiration":3494138444,"value":"user3"}]},{"id":"test2","type":"data_with_expiration","data":[{"expiration":3495138481,"value":"user4"}]}]}`), }, expected: config.RulesFragment{ExclusionData: []config.DataEntry{ {ID: "test1", Type: "data_with_expiration", Data: []rc.ASMDataRuleDataEntry{ @@ -227,8 +227,8 @@ func TestMergeRulesData(t *testing.T) { { name: "merging-exclusions-entries", update: map[string][]byte{ - "some/path/1": []byte(`{"exclusions_data":[{"id":"test1","type":"data_with_expiration","data":[{"expiration":3494138444,"value":"user3"}]},{"id":"test2","type":"data_with_expiration","data":[{"expiration":3495138481,"value":"user4"}]}]}`), - "some/path/2": []byte(`{"exclusions_data":[{"id":"test1","type":"data_with_expiration","data":[{"expiration":3494138445,"value":"user3"}]},{"id":"test2","type":"data_with_expiration","data":[{"expiration":0,"value":"user5"}]}]}`), + "some/path/1": []byte(`{"exclusion_data":[{"id":"test1","type":"data_with_expiration","data":[{"expiration":3494138444,"value":"user3"}]},{"id":"test2","type":"data_with_expiration","data":[{"expiration":3495138481,"value":"user4"}]}]}`), + "some/path/2": []byte(`{"exclusion_data":[{"id":"test1","type":"data_with_expiration","data":[{"expiration":3494138445,"value":"user3"}]},{"id":"test2","type":"data_with_expiration","data":[{"expiration":0,"value":"user5"}]}]}`), }, expected: config.RulesFragment{ExclusionData: []config.DataEntry{ {ID: "test1", Type: "data_with_expiration", Data: []rc.ASMDataRuleDataEntry{ @@ -509,7 +509,7 @@ type testRulesOverrideEntry struct { func TestOnRCUpdate(t *testing.T) { - BaseRuleset, err := config.NewRulesManeger(nil) + BaseRuleset, err := config.NewRulesManager(nil) require.NoError(t, err) BaseRuleset.Compile() @@ -723,7 +723,7 @@ func TestOnRCUpdate(t *testing.T) { } func TestOnRCUpdateStatuses(t *testing.T) { - invalidRuleset, err := config.NewRulesManeger([]byte(`{"version": "2.2", "metadata": {"rules_version": "1.4.2"}, "rules": [{"id": "id","name":"name","tags":{},"conditions":[],"transformers":[],"on_match":[]}]}`)) + invalidRuleset, err := config.NewRulesManager([]byte(`{"version": "2.2", "metadata": {"rules_version": "1.4.2"}, "rules": [{"id": "id","name":"name","tags":{},"conditions":[],"transformers":[],"on_match":[]}]}`)) require.NoError(t, err) invalidRules := invalidRuleset.Base overrides := config.RulesFragment{