Skip to content

fix: refuse unverified installs and fork publishes - #16

Merged
catinspace-au merged 1 commit into
mainfrom
fix/supply-chain-fail-closed
Oct 14, 2026
Merged

catinspace-au merged 1 commit into
mainfrom
fix/supply-chain-fail-closed

Conversation

@catinspace-au

Copy link
Copy Markdown
Contributor

Three supply-chain gaps from #10. The installer that action.yml pipes into every consumer's CI could install a binary it never verified, a fork PR could start the publish chain, and a re-run could swap the bytes behind a versioned URL.

  • install.sh fails closed. A missing sums file, a sums file without this asset, a mismatch, a download error or no SHA-256 tool all exit 1 with nothing installed. It reads the per-asset <asset>.sha256 every release already publishes, falls back to checksums.sha256, and matches the exact asset name rather than a substring. latest/checksums.sha256 is a 404 today, so every install was unverified.
  • Cross-build and Package filter workflow_run on branches: [main], and their resolve-tag jobs also require the upstream run to be in this repository, from a push or a dispatch. A fork can call its branch main, hence the repository check.
  • Versioned R2 paths are write-once. Each upload lists its marker file first and writes nothing, latest/ included, when it is already there. A concurrency group queues the tag-push and CI-completion Cross-builds for one tag instead of racing them.
  • build.rs stamps SOURCE_DATE_EPOCH, else the HEAD commit time, never the clock. Two release builds of one commit now hash the same.
  • The packages .sha256 no longer lists itself.
  • tests/install_sh.rs drives the rendered install.sh against a loopback HTTP server: 9 cases, and every failure path is asserted to exit 1 with nothing installed.

Still open: nothing is signed, so the sums file comes from the same host as the binary. Fixing that needs a key distributed out of band, which is a separate call.

Fixes #10

install.sh installed whatever it downloaded when the sums file was missing, did not name the asset, or no hash tool was present. It now refuses all three, matches the exact asset name rather than a substring, and reads the per-asset .sha256 the release already publishes before the combined checksums.sha256.

Cross-build and Package ran their publish jobs after any successful CI run, fork pull requests included. Both now need the upstream run on main, in this repository, from a push or a dispatch.

Re-runs no longer replace published bytes. Each upload writes nothing when its versioned marker file is already on R2, and build.rs stamps SOURCE_DATE_EPOCH or the commit time instead of the clock, so one commit builds one binary.

Fixes #10
@catinspace-au
catinspace-au merged commit 79f68a8 into main Oct 14, 2026
18 checks passed
@catinspace-au
catinspace-au deleted the fix/supply-chain-fail-closed branch October 14, 2026 04:46
@github-actions

Copy link
Copy Markdown

Released in v1.5.12 -- https://github.com/hyperi-io/macbash/releases/tag/v1.5.12

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Supply chain: install.sh checksum verification fails open, and the workflow_run chain is triggerable by a fork PR

1 participant