Skip to content

install: make BUN_CONFIG_NO_VERIFY disable integrity verification when set - #38310

Open
robobun wants to merge 1 commit into
mainfrom
farm/87342667/fix-bun-config-no-verify-inverted
Open

robobun wants to merge 1 commit into
mainfrom
farm/87342667/fix-bun-config-no-verify-inverted

Conversation

@robobun

@robobun robobun commented Aug 14, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • BUN_CONFIG_NO_VERIFY=0 turns tarball integrity verification off: a tarball whose bytes do not match the sha512 advertised by the registry installs with exit code 0 and the advertised hash is written to bun.lock.
  • BUN_CONFIG_NO_VERIFY=1 (or any other value) leaves verification on, so the variable cannot be used for what its name says.
  • Cause: src/install/PackageManager/PackageManagerOptions.rs:672 sets Do::VERIFY_INTEGRITY to value != "0", the opposite of the BUN_CONFIG_SKIP_* variables handled a few lines above it (value == "0"). The comparison has been inverted since the variable was added alongside --no-verify in b897ad3 (2022) and was ported as is.
  • --no-verify itself is unaffected.

Fix

  • PackageManagerOptions.rs:672: check_bool != b"0" becomes check_bool == b"0", so BUN_CONFIG_NO_VERIFY=<anything but 0> skips verification (same as --no-verify) and BUN_CONFIG_NO_VERIFY=0 keeps it on, matching how BUN_CONFIG_SKIP_SAVE_LOCKFILE, BUN_CONFIG_SKIP_LOAD_LOCKFILE and BUN_CONFIG_SKIP_INSTALL_PACKAGES are read right above it. This is the only line of behavior change.
  • --no-verify still wins when both are given; it is applied after the env var, unchanged.
  • The variable is not documented anywhere (docs only list the BUN_CONFIG_SKIP_* ones), and this is its only reference in the repo, so nothing in CI or tests depended on the inverted reading.
  • Verified with test/cli/install/bun-install-tarball-integrity.test.ts, three new cases in the existing "tarball integrity metadata forms" block. The registry advertises the sha512 of a different tarball than the one it serves:
    • BUN_CONFIG_NO_VERIFY=1 skips the integrity check like --no-verify: fails on main (main prints Integrity check failed), passes with this change.
    • BUN_CONFIG_NO_VERIFY=0 keeps the integrity check enabled: fails on main (main installs the package), passes with this change.
    • --no-verify installs a tarball whose bytes don't match the advertised integrity: passes on main and here; pins the behavior the env var now mirrors.
  • The rest of the file (19 tests) passes with the debug build.

Background

  • During bun install, each registry tarball is hashed while it is extracted and compared against the dist.integrity value from the package manifest (or the lockfile); a mismatch is reported as Integrity check failed for tarball: <name> and the install fails. --no-verify turns that comparison off by clearing the Do::VERIFY_INTEGRITY option bit; BUN_CONFIG_NO_VERIFY is the environment-variable form of the same switch.
  • Do is the bitflags set of per-run actions in PackageManagerOptions.rs (save lockfile, install packages, verify integrity, ...). The BUN_CONFIG_* environment variables are read in Options::load and are applied before the CLI flags, so flags override them.

[review] gate passed · iteration 0 · 2 files touched

fails on main (without fix)
ASAN without fix: 2 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/cli/install/bun-install-tarball-integrity.test.ts
bun test v1.4.0 (5ca9aa12a)

test/cli/install/bun-install-tarball-integrity.test.ts:
(pass) tarball integrity > should store integrity hash for local tarball in text lockfile [296.66ms]
(pass) tarball integrity > should store integrity hash for tarball URL in text lockfile [351.77ms]
(pass) tarball integrity > should install successfully from text lockfile without integrity hash (backward compat) [362.18ms]
(pass) tarball integrity > should add integrity hash to lockfile when re-resolving tarball dep [161.47ms]
(pass) tarball integrity > should fail integrity check when tarball URL content changes [572.99ms]
(pass) tarball integrity > should store consistent integrity hash for tarball URL across reinstalls [807.31ms]
(pass) tarball integrity > should install successfully from text lockfile without integrity hash for local tarball (backward compat) [405.09ms]
(pass) tarball integrity > should store consistent integrity hash for local tarball across reinstalls [628.35ms]
(pass) tarba
... (truncated)

release without fix: 2 FAILED
bun test v1.4.0-canary.1 (b7a043103)

