Skip to content

Commit

Permalink
Fix secret value showing up in logs
Browse files Browse the repository at this point in the history
Signed-off-by: Matheus Pimenta <[email protected]>
  • Loading branch information
matheuscscp committed Feb 24, 2025
1 parent 444b8d2 commit a7e4927
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
36 changes: 33 additions & 3 deletions internal/decryptor/decryptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (d *Decryptor) SopsDecryptWithFormat(data []byte, inputFormat, outputFormat
}

cipher := aes.NewCipher()
mac, err := tree.Decrypt(metadataKey, cipher)
mac, err := safeDecrypt(tree.Decrypt(metadataKey, cipher))
if err != nil {
return nil, sopsUserErr("error decrypting sops tree", err)
}
Expand All @@ -302,11 +302,11 @@ func (d *Decryptor) SopsDecryptWithFormat(data []byte, inputFormat, outputFormat
// the one that was stored in the document. If they match,
// integrity was preserved
// Ref: github.com/getsops/sops/v3/decrypt/decrypt.go
originalMac, err := cipher.Decrypt(
originalMac, err := safeDecrypt(cipher.Decrypt(
tree.Metadata.MessageAuthenticationCode,
metadataKey,
tree.Metadata.LastModified.Format(time.RFC3339),
)
))
if err != nil {
return nil, sopsUserErr("failed to verify sops data integrity", err)
}
Expand Down Expand Up @@ -811,3 +811,33 @@ func detectFormatFromMarkerBytes(b []byte) formats.Format {
}
return unsupportedFormat
}

// safeDecrypt redacts secret values in sops error messages.
func safeDecrypt[T any](mac T, err error) (T, error) {
const (
prefix = "Input string "
suffix = " does not match sops' data format"
)

if err == nil {
return mac, nil
}

var buf strings.Builder

e := err.Error()
prefIdx := strings.Index(e, prefix)
suffIdx := strings.Index(e, suffix)

var zero T
if prefIdx == -1 || suffIdx == -1 {
return zero, err
}

buf.WriteString(e[:prefIdx])
buf.WriteString(prefix)
buf.WriteString("<redacted>")
buf.WriteString(suffix)

return zero, errors.New(buf.String())
}
52 changes: 52 additions & 0 deletions internal/decryptor/decryptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"context"
"encoding/base64"
"errors"
"fmt"
"io/fs"
"os"
Expand Down Expand Up @@ -1598,3 +1599,54 @@ func TestDecryptor_detectFormatFromMarkerBytes(t *testing.T) {
})
}
}

func TestSafeDecrypt(t *testing.T) {
for _, tt := range []struct {
name string
mac string
err string
expectedMac string
expectedErr string
}{
{
name: "no error",
mac: "some mac",
expectedMac: "some mac",
},
{
name: "only prefix",
err: "Input string was not in a correct format",
expectedErr: "Input string was not in a correct format",
},
{
name: "only suffix",
err: "The value does not match sops' data format",
expectedErr: "The value does not match sops' data format",
},
{
name: "redacted value",
err: "Input string 1234567897 does not match sops' data format",
expectedErr: "Input string <redacted> does not match sops' data format",
},
} {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

var err error
if tt.err != "" {
err = errors.New(tt.err)
}

mac, err := safeDecrypt(tt.mac, err)

g.Expect(mac).To(Equal(tt.expectedMac))

if tt.expectedErr == "" {
g.Expect(err).To(Not(HaveOccurred()))
} else {
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(Equal(tt.expectedErr))
}
})
}
}

0 comments on commit a7e4927

Please sign in to comment.