Skip to content

ci(hooks): replace the duplicated bootstrap with a thin stub - #194

Merged
tnunamak merged 3 commits into
mainfrom
refactor/thin-keyscan-stub
Aug 19, 2026
Merged

tnunamak merged 3 commits into
mainfrom
refactor/thin-keyscan-stub

Conversation

@tnunamak

Copy link
Copy Markdown
Member

Replaces this repository's copy of the EVM key-scan bootstrap with a thin stub, following vana-com/.github#3.

Why

Every consuming repository carried ~90 near-identical lines of fetch-validate-delegate logic. That duplication is where both recent bugs lived — the worktree GIT_DIR failure and the GIT_CONFIG_GLOBAL origin-spoof hole — and fixing them required six near-identical patches across six repos. It was the third time this logic had drifted between copies, and the narrowest copy was the exploitable one.

What changes

The validation, locking and delegation logic now lives in vana-com/.github as scripts/bootstrap.sh. What stays here is a stub that does two things: name the reviewed policy commit, and fetch it.

Fetching by SHA is self-authenticating — git verifies the delivered objects hash to the requested commit — and the central bootstrap re-validates origin, SHA and working-tree cleanliness before anything executes.

A future fix in the policy reaches this repository when it advances its pin, with no edit to this file.

What deliberately does not change

The pinned SHA stays here. It is the supply-chain review gate: without it the central repository could execute new code on every developer's machine at push time. The aim was never to remove the pin — it is one line — but to stop shipping ninety lines of logic alongside it.

Pin moves to 7f59130 (vana-com/.github#3).

Verification

Against the real published policy:

  • install in a clean repo fetches the policy, execs the central bootstrap, and installs the hook
  • a range containing a key in a secret-shaped declaration is detected and exits 1
  • a clean range exits 0
  • from a linked worktree with an absolute GIT_DIR, the policy cache is fetched and prepared correctly
  • a cache whose origin is attacker/evil.git while GIT_CONFIG_GLOBAL claims vana-com/.github is refused

Assisted-by: AI

The ~90 lines of fetch-validate-delegate logic move to vana-com/.github as
scripts/bootstrap.sh (vana-com/.github#3). That duplication is where the
worktree GIT_DIR bug and the GIT_CONFIG_GLOBAL origin-spoof hole both lived,
and fixing them took six near-identical patches.

What stays here is a stub that names the reviewed policy commit and fetches it.
Fetching by SHA is self-authenticating, and the central bootstrap re-validates
origin, SHA and cleanliness before anything executes. A future policy fix now
reaches this repo when it advances its pin, with no edit to this file.

The pin stays local deliberately — it is the supply-chain review gate.

Assisted-by: AI
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
vana-console Ignored Ignored Aug 19, 2026 1:33am
vana-rbac-auditor Ignored Ignored Aug 19, 2026 1:33am
vana-vibes-demo Ignored Ignored Aug 19, 2026 1:33am

Request Review

@github-actions

Copy link
Copy Markdown
  • [P1] Authenticate the cached entrypoint before executing it.github/scripts/install-evm-key-scan-hook.sh:58 executes bootstrap.sh from any existing cache without first checking symlinks, commit, or modifications. A poisoned cache can execute arbitrary code before the central bootstrap’s validation runs. Verify the entrypoint against the pinned commit locally before execution.

  • [P2] Preserve locking around initial cache creation — At line 54, concurrent first runs can both fetch; the second mv places its temporary directory inside the newly created policy_dir, leaving the cache dirty and potentially unusable. Acquire a per-SHA lock before the existence check/fetch/publish sequence, or use an atomic operation that fails if the destination appeared.

Review caught a real regression in the first version of this stub: it exec'd
scripts/bootstrap.sh out of any pre-existing cache without checking it first,
so a poisoned cache ran arbitrary code BEFORE the central validation it
delegates to. Confirmed by planting a cache whose bootstrap printed and exited
0 — it executed.

Validates symlink, origin, pinned SHA and cleanliness ahead of the exec, and
refuses a symlinked bootstrap. These checks are deliberately duplicated with
the central bootstrap: that one still re-runs them for callers arriving another
way, but they must also happen here, before control transfers into the cache.

Verified: the poisoned cache is now refused at the origin check and never
executes, while fresh fetch, cached re-run and detection all still work.

Assisted-by: AI
@github-actions

Copy link
Copy Markdown

Found one security issue:

  • High: git status can execute attacker-controlled core.fsmonitor configured in the poisoned cache’s .git/config. That means arbitrary cache code may run during “authentication,” before bootstrap.sh is validated. Disable execution-capable local configuration for validation, e.g. invoke status with -c core.fsmonitor=false, and audit other repository-local config effects. Also read remote.origin.url directly via git config --local --no-includes --get rather than remote get-url, which applies attacker-controlled URL rewrites.

… cache

Review caught that a poisoned cache can execute code through its own
.git/config while being authenticated: core.fsmonitor runs a command during
`git status`, so the cleanliness check was itself an execution vector.
Environment scrubbing cannot reach this — the settings live in the cache's
repo-local config, which only -c overrides neutralize.

Pin moves to the policy carrying the same fix in bootstrap.sh, install-pre-push.sh
and hooks/pre-push.

Verified end to end: fresh install works, a planted core.fsmonitor never fires,
a modified cache bootstrap is refused, and detection still exits 1.

Assisted-by: AI
@github-actions

Copy link
Copy Markdown

No actionable findings in the new commit. The added Git configuration overrides appropriately neutralize the relevant execution paths during cache validation, and both policy references use the same pinned SHA.

@tnunamak
tnunamak merged commit 33ee493 into main Aug 19, 2026
10 checks passed
@tnunamak
tnunamak deleted the refactor/thin-keyscan-stub branch August 19, 2026 01:37
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 3.16.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant