From d78a8e094d7ea7a6333fffd88bad2ad0b2d9794d Mon Sep 17 00:00:00 2001 From: sai k Date: Wed, 17 Jun 2026 23:25:33 +0530 Subject: [PATCH] fix: use exact key matching in report sanitize to prevent false redaction Problem ------- The `sanitize()` function in `report.go` protects sensitive values in `pack report` output by redacting quoted strings on matching TOML field lines. However, it uses `strings.HasPrefix` to detect field names, which causes false-positive matches on any key that merely *starts with* one of the sensitive names. For example, the sensitive field list includes "image" and "name". A future config key such as "image-mirror = ..." or "name-prefix = ..." would unintentionally have its value redacted, because "image-mirror" has the prefix "image". Additionally, the redaction regex (`"(.*?)"`) is compiled fresh inside `sanitize()` on every line, even though it is a constant expression. Repeated compilation is wasteful when `pack report` processes a config file with many lines. Fix --- - Replace the `strings.HasPrefix` check with a field-anchored regex that requires the match to be `` followed immediately by optional whitespace and `=`. This ensures only the exact TOML key is matched, not keys that happen to share a prefix. - Pre-compile both the value-redaction regex and the field-match helper at package initialisation time so they are compiled exactly once. The new pattern for each sensitive field is: `^\s*=` This is consistent with TOML syntax, where `key = value` and `key=value` are both valid. Signed-off-by: saiashok103@gmail.com --- internal/commands/report.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/internal/commands/report.go b/internal/commands/report.go index 64cc24d4a6..22c883c2eb 100644 --- a/internal/commands/report.go +++ b/internal/commands/report.go @@ -18,6 +18,11 @@ import ( "github.com/buildpacks/pack/pkg/logging" ) +// quotedValueRe matches any double-quoted string in a TOML line. +// Pre-compiled once at package initialisation to avoid repeated allocation +// inside the hot sanitize() path. +var quotedValueRe = regexp.MustCompile(`"(.*?)"`) + func Report(logger logging.Logger, version, cfgPath string) *cobra.Command { var explicit bool @@ -83,9 +88,16 @@ Config: }) } +// sanitize redacts the quoted values of sensitive TOML fields in a config +// line so that they are not leaked by `pack report`. +// +// The match is intentionally exact: a TOML key is considered sensitive only +// when the trimmed line begins with `` followed immediately by +// optional whitespace and `=`. This prevents false-positive redaction of +// keys that merely share a prefix with a sensitive field (e.g. an +// "image-mirror" key would previously be redacted because it starts with +// the sensitive field "image"). func sanitize(line string) string { - re := regexp.MustCompile(`"(.*?)"`) - redactedString := `"[REDACTED]"` sensitiveFields := []string{ "default-builder-image", "image", @@ -94,8 +106,12 @@ func sanitize(line string) string { "url", } for _, field := range sensitiveFields { - if strings.HasPrefix(strings.TrimSpace(line), field) { - return re.ReplaceAllString(line, redactedString) + // Build a pattern that matches the exact TOML key: + // ^\s*\s*= + // This ensures "image" does not match "image-mirror" etc. + keyRe := regexp.MustCompile(`(?i)^\s*` + regexp.QuoteMeta(field) + `\s*=`) + if keyRe.MatchString(line) { + return quotedValueRe.ReplaceAllString(line, `"[REDACTED]"`) } }