From b64cefe02915741a4d7efe851fe7087e83b2ac66 Mon Sep 17 00:00:00 2001 From: Jordan Tunstill Date: Wed, 10 Jun 2026 08:31:35 -0700 Subject: [PATCH] set redacted value to last 4 characters of secret, to match how the secret type admin interface displays it (#5027) --- .../contentfulpersonalaccesstoken.go | 1 + .../contentfulpersonalaccesstoken_test.go | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken.go b/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken.go index 8926787a0..1c0884e89 100644 --- a/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken.go +++ b/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken.go @@ -41,6 +41,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result s1 := detectors.Result{ DetectorType: detector_typepb.DetectorType_ContentfulPersonalAccessToken, Raw: []byte(keyRes), + Redacted: "..." + keyRes[len(keyRes)-4:], SecretParts: map[string]string{"key": keyRes}, } diff --git a/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken_test.go b/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken_test.go index 52c2b55b5..1ff0d4e6e 100644 --- a/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken_test.go +++ b/pkg/detectors/contentfulpersonalaccesstoken/contentfulpersonalaccesstoken_test.go @@ -2,6 +2,7 @@ package contentfulpersonalaccesstoken import ( "context" + "fmt" "testing" "github.com/google/go-cmp/cmp" @@ -10,6 +11,8 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) +const validToken = "CFPAT-fakeabcdefghijklmnopqrstuvwxyz0123456789xyz" + var ( validPattern = ` # Configuration File: config.yaml @@ -29,6 +32,12 @@ var ( # - Remember to rotate the secret every 90 days. # - The above credentials should only be used in a secure environment. ` + + validPatternWithToken = fmt.Sprintf(` + api: + auth_type: "Bearer" + contentful_access_token: "%s" + `, validToken) ) func TestContentfulPersonalAccessToken_Pattern(t *testing.T) { @@ -45,6 +54,11 @@ func TestContentfulPersonalAccessToken_Pattern(t *testing.T) { input: validPattern, want: nil, }, + { + name: "valid pattern with token - found", + input: validPatternWithToken, + want: []string{validToken}, + }, } for _, test := range tests { @@ -89,3 +103,22 @@ func TestContentfulPersonalAccessToken_Pattern(t *testing.T) { }) } } + +func TestContentfulPersonalAccessToken_SecretRedacted(t *testing.T) { + d := Scanner{} + + results, err := d.FromData(context.Background(), false, []byte(validPatternWithToken)) + if err != nil { + t.Errorf("error = %v", err) + return + } + + if len(results) == 0 { + t.Fatal("did not receive result") + } + + want := "..." + validToken[len(validToken)-4:] + if results[0].Redacted != want { + t.Errorf("expected redacted secret to be '%s', got '%s'", want, results[0].Redacted) + } +}