test/cli/install/bun-install-tarball-integrity.test.ts:
(pass) tarball integrity > should store integrity hash for local tarball in text lockfile [33.99ms]
(pass) tarball integrity > should install successfully from text lockfile without integrity hash for local tarball (backward compat) [32.90ms]
796 |       env: { ...env, BUN_INSTALL_CACHE_DIR: join(String(dir), ".cache"), BUN_CONFIG_NO_VERIFY: "1" },
797 |       stdout: "pipe",
798 |       stderr: "pipe",
799 |     });
800 |     const [stderr, stdout, exitCode] = await Promise.all([proc.stderr.text(), proc.stdout.text(), proc.exited]);
801 |     expect(stderr + stdout).not.toContain("Integrity check failed");
                                      ^
error: expect(received).not.toContain(expected)

Expected to not contain: "Integrity check failed"
Received: "Resolving dependencies\nerror: Integrity check failed for tarball: pkg\nResolved, downloaded and extracted [4]\nerror: IntegrityCheckFailed extracting tarball from pkg\nbun install v1.4.0-canary.1 (b7a043103)\n"

      at <anonymous> (/workspace/bun/test/cli/install/bun-install-tarball-integrity.test.ts:801:33)
(fail) tarba
... (truncated)
passes on PR (with fix)
ASAN with fix: all passed
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/cli/install/bun-install-tarball-integrity.test.ts
bun test v1.4.0 (5ca9aa12a)

test/cli/install/bun-install-tarball-integrity.test.ts:
(pass) tarball integrity > should install successfully from text lockfile without integrity hash (backward compat) [372.27ms]
(pass) tarball integrity > should store integrity hash for tarball URL in text lockfile [456.93ms]
(pass) tarball integrity > should store integrity hash for local tarball in text lockfile [533.89ms]
(pass) tarball integrity > should fail integrity check when tarball URL content changes [690.64ms]
(pass) tarball integrity > should add integrity hash to lockfile when re-resolving tarball dep [339.45ms]
(pass) tarball integrity > should store consistent integrity hash for tarball URL across reinstalls [1032.20ms]
(pass) tarball integrity > should store consistent integrity hash for local tarball across reinstalls [766.62ms]
(pass) tarball integrity > should install successfully from text lockfile without integrity hash for local tarball (backward compat) [564.74ms]
(pass) tarb
... (truncated)

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 809ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/5] gen generated_host_exports.rs
generated_host_exports.rs: 93 exports (host=3, lazy=10, generic=80, rust=0); 239 extern-C blocks audited
[1/5] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

