mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 18:00:54 -10:00
* redaction: catch compound secret keys + non-bearer auth schemes; stop scanner over-redaction Hardens the secret-redaction last line of defense after an audit of internal/redaction + internal/secrets. 1. Compound secret keys are now redacted. IsSensitiveKey was exact-match only, so db_password, session_secret, stripe_secret_key, auth_token, csrf_token, ssh_private_key, backup_api_key, etc. passed through in cleartext. A new keyLooksSensitive applies conservative structural heuristics (secret / password / passphrase / credential / apikey segments; a singular trailing "_token"; api_key / private_key pairs). Critically, the agent's token-COUNT fields (max_tokens, prompt_tokens, token_count) and ordinary *_key fields (primary_key, public_key, cache_key) are deliberately NOT redacted. 2. Authorization headers with non-bearer/basic schemes were leaking. The header pattern now also covers token, apikey, digest, negotiate, oauth, and aws4-hmac-sha256. 3. The secrets scanner over-redacted ordinary text: its prefixed patterns (sk-, gh*, AIza, AKIA, xox, github_pat, jwt) lacked the word boundaries that internal/redaction already uses, so kebab-case words like "task-management-and-coordination" matched as a fake key. Added \b anchors. Design note: a free-text "key: value" colon pattern was prototyped but dropped -- it mangled "file.go:line: message" output (a filename's "secret" segment looked like a sensitive key), the same over-redaction class fix #3 addresses. The structured paths (RedactValue for maps/structs, plus assign/JSON/query forms in RedactString) are covered; free-text colon-form remains out of scope. Tests: compound-key + token-count-safety matrix, auth-scheme redaction, the file:line guard, and scanner boundary positives/negatives. * redaction: redact the full auth-header value for multi-part schemes The broadened header pattern captured only the first token after the scheme, so parameterized schemes (Digest "…, response=…", AWS4-HMAC-SHA256 "…, Signature=…") left the actual secret param visible. Redact the entire value to end of line; the scheme name is kept. Adds tests with realistic Digest + AWS SigV4 headers. Addresses review feedback.
39 lines
1.3 KiB
Go
39 lines
1.3 KiB
Go
package secrets
|
|
|
|
import "testing"
|
|
|
|
// Kebab-case words must NOT be redacted: "sk-" inside "task"/"ask"/"risk"/etc.
|
|
// is not an openai_key. This is the over-redaction the \b anchors fix.
|
|
func TestScan_NoOverRedactionOnKebabWords(t *testing.T) {
|
|
clean := []string{
|
|
"see task-management-and-coordination-plan for the roadmap",
|
|
"we should ask-the-user-about-this-before-proceeding now",
|
|
"the risk-assessment-and-mitigation-strategy-doc is ready",
|
|
"disk-usage-monitoring-and-alerting-subsystem looks good",
|
|
"desk-booking-and-reservation-management-flow updated",
|
|
}
|
|
for _, c := range clean {
|
|
red, f := Redact(c)
|
|
if len(f) != 0 || red != c {
|
|
t.Errorf("over-redacted %q -> %q (findings=%d)", c, red, len(f))
|
|
}
|
|
}
|
|
}
|
|
|
|
// Real secrets preceded by a delimiter (space, =, :, quote, start) still match —
|
|
// the \b is satisfied by all of those, so the fix loses no real coverage.
|
|
func TestScan_RealSecretsStillCaught(t *testing.T) {
|
|
cases := []string{
|
|
"export OPENAI_API_KEY=sk-proj-abcdefghijklmnopqrstuvwx",
|
|
`token: "sk-abcdefghijklmnopqrstuvwxyz"`,
|
|
"key is sk-svcacct-abcdefghijklmnopqrstuvwx at the end",
|
|
"github_pat_11ABCDEFG0abcdefghijklmnopqrst",
|
|
"creds AKIAIOSFODNN7EXAMPLE here",
|
|
}
|
|
for _, c := range cases {
|
|
if _, f := Redact(c); len(f) == 0 {
|
|
t.Errorf("real secret NOT caught in %q", c)
|
|
}
|
|
}
|
|
}
|