Development record
GHSA-fg9r-3f8g-89m6: the gitleaks adapter executes an attacker-controlled binary from a committed relative path. resolveBinary accepts a relative cfg.Path from the committed .abcd/config/gitleaks.json, validates it only with os.Stat (symlinks follow), resolves it against the working directory, and the runner executes it under a #nosec G204 waiver; the LookPath fallback also honours inherited PATH (CWE-426). Any SessionStart drain or history capture/drain in a hostile checkout runs the attacker's binary with the victim's privileges.
issueresolvedcriticaliss-2608291807456485
GHSA-fg9r-3f8g-89m6: the gitleaks adapter executes an attacker-controlled binary from a committed relative path. resolveBinary accepts a relative cfg.Path from the committed .abcd/config/gitleaks.json, validates it only with os.Stat (symlinks follow), resolves it against the working directory, and the runner executes it under a #nosec G204 waiver; the LookPath fallback also honours inherited PATH (CWE-426). Any SessionStart drain or history capture/drain in a hostile checkout runs the attacker's binary with the victim's privileges.
Frontmatter
| id | iss-2608291807456485 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | critical |
.abcd/work/issues/resolved/iss-2608291807456485-gitleaks-adapter-executes-committed.md
open on GitHub ↗ · commit history ↗
mentions1
- dcn-26082900000000022026-08-29 — The gitleaks adapter admits a binary under an allow-shape, not a deny-list (GHSA-fg9r-3f8g-89m6, iss-2608291807456485): absolute path, resolved OUTSIDE the repository both lexically and after symlink resolution, regular, executable — applied identically to a committed `path` and to the PATH lookup result. Refusal is `ErrConfiguredPathRefused`, as loud as not-found, and a refused configured path never falls back to PATH. PATH itself stays trusted as the operator's environment (abcd already resolves git, gh and grep from it; a hostile checkout cannot set it); what the admission rule closes is a PATH entry or config that reaches INTO the checkout. Rejected: a fixed safe search path for the fallback (would break Homebrew/asdf/custom installs for no gain against an operator-level PATH compromise) and executing with an isolated env (the env is the operator's, like PATH — gitleaks does honour GITLEAKS_CONFIG, but a checkout cannot set it; cwd is pinned to the private temp dir instead). Containment routes through `fsutil.PathWithin` with the case-folding predicate AND an `os.SameFile` ancestor walk, because a byte-exact compare admitted a case-variant or NFD respelling of the root on APFS.