Skip to content
This repository was archived by the owner on Nov 2, 2023. It is now read-only.

Commit 897eb37

Browse files
author
Julio Guerra
authored
scubbing: fix the waf metadata scrubbing
Change the scrubbing function of the WAF metadata to sanitize substrings and not only the full string value.
2 parents 4f48c2e + 693342e commit 897eb37

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

internal/backend/api/api.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package api
66

77
import (
88
"encoding/json"
9+
"strings"
910
"time"
1011

1112
"github.com/sqreen/go-agent/internal/sqlib/sqsanitize"
@@ -451,12 +452,17 @@ func (i *WAFAttackInfo) Scrub(scrubber *sqsanitize.Scrubber, info sqsanitize.Inf
451452
redactedString := scrubber.RedactedValueMask()
452453
for e := range wafInfo {
453454
for f := range wafInfo[e].Filter {
454-
if info.Contains(wafInfo[e].Filter[f].ResolvedValue) {
455-
wafInfo[e].Filter[f].ResolvedValue = redactedString
456-
if wafInfo[e].Filter[f].MatchStatus != "" {
457-
wafInfo[e].Filter[f].MatchStatus = redactedString
455+
for v := range info {
456+
resolvedValue := wafInfo[e].Filter[f].ResolvedValue
457+
newStr := strings.ReplaceAll(resolvedValue, v, redactedString)
458+
if newStr != resolvedValue {
459+
// The string was changed
460+
wafInfo[e].Filter[f].ResolvedValue = newStr
461+
if wafInfo[e].Filter[f].MatchStatus != "" {
462+
wafInfo[e].Filter[f].MatchStatus = strings.ReplaceAll(wafInfo[e].Filter[f].MatchStatus, v, redactedString)
463+
}
464+
scrubbed = true
458465
}
459-
scrubbed = true
460466
}
461467
}
462468
}

internal/backend/api/json_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func TestCustomScrubber(t *testing.T) {
220220
OperatorValue: "trigger",
221221
BindingAccessor: "#.request_params",
222222
ResolvedValue: expectedMask,
223-
MatchStatus: expectedMask,
223+
MatchStatus: "forbidden",
224224
},
225225
},
226226
},

internal/sqlib/sqsanitize/sanitize.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ func (s *Scrubber) scrubMap(v reflect.Value, info Info) (scrubbed bool) {
236236
// When the current value is an interface value, we scrub its underlying
237237
// value.
238238
if hasInterfaceValueType {
239+
if val.IsNil() {
240+
continue
241+
}
239242
val = val.Elem()
240243
valT = val.Type()
241244
}
@@ -337,14 +340,6 @@ func (i Info) Add(value string) {
337340
i[value] = struct{}{}
338341
}
339342

340-
func (i Info) Contains(value string) bool {
341-
if len(i) == 0 {
342-
return false
343-
}
344-
_, exists := i[value]
345-
return exists
346-
}
347-
348343
func (i Info) Append(info Info) {
349344
if i == nil || len(info) == 0 {
350345
return

internal/sqlib/sqsanitize/sanitize_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,14 @@ func TestScrubber(t *testing.T) {
935935
},
936936
"e": 33,
937937
"passwd": []interface{}{"everything", randString},
938+
"g": nil,
939+
"h": (*string)(nil),
940+
"i": []interface{}{nil},
941+
"j": []interface{}{(*string)(nil)},
942+
"password": map[string]interface{}{
943+
"a": nil,
944+
"b": []interface{}{nil},
945+
},
938946
}
939947
},
940948
expected: expectedValues{
@@ -948,6 +956,14 @@ func TestScrubber(t *testing.T) {
948956
},
949957
"e": 33,
950958
"passwd": []interface{}{expectedMask, randString},
959+
"g": nil,
960+
"h": (*string)(nil),
961+
"i": []interface{}{nil},
962+
"j": []interface{}{(*string)(nil)},
963+
"password": map[string]interface{}{
964+
"a": nil,
965+
"b": []interface{}{nil},
966+
},
951967
},
952968
withKeyRE: map[string]interface{}{
953969
"apikey": expectedMask,
@@ -959,6 +975,14 @@ func TestScrubber(t *testing.T) {
959975
},
960976
"e": 33,
961977
"passwd": []interface{}{expectedMask, expectedMask},
978+
"g": nil,
979+
"h": (*string)(nil),
980+
"i": []interface{}{nil},
981+
"j": []interface{}{(*string)(nil)},
982+
"password": map[string]interface{}{
983+
"a": nil,
984+
"b": []interface{}{nil},
985+
},
962986
},
963987
withBothRE: map[string]interface{}{
964988
"apikey": expectedMask,
@@ -970,6 +994,14 @@ func TestScrubber(t *testing.T) {
970994
},
971995
"e": 33,
972996
"passwd": []interface{}{expectedMask, expectedMask},
997+
"g": nil,
998+
"h": (*string)(nil),
999+
"i": []interface{}{nil},
1000+
"j": []interface{}{(*string)(nil)},
1001+
"password": map[string]interface{}{
1002+
"a": nil,
1003+
"b": []interface{}{nil},
1004+
},
9731005
},
9741006
withBothDisabled: map[string]interface{}{
9751007
"apikey": randString,
@@ -981,6 +1013,14 @@ func TestScrubber(t *testing.T) {
9811013
},
9821014
"e": 33,
9831015
"passwd": []interface{}{"everything", randString},
1016+
"g": nil,
1017+
"h": (*string)(nil),
1018+
"i": []interface{}{nil},
1019+
"j": []interface{}{(*string)(nil)},
1020+
"password": map[string]interface{}{
1021+
"a": nil,
1022+
"b": []interface{}{nil},
1023+
},
9841024
},
9851025
},
9861026
},

0 commit comments

Comments
 (0)