Skip to content

feat: fail closed when checksums.txt is missing during install#1503

Open
dc-bytedance wants to merge 3 commits into
mainfrom
feat/harden-npm-install
Open

feat: fail closed when checksums.txt is missing during install#1503
dc-bytedance wants to merge 3 commits into
mainfrom
feat/harden-npm-install

Conversation

@dc-bytedance

@dc-bytedance dc-bytedance commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

The npm postinstall (scripts/install.js) verifies the downloaded Go binary against the package-shipped checksums.txt, but previously skipped verification entirely when checksums.txt was missing (fail-open) — letting an unverified or tampered binary install silently. This change makes it fail-closed: a missing manifest now aborts the install with a clear [SECURITY] error and a non-zero exit, so an unverified binary is never copied into place.

Changes

  • scripts/install.js: getExpectedChecksum now throws [SECURITY] checksums.txt not found; refusing to install an unverified binary. when checksums.txt is missing (previously logged [WARN] and returned null to skip verification).
  • scripts/install.js: verifyChecksum now throws [SECURITY] missing expected checksum; ... for a non-string/empty expected hash, replacing the silent if (expectedHash === null) return; early-return (the second half of the fail-open path).
  • scripts/install.test.js: updated the missing-manifest case to assert the fail-closed throw; added a regression test for the empty-hash guard.

Normal installs are unaffected: published packages always ship checksums.txt (package.json files includes it and the release workflow enforces its presence before publish). A missing manifest only occurs for tampered or non-standard packages — exactly what fail-closed should reject.

Test Plan

  • node --test scripts/install.test.js passed (33/33)
  • validate passed (build / vet / unit / integration; zero Go change)
  • local-eval: E2E N/A (postinstall script, no CLI E2E), skillave N/A (no shortcut/skill change)
  • acceptance-reviewer passed (5/5 cases)
  • manual verification: stubbed the download and ran the full install() path with no checksums.txt — aborted with [SECURITY], exit 1, no binary written to bin/; with a valid checksums.txt it passed the checksum gate

Related Issues

N/A

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced installer security by hardening checksum validation. The installer now fails safely and refuses to proceed when checksum data is missing or incomplete, preventing installation of unverified or potentially tampered binaries.
  • Tests
    • Updated checksum verification tests to enforce fail-closed behavior when checksum data is missing or when the expected hash is null.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5e46b257-eecf-466d-9a60-b06b2a7224bc

📥 Commits

Reviewing files that changed from the base of the PR and between ae88ea7 and c7e7e8a.

📒 Files selected for processing (2)
  • scripts/install.js
  • scripts/install.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/install.js
  • scripts/install.test.js

📝 Walkthrough

Walkthrough

Two functions in scripts/install.js are changed from fail-open to fail-closed: getExpectedChecksum now throws a [SECURITY] error when checksums.txt is missing (instead of returning null), and verifyChecksum now throws a [SECURITY] error when expectedHash is absent or empty. The test file is updated to assert these new throwing behaviors.

Changes

Fail-closed checksum verification

Layer / File(s) Summary
Throw security errors on missing checksum data
scripts/install.js
getExpectedChecksum throws a [SECURITY]-prefixed error instead of returning null when checksums.txt is not found. verifyChecksum throws a [SECURITY]-prefixed error instead of skipping verification when expectedHash is absent or empty.
Update tests to assert fail-closed behavior
scripts/install.test.js
The getExpectedChecksum test for a missing checksums.txt is updated from asserting null return to asserting a thrown [SECURITY] error. A new verifyChecksum test case asserts a thrown [SECURITY] error when called with a null expected hash.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • larksuite/cli#592: Previously established the checksum-verification flow in getExpectedChecksum/verifyChecksum that this PR converts from fail-open to fail-closed behavior.

Suggested reviewers

  • liangshuo-1

Poem

🐇 No more sneaky null returns, no silent pass-through gate,
A missing checksum file now makes the process terminate.
[SECURITY] thrown with flair, the binary waits in line,
Until the hash is verified — only then may it be mine!
Hop hop hooray, fail-closed today! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main security change: hardening checksum verification to fail closed when checksums.txt is missing during install.
Description check ✅ Passed The description covers all required template sections with comprehensive details: clear summary of the security issue, specific changes to both install.js and tests, detailed test plan with verification results, and accurate related issues.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/harden-npm-install

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the size/M Single-domain feat or fix with limited business impact label Jun 17, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/install.test.js`:
- Around line 135-144: The test for verifyChecksum with the name "verifyChecksum
throws [SECURITY] on null/empty expectedHash (fail-closed)" only tests the null
case but does not test the empty string case as the test name suggests. Add an
additional test case (or modify the existing one) to also verify that
verifyChecksum throws a [SECURITY] error when expectedHash is passed as an empty
string (""). Ensure the test uses the same assertion pattern with assert.throws
and validates that the error message matches the /^\[SECURITY\]/ regex pattern.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c988e8c9-3adf-4523-b086-8e1acf9108e1

📥 Commits

Reviewing files that changed from the base of the PR and between 4a4c334 and f9a17ad.

📒 Files selected for processing (2)
  • scripts/install.js
  • scripts/install.test.js

Comment thread scripts/install.test.js
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.52%. Comparing base (4a4c334) to head (c7e7e8a).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1503   +/-   ##
=======================================
  Coverage   73.52%   73.52%           
=======================================
  Files         783      783           
  Lines       74630    74630           
=======================================
  Hits        54874    54874           
  Misses      15662    15662           
  Partials     4094     4094           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@c7e7e8ad4042a2ca2f9714d7d4a2743fbd00f834

🧩 Skill update

npx skills add larksuite/cli#feat/harden-npm-install -y -g

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

PR Quality Summary

CI did not complete successfully. Use the failed check links below to decide whether this PR needs a code change or a rerun.

Failed checks

@dc-bytedance dc-bytedance force-pushed the feat/harden-npm-install branch from ae88ea7 to c7e7e8a Compare June 17, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant