Skip to content

Commit

Permalink
Merge pull request #560 from hashicorp/sensitive-value-masking
Browse files Browse the repository at this point in the history
Better masking of AWS secret access keys in HTTP request/response logs
  • Loading branch information
gdavison authored Jul 31, 2023
2 parents fbf29ba + d6948c4 commit 87bbc87
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 11 deletions.
50 changes: 45 additions & 5 deletions logging/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,58 @@ var UniqueIDRegex = regexp.MustCompile(`(A3T[A-Z0-9]` +

var SensitiveKeyRegex = regexp.MustCompile(`[A-Za-z0-9/+=]{16,}`)

const (
unmaskedFirst = 4
unmaskedLast = 4
)

func MaskAWSAccessKey(field string) string {
field = UniqueIDRegex.ReplaceAllStringFunc(field, func(s string) string {
return partialMaskString(s, 4, 4) //nolint:gomnd
return partialMaskString(s, unmaskedFirst, unmaskedLast)
})
return field
}

func MaskAWSSensitiveValues(field string) string {
field = MaskAWSAccessKey(field)

field = SensitiveKeyRegex.ReplaceAllStringFunc(field, func(s string) string {
return partialMaskString(s, 4, 4) //nolint:gomnd
})
field = MaskAWSSecretKeys(field)
return field
}

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

for i := 0; i < len; i++ {
b := in[i]
out[i] = b

if (b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z') || (b >= '0' && b <= '9') || b == '/' || b == '+' || b == '=' {
// base64 character.
base64Characters++
} else {
if base64Characters == secretKeyLen {
for j := (i - secretKeyLen) + unmaskedFirst; j < i-unmaskedLast; j++ {
out[j] = '*'
}
}

base64Characters = 0
}
}

if base64Characters == secretKeyLen {
for j := (len - secretKeyLen) + unmaskedFirst; j < len-unmaskedLast; j++ {
out[j] = '*'
}
}

return string(out)
}
44 changes: 38 additions & 6 deletions logging/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,55 @@ func TestMaskAWSSensitiveValues(t *testing.T) {

tests := map[string]testCase{
"mask_simple": {
input: "4skd4lTSLVBMG/asedterGLKSNMSAlsxiLGfjt=ssD",
expected: "4skd**********************************=ssD",
input: "MfP3tIG15gibzIx7CSbhSNkgD5sSV4k2tWXgN8U8",
expected: "MfP3********************************N8U8",
},
"mask_complex_json": {
input: `
{
"AWSSecretKey": "4skd4lTSLVBMG/asedterGLKSNMSAlsxiLGfjt=ssD",
"AWSSecretKey": "LEfH8nZmFN4BGIJnku6lkChHydRN5B/YlWCIjOte",
"BucketName": "test-bucket",
"AWSKeyId": "AIDACKCEVSQ6C2EXAMPLE",
}
`,
expected: `
{
"AWSSecretKey": "4skd**********************************=ssD",
"AWSSecretKey": "LEfH********************************jOte",
"BucketName": "test-bucket",
"AWSKeyId": "AIDA*************MPLE",
}
`,
},
"mask_multiple_json": {
input: `
{
"AWSSecretKey": "LEfH8nZmFN4BGIJnku6lkChHydRN5B/YlWCIjOte",
"BucketName": "test-bucket-1",
"AWSKeyId": "AIDACKCEVSQ6C2EXAMPLE",
},
{
"Key": "ABCDEFGH!JKLMNOPQRSTUVWXYZ012345678901234567890123456789",
},
{
"AWSSecretKey": "MfP3tIG15gibzIx7CSbhSNkgD5sSV4k2tWXgN8U8",
"BucketName": "test-bucket-2",
"AWSKeyId": "AKIA5PX2H2S3LHEXAMPLE",
}
`,
expected: `
{
"AWSSecretKey": "LEfH********************************jOte",
"BucketName": "test-bucket-1",
"AWSKeyId": "AIDA*************MPLE",
},
{
"Key": "ABCDEFGH!JKLMNOPQRSTUVWXYZ012345678901234567890123456789",
},
{
"AWSSecretKey": "MfP3********************************N8U8",
"BucketName": "test-bucket-2",
"AWSKeyId": "AKIA*************MPLE",
}
`,
},
"no_mask": {
Expand All @@ -42,12 +74,12 @@ func TestMaskAWSSensitiveValues(t *testing.T) {
},
"mask_xml": {
input: `
<AWSSecretKey>4skd4lTSLVBMG/asedterGLKSNMSAlsxiLGfjt=ssD</AWSSecretKey>
<AWSSecretKey>8/AiP0ofCD/YOAqXWrungQt/Y4BkTj1UOjZ0MqBs</AWSSecretKey>
<BucketName>test-bucket</BucketName>
<AWSKeyId>AIDACKCEVSQ6C2EXAMPLE</AWSKeyId>
`,
expected: `
<AWSSecretKey>4skd**********************************=ssD</AWSSecretKey>
<AWSSecretKey>8/Ai********************************MqBs</AWSSecretKey>
<BucketName>test-bucket</BucketName>
<AWSKeyId>AIDA*************MPLE</AWSKeyId>
`,
Expand Down

0 comments on commit 87bbc87

Please sign in to comment.