Repository navigation
Conversation
|
Updated 11:01 PM PT - Oct 21st, 2026
✅ @robobun, your commit 6016ffc332b27df62b1634deaaa9a371f82df67a passed in 🧪 To try this PR locally: bunx bun-pr 46143That installs a local version of the PR into your bun-46143 --bun |
|
Status: draft. The third head (6016ffc) is pushed. A self-review of it is in progress. What changed from the first head.
The second head (0573dd0) saved the lockfile once on a plain How it was reproduced. A project depends on The tests are in the |
1485766 to
0573dd0
Compare
…in the lockfile A tarball, git or GitHub row has a URL or a commit where a registry row has a version. `bun install` now records the `version` of the package's package.json in the row: a `"version"` key in bun.lock, and a slot of `Meta` that nothing assigned in bun.lockb. There is no lockfileVersion bump: an older bun ignores the key. A row that has no version gets it when the lockfile is saved, from the package.json of the row's cache entry. That entry is named after the commit or the integrity of the row, so it has the bytes that the lockfile pins. The version is recorded only when the package declares the name that the row has. No install saves the lockfile only to add a version. The package-lock.json and pnpm-lock.yaml migrators record the version that the other lockfile states, for a row that has a commit or an integrity.
`bun audit` and `bun audit fix` skipped every row that is not a registry package. They now send a tarball, git or GitHub row under its name and its recorded version. A tarball row at the URL that the registry serves its name from is sent with the version in the URL. A row with no recorded version is named in a warning and counted as `not audited`. It does not change the exit code. A registry matches these copies by name only. The report says where such a copy came from. A malware advisory (CWE-506) for a name that the project has from a tarball, git or GitHub only is a warning, and it is not counted. `bun audit fix` lists a vulnerable tarball or git copy under `pinned to a tarball or a commit, not changed`.
0573dd0 to
6016ffc
Compare
Problem
bun auditskips every package from a tarball, git or GitHub:No vulnerabilities found (checked 0 packages), exit 0.collect_packages_for_auditskips them (src/runtime/cli/audit_command.rs:456on main).Fix
bun installrecords thepackage.jsonversion in the row: a"version"key inbun.lock, an unused slot inbun.lockb.bun auditandbun audit fixsend the row under that name and version, or under the version in a registry tarball URL.test/cli/install/bun-audit.test.ts(45 new tests), 39 other install test files (Notes).Background
pkg@1.2.3). These rows have a URL or a commit there.node_modulesat audit time: a frozen CI install can have no copy.Downsides
bun auditwarns about an older lockfile until Bun next saves it (bun install --lockfile-onlydoes). An older Bun drops the key again.bun auditand in a lockfile save. +29 KB.text(Notes).Notes
Cost for a project with registry packages only. Release builds of main 491aaad and of this head (6016ffc), built on the same machine on 2026-10-22. 2,000 packages, loopback registry. Instructions are user-mode counts over interleaved pairs, with the standard deviation of the pair differences.
bun.lockbun.lockbbun audit, file syscallsbun audit, allocation callsbun audit, instructions (60 pairs)bun pm hash(loadsbun.lock), instructions (40 pairs)bun install --lockfile-only(load and save), allocation callsbun install --lockfile-only, instructions (40 pairs).textbun auditgrows with the number of packages: +27,000 instructions for 500 packages, +186,000 for 4,000, and none for one. That is about 47 instructions for each package.bun auditmade 72 or 73 file syscalls on either build.bun auditmakes the same 72 file syscalls.perf_event_openfor the instruction counts,ptracefor the syscall counts, gdb breakpoints on the mimalloc entry points for the allocation counts.perf,strace,valgrindandbloatyare not on the machine.What is sent. Against a loopback registry,
vul@1.0.0with an advisory for<2.0.0:vul@1.0.0from the registry{}{"vul":["1.0.0"]}file:tarballgit+file:repositorynode_modulesand cache deletedgithub:dependency has the same result in the new test (sends a package that came from GitHub, stub API).nameandversionof itspackage.json, as written there. A package with noversionis not sent, as with npm (shouldAuditin@npmcli/arborist/lib/audit-report.js).<registry>/<name>/-/<name>-<version>.tgz, for the registry of that name or for the public registry, is sent with the version in the URL. A released Bun wrote such rows when it migrated ayarn.lock, andbun add <that URL>writes one. The URL has to be exactly what Bun builds for that name and version.bun audit fixlists a vulnerable tarball or git copy underpinned to a tarball or a commit, not changed, with its resolution. It counts as remaining. The key in--jsonispinned.Matches by name. A registry knows these copies by name and version only.
1.0.0 from github:owner/vul#abc1234, matched by name.npm:packages (plugin-npm-cli/sources/npmAuditUtils.ts).Rows with no recorded version. A
bun.lockorbun.lockbfrom an older Bun:bun audit: a warning that names each row that a dependency leads to,N not auditedin the summary, and the exit code of the other packages.bun audit fix --dry-run --jsonlists the rows underunrecorded.--silentprints no warning.package.jsonof its cache entry. The entry is named after the commit or the integrity of the row, so it has the bytes that the lockfile pins.overrides.test.ts(a bun.lock written by Bun 1.4 ... bun install and --frozen-lockfile say nothing) andbun-install-git-deps.test.ts(Nothing changed, so nothing is saved) test that. The second head of this PR saved once on a plain install and failed the first of them in CI.bun install --lockfile-onlysaves the lockfile and changes nothing else. The warning names that command.bun/Dockerfilein dependabot-core), so each of its PRs drops the key, and the next save with a newer Bun writes it back.Limits.
bun installit is.yarn.lockmigrators name a row after the dependency or the repository.bun update <dependency>resolves it again under the declared name.MAX_LENGTH) is recorded as no version.bun auditandbun audit fixread the record.Lockfile::package_version, the install-time security scanner andbun install --yarnstill see the URL or the commit.Migrated lockfiles. The package-lock.json and pnpm-lock.yaml migrators record the version that the other lockfile states, for a row that has a commit or an integrity. A package-lock node with no
versionstays unrecorded: the arborist fixtureexternal-link-depin this repository has such a node forabbrev@1.1.1. The yarn migrators record nothing, becauseyarn.lockdoes not state the name that the package declares. The save at the end of the migrating install does.Questions for a maintainer.
bun audit --jsonprints{}and exits 0 for such a project, as on main.versionkey inbun.lock, with nolockfileVersionbump. install: fix regressions and older bugs found after the package manager consolidation #45307 addedhasInstallScriptto the same object in the same way. An older Bun reads a lockfile with the key and ignores it. Should a plainbun installsave an older lockfile once to add the key? This PR does not, because of the two tests above.Self-review. A self-review of the first head raised 37 concerns. This head addresses 34. Not done: (1) An install does not copy
binandhasInstallScriptfrom thepackage.jsoninto a migrated row. That is a separate bug with its own fix. (2) A package-lock node with noversionis not read as a package with no version, for the reason under Migrated lockfiles. (3) Rows with no version keep their ownunrecordedlist.unauditedis a list of registries that did not answer. A self-review of this head is in progress.Tests. On a debug build of this head, with a raised timeout for each test:
bun-audit.test.ts(302 tests) and 39 other files intest/cli/installpass. They are overrides, bun-install, bun-install-registry, bun-install-git-deps, bun-install-tarball-integrity, bun-install-lifecycle-scripts, bun-lock, bun-lockb, bun-workspaces, bun-add, bun-add-catalog, bun-add-filter, bun-update, bun-update-transitive, bun-update-security-provider, bun-dedupe, bun-pm-scan, bun-pm-why, bun-pm-fetch, hoist, catalogs, lockfile-version-2, minimum-release-age, redacted-config-logs, GHSA-pfwx-36v6-832x, migrate-bun-lockb-v2, the three frozen-lockfile files, and the 10 files inmigration/. On a release build of main 491aaad, the 45 tests of the new block fail. On a release build of this head they pass.bun-types.test.tspasses (24 tests). The three next-pages snapshots were not run.Related. #45668 changes how
bun auditranks an unknown severity. It touches other regions ofaudit_command.rs. #46116 adds an early return tocollect_packages_for_auditfor a lockfile with no package. With both, that return has to keep the list of rows with no version. A later PR will match each advisory range against each installed copy. It builds onaudit_rows. A migrated tarball or git row also has nobin: that is a separate bug with its own fix.Debug dump. The lockfile debug dump prints
package_json_versionwhere it printedman_dir, a slot that nothing assigned. That renames one line per package in five snapshot files. The three next-pages snapshots were rewritten by a script.