feat(pkggate): new package - block pkg run/exec of scratch-tier or repo-escaping scripts #91

Closed
opened 2026-06-07 04:07:38 +00:00 by coilysiren · 1 comment
Owner

Extraction candidate from the coily cmd/coily/ generic-code audit (2026-06-06). Source pinned at coily commit c7c17cb (canonical: forgejo.coilysiren.me/coilyco-bridge/coily). cli-guard is mid-refactor, so the "suggested home" below is the pre-refactor package layout - land this in whatever the post-refactor equivalent is, not necessarily the named package. The durable principle: the classifiers / argv-transforms are generic and move; the policy decisions and message copy stay in coily.

Source: cmd/coily/pkg_run_gate.go - pkgRunSpec registry, pkgRunSpecs map, pkgEscapingPath, looksLikePath, hasScriptSuffix, pkgScratchRoots. Already imports cli-guard/scope.

What it does: preflight gate for pkg <tool> run/exec passthroughs (uv, bun, npm, poetry, ...). Blocks running a script whose path is in a scratch tier (/tmp, /dev/shm, ...) or escapes the repo root - closes the "interpreter laundered through the shell-metachar gate" arbitrary-code-execution hole.

Generic core (lift this): the pkgRunSpec registry shape, the path-escape logic, and the scratch-root check are consumer-agnostic.

Consumer seams to parameterize: block-message branding (coily: prefix, coily#9/#10 refs) -> template/callback; ship pkgRunSpecs as a default map callers can extend/replace.

Dedup win: pkgScratchRoots is hand-synced with hook's scratchExecRoots (noted in-comment as kept-in-sync-by-hand). Extract one shared scratch-roots source and have both consume it.

Suggested home (pre-refactor): new pkggate package (or fold into passthrough as an optional gate).

Done when:

  • generic logic lives in cli-guard with zero coily/Kai/Forgejo identifiers or defaults
  • behavior-covered tests (table tests where the source has them)
  • godoc-current.txt regenerated (scripts/check-godoc-current.sh --update)
  • coily migrated onto the extracted API, its local copy deleted, make test green both sides
  • closes this issue

Related: cli-guard#61 (glob-pattern argv deny primitive) is adjacent - this gate is a path-shape deny, that issue is a glob deny; check whether they should share machinery post-refactor.

> Extraction candidate from the coily `cmd/coily/` generic-code audit (2026-06-06). Source pinned at coily commit `c7c17cb` (canonical: `forgejo.coilysiren.me/coilyco-bridge/coily`). **cli-guard is mid-refactor**, so the "suggested home" below is the pre-refactor package layout - land this in whatever the post-refactor equivalent is, not necessarily the named package. The durable principle: **the classifiers / argv-transforms are generic and move; the policy decisions and message copy stay in coily.** **Source:** `cmd/coily/pkg_run_gate.go` - `pkgRunSpec` registry, `pkgRunSpecs` map, `pkgEscapingPath`, `looksLikePath`, `hasScriptSuffix`, `pkgScratchRoots`. Already imports `cli-guard/scope`. **What it does:** preflight gate for `pkg <tool> run/exec` passthroughs (uv, bun, npm, poetry, ...). Blocks running a script whose path is in a scratch tier (`/tmp`, `/dev/shm`, ...) or escapes the repo root - closes the "interpreter laundered through the shell-metachar gate" arbitrary-code-execution hole. **Generic core (lift this):** the `pkgRunSpec` registry shape, the path-escape logic, and the scratch-root check are consumer-agnostic. **Consumer seams to parameterize:** block-message branding (`coily:` prefix, coily#9/#10 refs) -> template/callback; ship `pkgRunSpecs` as a default map callers can extend/replace. **Dedup win:** `pkgScratchRoots` is hand-synced with `hook`'s `scratchExecRoots` (noted in-comment as kept-in-sync-by-hand). Extract one shared scratch-roots source and have both consume it. **Suggested home (pre-refactor):** new `pkggate` package (or fold into `passthrough` as an optional gate). **Done when:** - [ ] generic logic lives in cli-guard with zero coily/Kai/Forgejo identifiers or defaults - [ ] behavior-covered tests (table tests where the source has them) - [ ] `godoc-current.txt` regenerated (`scripts/check-godoc-current.sh --update`) - [ ] coily migrated onto the extracted API, its local copy deleted, `make test` green both sides - [ ] `closes` this issue **Related:** cli-guard#61 (glob-pattern argv deny primitive) is adjacent - this gate is a path-shape deny, that issue is a glob deny; check whether they should share machinery post-refactor.
Author
Owner

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: burndown-2026-06.

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: `burndown-2026-06`.
coilysiren 2026-06-17 08:23:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/cli-guard#91
No description provided.