Pnpm has a new setting to stave off supply chain attacks

by ivanbon 9/18/2025, 7:12 AMwith 146 comments

by postepowanieadmon 9/18/2025, 8:05 AM

If everyone is going to wait 3 days before installing the latest version of a compromised package, it will take more than 3 days to detect an incident.

by omnicognateon 9/18/2025, 8:26 AM

Should have included the units in the name or required a choice of unit to be selected as part of the value. Sorry, just a bugbear of mine.

by the_mitsuhikoon 9/18/2025, 10:08 AM

I think uv should get some credit for being an early supporter of this. They originally added it as a hidden way to create stable fixtures for their own tests, but it has become a pretty popular flag to use.

This for instance will only install packages that are older than 14 days:

uv sync --exclude-newer $(date -u -v-14d '+%Y-%m-%dT%H:%M:%SZ')

It's great to see this kind of stuff being adopted in more places.

by dwoldrichon 9/18/2025, 7:54 PM

I am an npm user. My reaction to these software supply chain attacks is to stop taking updates unless absolutely necessary for vulnerability mitigation or to selectively take performance or feature upgrades on a package-by-package basis. Obviously, that approach still opens me up to attacks based on when I choose to take updates that coincides with a malicious package release, but I feel like an extreme reluctance to upgrade will mostly keep me safe.

To achieve my goal, would this approach work:

- Pin all of my package.json versions (no prefacing versions with ~ or ^)

- Routine installation of packages both on my local and on CI servers will be done using `npm ci`

- `npm install <package_name> --save-exact/--save-dev` would be used only at the time of adding a package to package.json, followed by an `npm ci`

- Rely on tooling like GitHub Dependabot and CodeQL to inform the team when a dependency should be updated for security reasons and then manually update only the dependency with the desired version using `npm install lodash@4.17.21 --save-exact`, for example

EDIT: Thinking about this more, we would have to forbid deleting the package-lock.json and regenerating it with `npm install` and forbid the use of `npm update` so that package-lock.json would stay stable.

by OskarSon 9/18/2025, 8:37 AM

I have a question: when I’ve seen people discussing this setting, people talk about using like ”3 days” or ”7 days” as the timeout, which seems insanely short to me for production use. As a C++ developer, I would be hesitant to use any dependency in the first six months of release in production, unless there’s some critical CVE or something (then again, we make client side applications with essentially no networking, so security isn’t as critical for us, stability is much more important).

Does the JS ecosystem really move so fast that you can’t wait a month or two before updating your packages?

by calyhreon 9/18/2025, 3:34 PM

Yarn just landed a similar feature too https://github.com/yarnpkg/berry/pull/6901

by kerafon 9/18/2025, 10:08 AM

I might be naive but why isn't any package manager (npm, pnpm, bun, yarn, ...) pushing for a permission system, where packages have to define in the package.json what permission they would like to access? À la Deno but scoped to dependencies or like mobile apps do with their manifest.

I know it would take time for packages to adopt this but it could be implemented as parameters when installing a new dependency, like `npm i ping --allow-net`. I wouldn't give a library like chalk access to I/O, processes or network.

by nicoburnson 9/18/2025, 4:04 PM

I feel like the correct solution to these problems (across NPM and all similar package managers) is a web-of-trust audit system based on:

- Reviewing the source code in the actual published package

- Tooling that enable one to easily see a trusted diff between a package version and the previous version of that package

- Built-in support in the package manager CLIs to only install packages that have a sufficient number of manual reviews from trusted sources (+ no / not too many negative reviews). With manual review required to bypass these checks.

There are enough users of each package that such a system should not be too onerous on users once the infrastructure was in place.

by Ozzie_osmanon 9/18/2025, 12:21 PM

Does anyone understand why npm isn't adding these sorts of features?

by gausswhoon 9/18/2025, 9:15 AM

'Delayed dependency updates' is a response to supply-side attacks in the JavaScript world, but it aptly describes how I have come to approach technology broadly.

Large tech companies, as with most industry, have realized most people will pay with their privacy and data long before they'll pay with money. We live in a time of the Attention Currency, after all.