�[1m�[92m   Compiling�[0m bun_install v0.0.0 (/workspace/bun/src/install)
�[1m�[92m   Compiling�[0m bun_jsc v0.0.0 (/workspace/bun/src/jsc)
�[1m�[92m   Compiling�[0m bun_ast_jsc v0.0.0 (/workspace/bun/src/ast_jsc)
�[1m�[92m   Compiling�[0m bun_js_parser_jsc v0.0.0 (/workspace/bun/src/js_parser_jsc)
�[1m�[92m   Compiling�[0m bun_patch_jsc v0.0.0 (/workspace/bun/src/patch_jsc)
�[1m�[92m   Compiling�[0m bun_semver_jsc v0.0.0 (/workspace/bun/src/semver_jsc)
�[1m�[92m   Compiling�[0m bun_sys_jsc v0.0.0 (/workspace/bun/src/sys_jsc)
�[1m�[92m   Compiling�[0m bun_sql_jsc v0.0.0 (/workspace/bun/src/sql_jsc)
�[1m�[92m   Compiling�[0m bun_sourcemap_jsc v0.0.0 (/workspace/bun/src/sourcemap_jsc)
�[1m�[92m 
... (truncated)
diff hotspot
.../PackageManager/PackageManagerOptions.rs        |  2 +-
 .../install/bun-install-tarball-integrity.test.ts  | 68 ++++++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)

gate history · 1 passed · 0 rejected · iteration 0

evidence per changed file
file                                                    reads  edits  tests
src/install/PackageManager/PackageManagerOptions.rs         2      1      0
test/cli/install/bun-install-tarball-integrity.test.ts      2      1      0

root cause · written by the author bot

The BUN_CONFIG_NO_VERIFY environment variable was read with inverted polarity in PackageManagerOptions.rs, assigning the result of a check_bool != "0" comparison to the VERIFY_INTEGRITY flag, so setting it to 1 kept tarball integrity verification on while setting it to 0 silently disabled it. The fix flips that comparison so the variable clears VERIFY_INTEGRITY when truthy and leaves it set when 0, matching the BUN_CONFIG_SKIP_* variables beside it and the documented --no-verify flag, which is still applied afterwards and keeps its precedence. Three new tests in bun-install-tarball-integrit…

…n set

The env var was read with the comparison inverted since it was added:
BUN_CONFIG_NO_VERIFY=0 turned tarball integrity verification off and
BUN_CONFIG_NO_VERIFY=1 left it on. Read it the same way as the
BUN_CONFIG_SKIP_* variables next to it, so any value other than "0"
skips verification (same as --no-verify) and "0" keeps it enabled.
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 11e9e82b-5a08-4c2d-819d-7cc1b9e2d2df

📥 Commits

Reviewing files that changed from the base of the PR and between b555e06 and 5ca9aa1.

📒 Files selected for processing (2)
  • src/install/PackageManager/PackageManagerOptions.rs
  • test/cli/install/bun-install-tarball-integrity.test.ts

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

@robobun

robobun commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator Author

Reproduced on main (b7a0431) with a loopback registry that advertises the sha512 of a different tarball than the one it serves:

(no env, no flag)          exit=1 integrity_failed=true  installed=false
--no-verify                exit=0 integrity_failed=false installed=true
BUN_CONFIG_NO_VERIFY=0     exit=0 integrity_failed=false installed=true   <- verification off
BUN_CONFIG_NO_VERIFY=1     exit=1 integrity_failed=true  installed=false  <- verification still on

With this branch the two env var rows flip (=0 rejects the tarball, =1 and =true install it); the first two rows are unchanged. The two new BUN_CONFIG_NO_VERIFY cases in test/cli/install/bun-install-tarball-integrity.test.ts fail on main and pass here.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — one-character polarity fix aligning BUN_CONFIG_NO_VERIFY with the three BUN_CONFIG_SKIP_* env vars directly above it.

What was reviewed:

  • Confirmed BUN_CONFIG_NO_VERIFY appears nowhere else in the repo (src, tests, harness, docs), so the polarity flip has no collateral impact.
  • The three new tests reuse the existing serveManifest/projectDir helpers and drain/assert pattern from the same describe block; the =1 and =0 cases each fail on main for the reason stated.
  • --no-verify is applied after the env var in Options::load, so CLI-flag precedence is unchanged; disabling verification via env adds no capability beyond the already-documented --no-verify.
Extended reasoning...

Overview

Single behavioral change at src/install/PackageManager/PackageManagerOptions.rs:672: check_bool != b"0" → check_bool == b"0". This makes BUN_CONFIG_NO_VERIFY=<truthy> clear Do::VERIFY_INTEGRITY (skip integrity checks) and BUN_CONFIG_NO_VERIFY=0 keep it set — the same reading used by BUN_CONFIG_SKIP_SAVE_LOCKFILE, BUN_CONFIG_SKIP_LOAD_LOCKFILE, and BUN_CONFIG_SKIP_INSTALL_PACKAGES in the immediately preceding lines. Three tests are added to test/cli/install/bun-install-tarball-integrity.test.ts inside the existing tarball integrity metadata forms describe block, covering --no-verify, BUN_CONFIG_NO_VERIFY=1, and BUN_CONFIG_NO_VERIFY=0 against a registry that advertises a mismatched sha512.

Security risks

None introduced. The change makes it possible to disable tarball integrity verification via an env var, but that capability already exists via the documented --no-verify CLI flag (handled a few dozen lines later in the same function), and the env var itself already existed — it just had inverted polarity. Grep confirms the env var is undocumented and unused elsewhere in the repo, so no CI/test was silently relying on the old inverted behavior to keep verification on.

Level of scrutiny

Low. This is a one-token bug fix that brings one env var in line with three identically-shaped siblings right above it. The fix is mechanically obvious once the bug is stated, and the PR description traces the inversion back to the 2022 commit that introduced it. The tests are the bulk of the diff and follow the file's existing conventions exactly (same tarball builder, same local Bun.serve registry, same Promise.all pipe drain, describe.concurrent, per-test cache dir).

Other factors

  • Repo-wide grep confirms this is the only read of BUN_CONFIG_NO_VERIFY; bunEnv/harness does not set it, so flipping polarity cannot break other tests.
  • CLI --no-verify is applied after the env-var block in Options::load, so flag-overrides-env precedence is preserved.
  • The new tests satisfy the review guide's "cover the variant matrix" rule (env=1, env=0, and the CLI flag they mirror) and each has a clear fails-on-main / passes-here direction per the PR description.
  • No prior human or bot reviews on this PR beyond a CodeRabbit rate-limit notice.

This branch has not been deployed

No deployments
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.

2 participants