Skip to content

Commit 751df9f

Browse files
committed
Reduces allocations when masking sensitive values
1 parent 755a7f9 commit 751df9f

File tree

3 files changed

+24
-36
lines changed

3 files changed

+24
-36
lines changed

logging/aws.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package logging
55

66
import (
77
"regexp"
8+
"unsafe"
89
)
910

1011
// IAM Unique ID prefixes from
@@ -24,48 +25,45 @@ var UniqueIDRegex = regexp.MustCompile(`(A3T[A-Z0-9]` +
2425
`|ASIA` + // STS temporary access key
2526
`)[A-Z0-9]{16,}`)
2627

27-
var SensitiveKeyRegex = regexp.MustCompile(`[A-Za-z0-9/+=]{16,}`)
28-
2928
const (
3029
unmaskedFirst = 4
3130
unmaskedLast = 4
3231
)
3332

34-
func MaskAWSAccessKey(field string) string {
35-
field = UniqueIDRegex.ReplaceAllStringFunc(field, func(s string) string {
33+
func MaskAWSAccessKey(field []byte) []byte {
34+
field = UniqueIDRegex.ReplaceAllFunc(field, func(s []byte) []byte {
3635
return partialMaskString(s, unmaskedFirst, unmaskedLast)
3736
})
3837
return field
3938
}
4039

4140
func MaskAWSSensitiveValues(field string) string {
42-
field = MaskAWSAccessKey(field)
43-
field = MaskAWSSecretKeys(field)
44-
return field
41+
b := unsafe.Slice(unsafe.StringData(field), len(field))
42+
b = MaskAWSAccessKey(b)
43+
MaskAWSSecretKeys(b)
44+
return unsafe.String(unsafe.SliceData(b), len(b))
4545
}
4646

4747
// MaskAWSSecretKeys masks likely AWS secret access keys in the input.
4848
// See https://aws.amazon.com/blogs/security/a-safer-way-to-distribute-aws-credentials-to-ec2/:
4949
// "Find me 40-character, base-64 strings that don’t have any base 64 characters immediately before or after".
50-
func MaskAWSSecretKeys(in string) string {
50+
func MaskAWSSecretKeys(in []byte) {
5151
const (
5252
secretKeyLen = 40
5353
)
5454
len := len(in)
55-
out := make([]byte, len)
5655
base64Characters := 0
5756

5857
for i := 0; i < len; i++ {
5958
b := in[i]
60-
out[i] = b
6159

6260
if (b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z') || (b >= '0' && b <= '9') || b == '/' || b == '+' || b == '=' {
6361
// base64 character.
6462
base64Characters++
6563
} else {
6664
if base64Characters == secretKeyLen {
6765
for j := (i - secretKeyLen) + unmaskedFirst; j < i-unmaskedLast; j++ {
68-
out[j] = '*'
66+
in[j] = '*'
6967
}
7068
}
7169

@@ -75,9 +73,7 @@ func MaskAWSSecretKeys(in string) string {
7573

7674
if base64Characters == secretKeyLen {
7775
for j := (len - secretKeyLen) + unmaskedFirst; j < len-unmaskedLast; j++ {
78-
out[j] = '*'
76+
in[j] = '*'
7977
}
8078
}
81-
82-
return string(out)
8379
}

logging/aws_test.go

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

66
import (
77
"testing"
8+
"unsafe"
89
)
910

1011
func TestMaskAWSSensitiveValues(t *testing.T) {
@@ -101,42 +102,38 @@ func TestMaskAWSSensitiveValues(t *testing.T) {
101102
}
102103

103104
func BenchmarkMaskAWSAccessKey(b *testing.B) {
104-
var s string
105105
b.ReportAllocs()
106106
for n := 0; n < b.N; n++ {
107-
s = MaskAWSAccessKey(`
107+
MaskAWSAccessKey([]byte(`
108108
{
109109
"AWSSecretKey": "LEfH8nZmFN4BGIJnku6lkChHydRN5B/YlWCIjOte",
110110
"BucketName": "test-bucket",
111111
"AWSKeyId": "AIDACKCEVSQ6C2EXAMPLE",
112112
}
113-
`)
113+
`))
114114
}
115-
dump = s
116115
}
117116

118117
func BenchmarkPartialMaskString(b *testing.B) {
119-
var s string
118+
var s []byte
120119
b.ReportAllocs()
121120
for n := 0; n < b.N; n++ {
122-
s = partialMaskString("AIDACKCEVSQ6C2EXAMPLE", 4, 4)
121+
s = partialMaskString([]byte("AIDACKCEVSQ6C2EXAMPLE"), 4, 4)
123122
}
124-
dump = s
123+
dump = unsafe.String(unsafe.SliceData(s), len(s))
125124
}
126125

127126
func BenchmarkMaskAWSSecretKeys(b *testing.B) {
128-
var s string
129127
b.ReportAllocs()
130128
for n := 0; n < b.N; n++ {
131-
s = MaskAWSSecretKeys(`
129+
MaskAWSSecretKeys([]byte(`
132130
{
133131
"AWSSecretKey": "LEfH8nZmFN4BGIJnku6lkChHydRN5B/YlWCIjOte",
134132
"BucketName": "test-bucket",
135133
"AWSKeyId": "AIDACKCEVSQ6C2EXAMPLE",
136134
}
137-
`)
135+
`))
138136
}
139-
dump = s
140137
}
141138

142139
func BenchmarkMaskAWSSensitiveValues(b *testing.B) {

logging/mask.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,13 @@
33

44
package logging
55

6-
import (
7-
"strings"
8-
)
9-
10-
func partialMaskString(s string, first, last int) string {
6+
func partialMaskString(s []byte, first, last int) []byte {
117
l := len(s)
12-
result := strings.Builder{}
13-
result.Grow(l)
14-
result.WriteString(s[0:first])
8+
result := make([]byte, 0, l)
9+
result = append(result, s[0:first]...)
1510
for i := 0; i < l-first-last; i++ {
16-
result.WriteByte('*')
11+
result = append(result, '*')
1712
}
18-
result.WriteString(s[l-last:])
19-
return result.String()
13+
result = append(result, s[l-last:]...)
14+
return result
2015
}

0 commit comments

Comments
 (0)