Skip to content

fix: add SHA-256 checksum verification to release download (security)#285

Open
xiaolai wants to merge 1 commit into
nextlevelbuilder:mainfrom
xiaolai:fix/nlpm-download-checksum
Open

fix: add SHA-256 checksum verification to release download (security)#285
xiaolai wants to merge 1 commit into
nextlevelbuilder:mainfrom
xiaolai:fix/nlpm-download-checksum

Conversation

@xiaolai
Copy link
Copy Markdown

@xiaolai xiaolai commented Apr 26, 2026

Automated audit: This PR was generated by NLPM, a natural language programming linter, running via claude-code-action. Please evaluate the diff on its merits.

Security Fix (Medium severity)

cli/src/utils/github.tsdownloadRelease() fetches a ZIP from GitHub releases and writes it to disk, then init.ts extracts and copies the contents into the user's project. No integrity check was performed, so a compromised or corrupted release asset would be silently installed.

Fix

cli/src/utils/github.ts

  • Added an optional expectedSha256 parameter to downloadRelease(). When provided, the downloaded buffer is hashed with Node's built-in node:crypto before writing to disk. A mismatch throws a GitHubDownloadError with both expected and actual hashes for easy diagnosis.
  • Added findChecksumAsset(release, assetName) — looks for a companion checksum file in the GitHub release assets (<assetName>.sha256, checksums.sha256, SHA256SUMS) and extracts the hex digest.

cli/src/commands/init.ts

  • Calls findChecksumAsset() before downloading.
  • Passes the result to downloadRelease().

Backwards compatibility: if the release does not include a checksum file, findChecksumAsset returns null and downloadRelease proceeds as before — no regression for existing releases.

downloadRelease() previously wrote the fetched ZIP to disk with no
integrity check. A compromised release asset would be silently installed.

Added an optional expectedSha256 parameter: when provided, the buffer is
hashed with node:crypto before writing, and a mismatch throws an error.

Added findChecksumAsset() to look for a companion checksum file in the
release assets (e.g. release.zip.sha256, checksums.sha256, SHA256SUMS)
and extract the hex digest. init.ts now calls findChecksumAsset() before
downloading and passes the result to downloadRelease() — if the release
includes a checksum file the download is verified; if not, the current
behaviour is preserved with no regression.

Co-Authored-By: Claude Code <[email protected]>
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.

1 participant