Skip to content

Commit 009b014

Browse files
authored
Make header name checking case insensitive (#119)
1 parent 0a0f632 commit 009b014

File tree

5 files changed

+287
-14
lines changed

5 files changed

+287
-14
lines changed

data_masks/redaction_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ func TestRedaction(t *testing.T) {
7373
inputFile: "003-witness.pb.txt",
7474
expectedFile: "003-expected-redact-by-name-and-by-name-regexp.pb.txt",
7575
},
76+
77+
"agent config: redact by name and by regexp": {
78+
agentConfig: optionals.Some(&kgxapi.FieldRedactionConfig{
79+
FieldNameRegexps: []*regexp.Regexp{regexp.MustCompile("^value for key[12]$")},
80+
}),
81+
inputFile: "004-witness.pb.txt",
82+
expectedFile: "004-expected-redact-by-value-regexp.pb.txt",
83+
},
7684
}
7785

7886
for testName, testCase := range testCases {

data_masks/redactor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func (s *redactSensitiveInfoVisitor) isSensitiveString(v string) bool {
220220
return true
221221
}
222222
}
223-
return false
223+
return s.redactionOptions.userConfig.redactStringRegex(v)
224224
}
225225

226226
// Determines whether the given Primitive has a sensitive value.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# api_spec.Witness proto
2+
3+
method: {
4+
id: {
5+
api_type: HTTP_REST
6+
}
7+
args: {
8+
key: "gwLpCbDEj9U="
9+
value: {
10+
primitive: {
11+
string_value: {
12+
value: "curl/8.11.1"
13+
}
14+
}
15+
meta: {
16+
http: {
17+
header: {
18+
key: "User-Agent"
19+
}
20+
}
21+
}
22+
}
23+
}
24+
args: {
25+
key: "h9izWKXxdQE="
26+
value: {
27+
primitive: {
28+
string_value: {
29+
value: "*/*"
30+
}
31+
}
32+
meta: {
33+
http: {
34+
header: {
35+
key: "Accept"
36+
}
37+
}
38+
}
39+
}
40+
}
41+
responses: {
42+
key: "bogus hash"
43+
value: {
44+
struct: {
45+
fields: {
46+
key: "api-key"
47+
value: {
48+
primitive: {
49+
string_value: {
50+
value: "*REDACTED*"
51+
}
52+
}
53+
}
54+
}
55+
fields: {
56+
key: "by-value-regexp"
57+
value: {
58+
primitive: {
59+
string_value: {
60+
value: "*REDACTED*"
61+
}
62+
}
63+
}
64+
}
65+
fields: {
66+
key: "by-name"
67+
value: {
68+
primitive: {
69+
string_value: {
70+
value: "redact by name"
71+
}
72+
}
73+
}
74+
}
75+
fields: {
76+
key: "by-name-regexp"
77+
value: {
78+
primitive: {
79+
string_value: {
80+
value: "redact by name regexp"
81+
}
82+
}
83+
}
84+
}
85+
fields: {
86+
key: "key1"
87+
value: {
88+
primitive: {
89+
string_value: {
90+
value: "*REDACTED*"
91+
}
92+
}
93+
}
94+
}
95+
fields: {
96+
key: "key2"
97+
value: {
98+
primitive: {
99+
string_value: {
100+
value: "*REDACTED*"
101+
}
102+
}
103+
}
104+
}
105+
fields: {
106+
key: "never"
107+
value: {
108+
primitive: {
109+
string_value: {
110+
value: "never redacted"
111+
}
112+
}
113+
}
114+
}
115+
}
116+
}
117+
}
118+
meta: {
119+
http: {
120+
method: "GET"
121+
path_template: "/"
122+
host: "localhost:8080"
123+
}
124+
}
125+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# api_spec.Witness proto
2+
3+
method: {
4+
id: {
5+
api_type: HTTP_REST
6+
}
7+
args: {
8+
key: "gwLpCbDEj9U="
9+
value: {
10+
primitive: {
11+
string_value: {
12+
value: "curl/8.11.1"
13+
}
14+
}
15+
meta: {
16+
http: {
17+
header: {
18+
key: "User-Agent"
19+
}
20+
}
21+
}
22+
}
23+
}
24+
args: {
25+
key: "h9izWKXxdQE="
26+
value: {
27+
primitive: {
28+
string_value: {
29+
value: "*/*"
30+
}
31+
}
32+
meta: {
33+
http: {
34+
header: {
35+
key: "Accept"
36+
}
37+
}
38+
}
39+
}
40+
}
41+
responses: {
42+
key: "bogus hash"
43+
value: {
44+
struct: {
45+
fields: {
46+
key: "api-key"
47+
value: {
48+
primitive: {
49+
string_value: {
50+
value: "always redacted"
51+
}
52+
}
53+
}
54+
}
55+
fields: {
56+
key: "by-value-regexp"
57+
value: {
58+
primitive: {
59+
string_value: {
60+
value: "PMAK-123456789012345678901234"
61+
}
62+
}
63+
}
64+
}
65+
fields: {
66+
key: "by-name"
67+
value: {
68+
primitive: {
69+
string_value: {
70+
value: "redact by name"
71+
}
72+
}
73+
}
74+
}
75+
fields: {
76+
key: "by-name-regexp"
77+
value: {
78+
primitive: {
79+
string_value: {
80+
value: "redact by name regexp"
81+
}
82+
}
83+
}
84+
}
85+
fields: {
86+
key: "key1"
87+
value: {
88+
primitive: {
89+
string_value: {
90+
value: "value for key1"
91+
}
92+
}
93+
}
94+
}
95+
fields: {
96+
key: "key2"
97+
value: {
98+
primitive: {
99+
string_value: {
100+
value: "value for key2"
101+
}
102+
}
103+
}
104+
}
105+
fields: {
106+
key: "never"
107+
value: {
108+
primitive: {
109+
string_value: {
110+
value: "never redacted"
111+
}
112+
}
113+
}
114+
}
115+
}
116+
}
117+
}
118+
meta: {
119+
http: {
120+
method: "GET"
121+
path_template: "/"
122+
host: "localhost:8080"
123+
}
124+
}
125+
}

data_masks/user_redaction_config.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package data_masks
33
import (
44
"regexp"
55
go_slices "slices"
6+
"strings"
67
"sync"
78

89
"github.com/akitasoftware/akita-libs/api_schema"
@@ -12,8 +13,8 @@ import (
1213
)
1314

1415
type userRedactionConfig struct {
15-
fieldNames sets.Set[string]
16-
fieldNameRegexps []*regexp.Regexp
16+
fieldNames sets.Set[string]
17+
stringRegexps []*regexp.Regexp
1718

1819
// Protects this instance.
1920
mu sync.RWMutex
@@ -23,22 +24,31 @@ type userRedactionConfig struct {
2324
func newUserRedactionConfig(
2425
agentConfig *api_schema.ServiceAgentConfig,
2526
) *userRedactionConfig {
27+
fieldNames := make([]string, 0, len(agentConfig.FieldsToRedact.FieldNames))
28+
for _, fieldName := range agentConfig.FieldsToRedact.FieldNames {
29+
fieldNames = append(fieldNames, strings.ToLower(fieldName))
30+
}
31+
2632
return &userRedactionConfig{
27-
fieldNames: sets.NewSet(agentConfig.FieldsToRedact.FieldNames...),
28-
fieldNameRegexps: agentConfig.FieldsToRedact.FieldNameRegexps,
33+
fieldNames: sets.NewSet(fieldNames...),
34+
stringRegexps: agentConfig.FieldsToRedact.FieldNameRegexps,
2935
}
3036
}
3137

3238
// Determines whether fields with the given name should be redacted according to
3339
// this configuration.
3440
func (c *userRedactionConfig) redactFieldsNamed(fieldName string) bool {
35-
if c.fieldNames.Contains(fieldName) {
41+
if c.fieldNames.Contains(strings.ToLower(fieldName)) {
3642
return true
3743
}
3844

45+
return c.redactStringRegex(fieldName)
46+
}
47+
48+
func (c *userRedactionConfig) redactStringRegex(v string) bool {
3949
// Determine whether to redact based on user-specified regular expressions.
40-
for _, re := range c.fieldNameRegexps {
41-
if re.MatchString(fieldName) {
50+
for _, re := range c.stringRegexps {
51+
if re.MatchString(v) {
4252
return true
4353
}
4454
}
@@ -50,13 +60,18 @@ func (c *userRedactionConfig) redactFieldsNamed(fieldName string) bool {
5060
func (c *userRedactionConfig) update(
5161
agentConfig *api_schema.ServiceAgentConfig,
5262
) {
53-
newFieldNames := sets.NewSet(agentConfig.FieldsToRedact.FieldNames...)
63+
fieldNames := make([]string, 0, len(agentConfig.FieldsToRedact.FieldNames))
64+
for _, fieldName := range agentConfig.FieldsToRedact.FieldNames {
65+
fieldNames = append(fieldNames, strings.ToLower(fieldName))
66+
}
67+
68+
newFieldNames := sets.NewSet(fieldNames...)
5469

5570
// Filter out empty regular expressions from the incoming configuration. These
5671
// match everything, which is almost certainly not what is intended. If the
5772
// user wants to match everything, they can use a different regular
5873
// expression, such as `$`.
59-
newFieldNameRegexps := slices.Filter(
74+
newStringRegexps := slices.Filter(
6075
agentConfig.FieldsToRedact.FieldNameRegexps,
6176
func(re *regexp.Regexp) bool {
6277
return len(re.String()) > 0
@@ -73,8 +88,8 @@ func (c *userRedactionConfig) update(
7388
}
7489

7590
if !go_slices.EqualFunc(
76-
c.fieldNameRegexps,
77-
newFieldNameRegexps,
91+
c.stringRegexps,
92+
newStringRegexps,
7893
func(r1, r2 *regexp.Regexp) bool {
7994
return r1.String() == r2.String()
8095
},
@@ -96,10 +111,10 @@ func (c *userRedactionConfig) update(
96111
c.mu.Unlock()
97112
printer.Debugln("Updated user redaction config")
98113
printer.Debugf("field names: %v\n", newFieldNames.AsSlice())
99-
printer.Debugf("field name regexps: %v\n", newFieldNameRegexps)
114+
printer.Debugf("string regexps: %v\n", newStringRegexps)
100115
}()
101116
c.fieldNames = newFieldNames
102-
c.fieldNameRegexps = newFieldNameRegexps
117+
c.stringRegexps = newStringRegexps
103118
}
104119

105120
func (c *userRedactionConfig) RLock() {

0 commit comments

Comments
 (0)