Development record
The native secret patterns miss several prefix-anchored vendor tokens, which capture writes into the committed ledger
The native secret patterns miss several prefix-anchored vendor tokens, which capture writes into the committed ledger
Published as security advisory GHSA-jr36-r49j-cmj2; the advisory is the public account of this finding.
What
The native secret patterns (internal/adapter/scanner/patterns.go:169-350) cover GitHub, Anthropic, OpenAI, OpenRouter, generic sk-, AWS access key IDs, Slack xox*, Google AIza, Stripe, JWT and PEM. They have no pattern for several other prefix-anchored, fixed-shape vendor tokens: npm (npm_), GitLab personal access tokens (glpat-), Hugging Face (hf_), DigitalOcean (dop_v1_), HashiCorp Vault (hvs.), Shopify (shpat_), PyPI (pypi-), SendGrid (SG.) and Slack incoming-webhook URLs.
dcn-2608280000000002 scopes the always-on native set to prefix-anchored tokens and leaves labelled, delimited and high-entropy values to the opt-in gitleaks augmenter. These families are prefix-anchored, the class the native set says it covers. When gitleaks is not armed, abcd capture (and resolve and promote) writes them verbatim into the committed issue ledger, and the run reports nothing redacted for them, while internal/core/capture/redact.go says it sanitises prose bound for the committed ledger. The same detector serves decide, the outbound-text check and the launch release scan.
Reproduced by running abcd capture in a scratch repository with text holding these tokens: the record under .abcd/work/issues/open/ keeps every one verbatim; a ghp_ control in the same text is masked.
Labelled values (aws_secret_access_key = …, Authorization: Bearer …, user:pass@ URLs, AccountKey=) are outside this advisory: iss-96 recorded them as the opt-in adapter's reach.
Affected versions
Every released version up to and including 0.15.1. Patched versions will be set when the release carrying the fix is cut.
Would it exist without abcd?
Not on this route. A person can paste a token into any file, but here abcd takes the text, promises to redact it, and writes it into a committed tier. The redaction claim is abcd's, so abcd fixes it.
Fix
Add hard-fail, prefix-anchored patterns for the families above to the native set, each with runtime-assembled tests and a false-positive sweep of the tree. Detector change only; no repository behaviour changes.
Frontmatter
| id | iss-2610280103498613 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2610280103498613-private-report.md
open on GitHub ↗ · commit history ↗
mentions2
- dcn-26082800000000022026-08-28 — Transcript deep-secret coverage lands as an OPT-IN gitleaks adapter, off by default (iss-96). The native scanner stays the always-on default; a repo arms deeper coverage by dropping an enabled `.abcd/config/gitleaks.json`, whereupon `internal/adapter/gitleaks` shells out to a gitleaks binary (PATH or configured path) over the transcript and its findings AUGMENT native redaction through the same `scanner.Redact` discipline. This realises option (c) of the iss-96 grill (labelled+delimited+high-entropy reach the prefix-anchored native set misses) as the host-delegated/opt-in-adapter pattern (adr: LLM/CLI oracles are opt-in adapters), NOT an always-on entropy detector (option (a), rejected for its redaction false-positive cost on prose) and NOT a hard gitleaks dependency in the default build. Fail-closed, never a silent no-op: an armed-but-absent binary makes capture refuse the write with `gitleaks configured but not found`. Default-off invokes nothing — no lookup, no process, no cost — so the unopted path is byte-for-byte unchanged. iss-96's residue beyond (c)'s reach (bare no-keyname values, sub-entropy-floor tokens) stays open.
- iss-96Now that transcripts are captured automatically on every session end, the scanner's secret-pattern coverage becomes load-bearing in a way it was not when capture was a manual verb nobody ran. Verified by live test: the bundled patterns DO catch anchored tokens (AKIA... access key IDs, ghp_/gho_/sk-ant- style prefixes) and absolute home paths, but they do NOT catch unanchored high-entropy values — an AWS SECRET access key (the 40-char base64 value, no prefix), a bare password, or a generic API token with no recognisable prefix all pass through into the store verbatim. This is the standard prefix-matching limitation and is pre-existing, not a regression; the point is that the blast radius changed. Consider entropy-based detection or the opt-in gitleaks adapter for the transcript path specifically, where the input is unstructured prose rather than curated source.