Skip to content

fix(install): verify sha256 checksum of downloaded release tarball#1395

Open
if414013 wants to merge 1 commit intortk-ai:developfrom
if414013:fix/install-verify-checksum
Open

fix(install): verify sha256 checksum of downloaded release tarball#1395
if414013 wants to merge 1 commit intortk-ai:developfrom
if414013:fix/install-verify-checksum

Conversation

@if414013
Copy link
Copy Markdown

Summary

The install.sh script (used by the documented curl | sh installation path) downloads the release tarball and extracts it without any integrity check. A tampered release asset, a MITM on the download, or a replaced asset on an already-published release is installed silently.

This PR adds sha256 verification by fetching checksums.txt from the same release and checking the downloaded archive against it before extraction.

Threat this closes

Given that rtk is installed into the agent's command path and rewrites output that an LLM consumes, a modified binary has an unusually high blast radius (it can silently alter what git diff, cat, npm test, etc. look like to the model). The current installer has a single point of trust — whoever can write to the release assets. After this PR, an attacker needs to modify the tarball and re-sign the checksums file served from the same release, which at minimum raises the bar.

This does not replace artifact signing (cosign / SLSA provenance) — those are separate hardening steps — but closes the specific case of "release-asset tampered after publication" on the installer path.

What changed

  • install.sh
    • New sha256_of() helper: uses sha256sum (GNU coreutils) when available, falls back to shasum -a 256 (default on macOS/BSD). Aborts explicitly if neither is present rather than silently skipping.
    • After download, fetches checksums.txt from the same release, looks up the expected sha256 for the archive by exact filename match (awk $2 == f, so we don't match on partial filenames), compares against the computed hash, and aborts before extraction on mismatch.

No workflow changes needed — the release workflow already publishes checksums.txt:

# .github/workflows/release.yml
- name: Create checksums
  run: |
    cd release
    sha256sum * > checksums.txt

Test plan

  • sh -n install.sh — syntax check passes
  • Parser tested against the live checksums.txt for v0.37.1:
    $ curl -fsSL https://github.com/rtk-ai/rtk/releases/download/v0.37.1/checksums.txt \
        | awk -v f="rtk-x86_64-unknown-linux-musl.tar.gz" \
            '{sub(/^\*/, "", $2); if ($2 == f) print $1}'
    f9aa033ec7146e552457f6231d706c0c42e5fdb77d836bc4c98ae24b2930d33e
    
  • Matches the exact filename only (verified with a crafted checksums.txt containing a filename that is a substring of another)
  • Maintainer sanity check: run the installer end-to-end on macOS and Linux against the current latest release

Notes / scope

Keeping this PR small and focused on the single highest-impact change. Related hardening that should land separately:

  • Pin GitHub Actions to commit SHA (currently softprops/action-gh-release@v2, googleapis/release-please-action@v4, actions/github-script@v7 track mutable tags).
  • Publish cosign / SLSA provenance alongside release artifacts.
  • Audit HOMEBREW_TAP_TOKEN PAT scope; consider a Homebrew bump-formula-pr flow instead of direct gh api PUT.
  • Add CODEOWNERS to enforce the tier-1 critical-file review policy described in SECURITY.md.

Happy to open follow-ups for any/all of these if useful.

The installer previously downloaded the release tarball and extracted
it without any integrity check. A tampered release asset, a MITM on the
download, or a replaced asset on an already-published release would be
installed silently.

After the download, fetch checksums.txt from the same release, look up
the expected sha256 for the archive by exact filename match, compute
the actual sha256 of what was downloaded, and abort before extraction
on mismatch.

Uses sha256sum (GNU coreutils) when available and falls back to
shasum -a 256 (present by default on macOS and BSD) so the script
stays portable across Linux and macOS without adding dependencies.
Aborts explicitly when neither tool is available, rather than
silently skipping verification.

The release workflow already publishes checksums.txt alongside each
release (.github/workflows/release.yml uses "sha256sum * > checksums.txt"),
so no pipeline changes are required.
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@pszymkowiak pszymkowiak added effort-small Quelques heures, 1 fichier enhancement New feature or request labels Apr 19, 2026
@pszymkowiak
Copy link
Copy Markdown
Collaborator

[w] wshm · Automated triage by AI

📊 Automated PR Analysis

🐛 Type bug-fix
🟢 Risk low

Summary

Adds SHA-256 checksum verification to the install.sh script to validate downloaded release tarballs before extraction. The change introduces a portable sha256_of() helper that works on both GNU and BSD/macOS systems, fetches checksums.txt from the release, and aborts installation if the hash doesn't match.

Review Checklist

  • Tests present
  • Breaking change
  • Docs updated

Analyzed automatically by wshm · This is an automated analysis, not a human review.

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

Labels

effort-small Quelques heures, 1 fichier enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants