mirror of
https://github.com/Heretek-AI/IUMBTEMS.git
synced 2026-10-12 02:03:00 +00:00
fix(audit-185): probe binary presence live instead of caching (Refs #243)
Follow-up to the negative-cache fix: caching positives is stale the other way — a PATH shim's finally-restore leaves the cached hit behind and the next gate run spawns a binary that is gone (CI: cli.test.ts gates run failed with `Executable not found in $PATH: gitleaks`). installed() is a live PATH probe now; a probe is microseconds and gate runs call it a handful of times. The unit test pins both directions (miss→shim→seen→removed→miss). TDD: CI run 38105290150 is the red witness for the stale-positive direction; gates-seeded.test.ts 13/13 green locally after. Refs #185
This commit is contained in:
@@ -8,21 +8,16 @@ import type { GateFinding } from "../schema/gates.ts"
|
||||
import { parseJsonc } from "../util/jsonc.ts"
|
||||
import { run } from "../util/proc.ts"
|
||||
|
||||
const which = new Map<string, boolean>()
|
||||
|
||||
/**
|
||||
* Is `binary` an executable on PATH? Pure lookup (no shell), so no injection.
|
||||
* Only positive answers are cached: a miss is re-probed every time, so a
|
||||
* binary installed (or shimmed onto PATH) later in the process is seen.
|
||||
* Caching a miss pinned Gate skips across PATH changes (#243: the gitleaks
|
||||
* PATH shims in these tests read as absent once any earlier gate run cached
|
||||
* the miss on a machine without the binary).
|
||||
* Probed live on every call: caching the answer pinned Gate skips across
|
||||
* PATH changes in both directions (#243 — a cached miss hid later shims;
|
||||
* a cached hit outlived the shim's finally-restore and sent the gate at a
|
||||
* binary that was already gone). A PATH probe is microseconds; gate runs
|
||||
* call this a handful of times.
|
||||
*/
|
||||
export function installed(binary: string): boolean {
|
||||
if (which.get(binary) === true) return true
|
||||
const found = onPath(binary)
|
||||
if (found) which.set(binary, true)
|
||||
return found
|
||||
return onPath(binary)
|
||||
}
|
||||
|
||||
function onPath(binary: string): boolean {
|
||||
|
||||
@@ -325,6 +325,10 @@ describe("gitleaks shape and waiver glob edges", () => {
|
||||
process.env.PATH = previous
|
||||
await rm(shimdir, { recursive: true, force: true })
|
||||
}
|
||||
// And no stale positive survives the shim's removal: the next gate run
|
||||
// must skip the scanner instead of spawning a binary that is gone (the
|
||||
// cli.test.ts gates failure this exact staleness caused in CI).
|
||||
expect(installed(missing)).toBe(false)
|
||||
})
|
||||
|
||||
test("a rule+files glob waiver hides only what both globs match", async () => {
|
||||
|
||||
Reference in New Issue
Block a user