v11.4.0
Breaking Changes📦 pnpmView on GitHub →
⚠ 1 breaking✨ 2 features🐛 10 fixes⚡ 1 deprecations🔧 3 symbols
Summary
This release significantly hardens security by enforcing tarball integrity checks by default and preventing credential leakage across registries. It also fixes several vulnerabilities related to malicious lockfile entries and patch files.
⚠️ Breaking Changes
- Tarball integrity mismatches against the lockfile now cause `pnpm install` (non-frozen) to fail hard with `ERR_PNPM_TARBALL_INTEGRITY` instead of silently overwriting the lockfile integrity. To refresh locked integrity values, use the new opt-in flag: `pnpm install --update-checksums`.
Migration Steps
- If you rely on unscoped credentials (like `_authToken`) in your configuration files, rewrite them to be URL-scoped (e.g., prefix them with `//registry.example.com/`).
- If you need to refresh locked integrity values without bypassing other integrity checks, use `pnpm install --update-checksums` instead of relying on silent overwrites.
✨ New Features
- Introduced the opt-in flag `--update-checksums` for `pnpm install` to allow refreshing locked integrity values from the registry without bypassing integrity checks for other operations.
- `pnpm runtime set <name> <version>` now defaults to saving the runtime configuration to `devEngines.runtime`. Use `--save-prod` or `-P` to save it to `engines.runtime` instead.
🐛 Bug Fixes
- Fixed a critical credential disclosure issue where unscoped credentials (`_authToken`, `_auth`, etc.) defined in one source (e.g., `~/.npmrc`) could be sent to an unrelated registry specified in another source. Credentials are now URL-scoped at load time.
- Fixed `pnpm deploy` crashing with `ENOENT` when `configDependencies` declares pacquet, by skipping the installation of config dependencies in the deploy directory.
- Rejected git resolutions where the `commit` field is not a 40-character hexadecimal SHA to prevent command injection via smuggled values in `git fetch`/`git checkout`.
- Limited concurrent project manifest reads during large workspace listing to prevent `EMFILE` errors.
- Rejected patch files whose `diff --git` headers reference paths outside the patched package directory to prevent arbitrary file modification.
- Improved the log message when `minimumReleaseAge` is set without `minimumReleaseAgeStrict`, clarifying that setting `minimumReleaseAgeStrict: true` is required to gate updates behind a prompt.
- Rejected dependency aliases containing path-traversal segments (e.g., `../../`) to prevent creating symlinks outside the `node_modules` directory.
- Rejected `pnpm-lock.yaml` entries where the remote tarball `resolution:` block is missing the `integrity` field, failing closed to prevent unverified content installation.
- Validated `devEngines.runtime` and `engines.runtime` version ranges for `node`, `deno`, and `bun` when `onFail` is set to `error` or `warn`; these modes now correctly enforce version checks.
- Require provenance before treating trusted publisher metadata as the strongest trust evidence.
Affected Symbols
⚡ Deprecations
- Unscoped per-registry settings like `_authToken`, `_auth`, `username`, `_password`, and `tokenHelper` are being phased out and will be removed in a future major release. Users must rewrite these settings to be URL-scoped (e.g., `//registry.example.com/:_authToken=...`). A deprecation warning is emitted when an unscoped credential is found, indicating where it was pinned and how to write it correctly.