But you don't need to be a canary to live a technology-enabled life. Much software that you pay with your privacy and data has free or cheap open-source alternatives that approach the same or higher quality. When you orient your way of consuming to 'eh, I can wait till the version that respects me is built', life becomes more enjoyable in myriad ways.

I don't take this to absolute levels. I pay for fancy pants LLM's, currently. But I look forward to the day not too far away where I can get today's quality for libre in my homelab.

by h4ch1on 9/18/2025, 10:50 AM

https://github.com/oven-sh/bun/issues/22679

There's an open discussion about adding something similar to bun as well^

minimumReleaseAge doesn't seem to be a bulletproof solution so there's still some research/testing to be done in this area

by kardianoson 9/18/2025, 5:58 PM

It seems like the core problem is (1) NPM node_modules is so large usually, no one actually audit them and (2) the NPM churn is so great, no one audits them and (3) the design of NPM appears to think that automatically updating point or minor versions is actually good and desirable.

Go is one of the few packing systems that got these right.

by chr15mon 9/18/2025, 12:00 PM

The correct value for this setting is infinity seconds. Upgrades should be considered and deliberate, not automatic.

by tripplyonson 9/18/2025, 2:33 PM

If I run:

pnpm config set -g minimumReleaseAge 1440

Does that work as well? I can't tell if the global settings are the same as workspace settings, and it lets me set nonsense keys this way, so I'm not sure if there is a global equivalent.

by Flimmon 9/18/2025, 7:16 PM

How is the age of a package calculated? If the publishing date of a package is obtained from the package's metadata defined by the package author, (just like Git commit dates are defined by the Git committer), then that would defeat the purpose of this new feature. The whole purpose of this feature is to protect from malicious or compromised package authors. Instead, it is necessary to query the package registry, trusting the package registry for the age of the package, rather than the package author. I presume this is how it works.

by wallraton 9/18/2025, 9:30 AM

There are a few commercial products that allow you to do this also for other ecosystems (e.g. maven, nuget, pypi etc), including ours https://docs.bytesafe.dev/policies/delay-upstream/

Good to see some OSS alternatives showing up!

by mceachenon 9/18/2025, 5:05 PM

npm-check-updates has a PR for --cooldown as well: https://github.com/raineorshine/npm-check-updates/pull/1547

by _betty_on 9/18/2025, 9:32 AM

how about requiring some kind of interaction if they want to run an install script?

by tuananhon 9/18/2025, 12:39 PM

in corp settings, you usually have a proxy registry. you can setup firewall there for this kind of things to filter out based on license, cve, release date, etc...

by lloydatkinsonon 9/18/2025, 2:52 PM

Why must this be in a workspace file which you may not even have if you aren't in a monorepo, why not in package.json? Anyway, it's progress.

by bamboozledon 9/18/2025, 11:36 AM

Can anyone tell me if yarn just as vulnerable as NPM? Isn't it the packages that are vulnerable and not the package manger software itself?

by sim7c00on 9/18/2025, 7:32 PM

just dont use latest... old oackages can be malicious, benign ones tho... they get malicious generally on 'latest'. not on old versions.

maybe its better to disallow latest than use age as a metric.

by NamlchakKhandroon 9/18/2025, 1:12 PM

npm is now the tutorial filter.

If I see someone using npm as a cli tool unironically...

by user1999919on 9/18/2025, 1:04 PM

but what will we ever do without our: "developers are lazy, developers are dumb, left-pad degeneracy!"

by __MatrixMan__on 9/18/2025, 10:58 AM

Its not a bad idea, might help in certain cases.

But the real solution to this kind of attack is to stop resolving packages by name and instead resolve them by hash, then binding a name to that hash for local use.

That would of course be a whole different, mostly unexplored, world, but there's just no getting around the fact that blindly accepting updated versions of something based on its name is always going to create juicy attack surface around the resolution of that name to some bits.

by progxon 9/18/2025, 8:41 AM

That solve not really the problem.

A better (not perfect) solution: Every package should by AI analysed on an update before it is public available, to detect dangerous code and set a rating.

In package.json should be a rating defined, when remote package is below that value it could be updated, if it is higher a warning should appear.

But this will cost, but i hope, that companies like github, etc. will allow package-Repositories to use their services for free. Or we should find a way, to distribute this services to us (the users and devs) like a BOINC-Client.