Let me provide context, since a bunch of people responding with "every package manager can be hit!!!" npm, by design, allows all packages to run package supplied arbitrary code as the logged-in user after an update completes.
That's an INSANE default. pnpm, by contrast, allows you to essentially "opt-in" only specific packages that need this (e.g. four out of thirty, in one of our projects). Then tacks on tons of other security settings, like minimum age, no trust downgrade, etc etc.
All attackers can attack packages by updating how a package functions; but npm is particularly problematic as it runs non-sandbox scripts as the calling user. Putting not just your project at risk, but your entire machine/network.
And this stuff has been known about for YEARS, they've taken no action.
Furthering the idea that not all package managers are the same, there are entire cycles of the moon where I don't open nuget once. Some ecosystems simply don't need to vendor out very often, and these are the ones where you generally find the least news like this.
In about 99% of cases, I have the option to pick between Microsoft, a 3rd party or myself. I'm picking that first option every time I can. If M$ can't handle it, I'm hand rolling it.
Dapper remains the only constant 3rd party dependency in my projects. I don't know how much longer this will last with LLM assistance. The frontier models are very good at writing repositories over arbitrary sql schemas with low level primitives now.
> Furthering the idea that not all package managers are the same, there are entire cycles of the moon where I don't open nuget once. Some ecosystems simply don't need to vendor out very often, and these are the ones where you generally find the least news like this.
This however is only to some degree the package manager's fault. The JavaScript culture is strongly ordering tiny packages by individual people doing small things (left pad) rather than larger utilit libraries maintained by a larger community.
A larger community contributing to a larger library would mean that a larger community feels responsible and checks it.
That small package mentality a trace to web usage: JavaScirpt code is often sent to the client, not having a huge library but having small dedicated libraries means that it is a lot simpler for the bundler to not bundle dead code which is sent to the browser client.
With server side Node.js this lead to tons of dependencies ... which is worsened by npm allowing to have multiple versions of the same package in parallel. So if something depends on leftpad 1.0 and something else in leftpad 1.1 both are fetched and both are available.
Regarding npm CLIENTS, PNPM is fundamentally different from (and superior to) npm or yarn.
Strongest possible recommendation to use pnpm.
It's also a good idea to use a private registry (eg via jfrog), acting as a proxy / pull-through cache, and point trad SAST and maybe AI scanners at it.
But dropping the npm client in favor of pnpm is a no-brainer. Speed, disk space, security, determinism, flexibility, fine-grained control over your dependency graph...
>Putting not just your project at risk, but your entire machine/network.
Between average hackers and extortion groups, foreign governments and state sponsored actors and last but not least my own government, I don't think there's much room left for non-compromised supply chains these days. Treat everything that can run foreign code as potentially compromized and keep everything compartmentalized. If you keep your crypto wallets or private banking info on the same machine where you do development, you're asking to get shafted one day. Or if you keep your big corporate github keys on the same machine where you do private weekend projects. It doesn't matter what you use in particular, even if some vectors are currently more popular than others.
Not running lifecycle scripts by default is eventually going to be the default behavior. Late is worse than not at all. https://github.com/npm/rfcs/pull/868
It's also the standard, and by far it's the contrast to not allow this. pnpm has a massive advantage of being the non-standard package manager, npm does not have that - what do you suggest that npm does?
> since a bunch of people responding with "every package manager can be hit!!!" npm, by design, allows all packages to run package supplied arbitrary code as the logged-in user after an update completes.
But that's a "Perfect is the enemy of good"-like argument. Wherein: Why even reduce an easy to exploit attack surface when there could be holes elsewhere?! Because, you know, it makes things much more secure even if imperfect.
Plus, to me, it is a culture issue. npm just doesn't take security seriously, so we don't see these improvements, and if there was additional test hardening later, I don't expect we'd see them in npm either. Since, they just don't care.
The biggest problem is not software but culture, not at npm, but in the js ecosystem.
The js ecosystem is simply a juicy targets, the attack surface is enormous.
The attacker can make their attack more sophisticated,
there will always be a maintainer that can seed the worm spread.
Meanwhile in the nuget ecosystem is way smaller and have way less mainteners involved for a single given dependency.
Nearly every package manager I've ever used had post-install scripts. Most run as root, since that's what usually what the package manager runs as.
It's not unreasonable: you're already installing software, which presents risks. If post-install scripts were not a thing, a payload could still run because you ran the software you installed. Or because the installer added it to auto-run. Or because the installer placed it somewhere where it would be dynamically loaded all the time.
Most package managers with postinstall scripts are also heavily curated and have reputation systems. As you say, they run as root, so the high trust requirement is definitely warranted. Anyone can upload an npm package.
I think it’s just a bundle of issues. Deep graph of dependencies, distribution of minimized code (java has jars, but I don’t remember scripts), and nearly impossible to audit. With most projects in other ecosytems, you only have to interact with a few developer/orgs. But with npm, you add one library and you need to essentially trust 10s of entities on the internet.
Nearly every package manager I've ever used had post-install scripts.
You're collapsing two different threat models. The risk isn't that code runs, it's WHEN it runs.
This worm spreads because npm install runs arbitrary scripts as you, automatically, just from resolving the tree. You don't have to build it, run it, or even import it. Opening the project in an IDE is enough.
apt/dnf scripts run on packages a maintainer signed and a distro gatekept. Not on whatever some rando pushed to a public scope 20 minutes ago that landed in your lockfile six levels deep.
"They both technically execute code" is true and beside the point. One runs signed code from a trusted path, the other runs unsigned code from the default automated path. That's the whole ballgame.
> You're collapsing two different threat models. The risk isn't that code runs, it's WHEN it runs.
> You don't have to build it, run it, or even import it
If you just installed something with npm, chances are you'll be running it shortly, either as a tool or a library, probably minutes or seconds later. I imagine the contingent of folks who explicitly install an npm package they don't plan on using, is pretty small.
The big attacks of today are spread across several package ecosystems: TrapDoor and Shai-Hulud have been hitting npm, pypi, composer, and crates with the same malware.
Regardless of what these attacks exploit, see elsewhere a larping comment of mine: the solution exists, the implementation already mitigated numerous such and other exploits (it's nice to read "nix is not affected" on discourse or over matrix chat), it predates Docker by a decade, and is older than Ubuntu and Fedora (to give the perspective), yet people prefer to remain ignorant.
The problem is compounded with NPM though thanks to lifecycle scripts: yes, any and all package managers create a risk of supply-chain attack, but NPM makes it dangerous to merely open a project up in an IDE.
It is the same for Crates.io and PyPI they also supply scripts without asking the user so opening an IDE will run them. For PyPI you need to even execute scripts to discover the dependencies!
That's a good point. For me it's getting people to realize they need to take up practice that help minimize these things. It's kinda us and them problem.
We need to ensure we don't just blindly install the latest, patch every CVE by just bumping everything to the latest even if the vulnerability has nothing to do with their system or use of said library.
We should have rules that we install the latest that's older than three days.
We should be running "npm audit" and other stuff like Trivy.
On the other hand, if the same problem keeps happening, it's hard to argue that the problem isn't foundational to the design and that it should be called out until either the problem is fixed or the design abandoned.
It's not that there isn't a conversation to be had. It's that it's a low-effort, karma farming, reddit-tier comment that always invites emotional/reactionary responses, typically the same ones as before, that usually shoots to the top of the comments section and drowns out any relevant or interesting (see: curious, as per HN guidelines) discussion.
All programming language package managers are vulnerable. They all have the exact same caveats as the Arch Linux User Repository. There are no trusted maintainers taking responsibility for things. Any random person can make an account and push packages.
I think this is a thought-terminating cliche, and false equivalences. Stating "This area where problems occur at a high rate is not a problem, as problems can happen elsewhere too" is a curt dismissal of a valid concern. It implies the course of action, rather than to address a high-problem area, is to ignore any solutions which aren't global, or equate it to lower-incidence areas.
You bring up a good point that this class of problem, or related ones can occur with other package managers. It was frustrating how long it took the Crates.io team (Rust manager) to address name squatting, in what appeared to be a "no perfect solution exists, so we won't act" line of reasoning.
Eh, it's worse than that. The GP comment is repeating a joke derived from an Onion headline about gun control. Where the very poignant message is about political will to make change. However, the npm ecosystem is very much willing and has already made several changes. If we're going to engage in discussion instead of meme-posting, the GP should have (imo) included real commentary _in addition to_ the meme they really wanted to post. What is the policy they want? Why do they see the NPM ecosystem as still resistant to change?
One easy change would be that before any package can be published, it has to wait a minimum of two weeks in a state where it can be reviewed but it can't be installed without jumping through several hoops with big warning signs, things like "INSTALL_INTENTIONALLY_DANGEROUS_PACKAGES_THAT_WILL_BREAK_MY_COMPUTER=1", selecting yes in a dialogue that asks if they want to install software that likely has viruses, and pointing to a different package repository URL.
If there's some change that must get out sooner, then there can be some fee to pay to npm to have their security team do their own review.
Critically, there must be time for someone to review before it's the default to be selected.
I'm sure there are issues with this, this was off my head, but it seems like a really easy step to at least stem the problem for now. And there are a bunch of ideas like this that would help, but NPM doesn't seem willing to take it seriously as an existential threat to the ecosystem, rather than taking trivial steps.
Linux distributions have trusted maintainers who are responsible for their packages. People who cared enough to figure out PGP and set up an actual web of trust. That's where the verification happens. All these programming language package managers have nothing of the sort. PyPI, Rubygems, crates, npm, it doesn't matter. I can just make an account and push whatever I want.
These package managers are like this because that's what developers actually want. They don't want to deal with Linux distribution maintainers in order to get their software into the official repositories. They want to just run $packager push and have it out there with zero friction.
They didn't back up their meme with real commentary because they have no real commentary to stand on:
They're spreading cheap disdain & scorn for npm ("only package manager" framing). But most other package management systems have similar abilities to run pretty un-sandboxed code.
While true, tarring Arch here is a little unfair. AUR isn't enabled by default. It can't even be used via the same package front end, and in fact the "official" usage model requires that you clone the source yourself.
Indeed, AUR is bad as a software distribution mechanism (really it's best understood as a proving ground for baby packages before they get real maintainers and distro blessing), but it's less bad than NPM which puts the malware in the trusted/default/automated path.
Our company uses yarn 4 which has an option to prevent you from installing an npm package for the first number of days of its release. Most of these seem to be caught within that timeframe (1-3 days).
There is something to be said about the need to keep all the packages as the latest and the greatest at all times. Every minor version update doesn’t need to be immediately applied. And maybe high and critical vulnerabilities don’t need to be a minor version upgrade.
I’m having a real problem at work with security theatre and the growing push to obsess over numbers of “vulnerabilities” in our projects. And then auto Dependabot PRs that encourage churn to fix issues that if an informed person actually reviews easily concludes it doesn’t affect us in the slightest.
The one week cooldown option is not relying on other users to be a canary for you. Its just giving automated scanners a chance to notice. This is the perfect example. I don't think step security found this by accident. They are actively monitoring NPM package releases at some level.
There is something to be said that Microsoft should be scanning packages pre-release. They aren't, though, so for right now there is a ton of value with very little downside if people implement a one week cooldown period.
To answer your question directly, though. If everyone else moves to a one week cooldown, I would absolutely suggest a two week cooldown is a good idea. Being the "slow" moving organization is a good security trade-off so long as you don't take it to extremes and have escape hatches when you actually need to be moving quickly.
Thank you for the thorough response. I got the following from yours and other responses:
* The JS ecosystem has been and will most likely continue to be fast-moving, so it's quite a safe assumption that at no point will a quarantine period be wide-spread.
* This quarantine period is for (semi-)automated scanners to catch the issue. Although considering the above there will always be a non-zero amount of end-user canaries as well.
* Maybe NPM should run scanners before distributing malware?
* If the ecosystem by any chance adopts a week-long quarantine period, you'd be safer if you applied a longer quarantine period.
A large array of automated and semi-automated security scanners are finding things quickly. The main benefit of waiting before updating is to give those scanners time to work.
@exitb it is much more desirable for security scanning companies to compete to find issues in a timely manor. If npm blessed one as a gatekeeper to the whole system they would be between a rock and a hard place. Unable to priorities high impact packages over the long tail of packages no one uses without pissing people off. Unable to add experimental new detections that may be a little noisy at first due to the huge disruption it would cause. Be trivial to game as obscure packages could brute-force their way though then use the same hole on a mainstream package.
I think the key right now is that these are semi-automated scanning processes. Right now, companies like step security selectively publish. So, in order for a hacking group to find out if their malware is detected or not, they have to burn access to a useful package.
None of this is to say I think Microsoft shouldn't be doing something as part of the release process on NPM. However, there is real value in giving more independent third parties a window to do things semi-manually.
Then the ... malware will just add delays? Or do they really do manual in-depth analysis of all new code? Just running and seeing it do things is probably a lot easier.
Security scans and authors realizing an unauthorized version was pushed will generally happen regardless of whether regular users updated. Even for compromises that are found by users updating, it'd generally be better to reduce the number of people affected with a slow roll-out rather than everyone jumping on at once.
It does make sense that the right way would be to fork every dependency you use and install from your own repo reviewing and merging from upstream as needed. Would be a giant PITA though. :)
Nothing that couldn't be automated; in Go land this is (arguably) called vendoring (https://go.dev/ref/mod#vendoring). Good to offload or reduce dependencies on 3rd party dependency hosters, pull a dependency into your own code review tools, and to ensure reproducible builds long term.
I mean there’s nothing stopping you from committing node_modules to git (after running something like https://github.com/timoxley/cruft on it) and reviewing code changes on dependency updates.
I even managed to make that part of the workflow on one team I worked with but several other teams since thought it was a crazy idea. :)
I think the general idea that your supply chain should be rooted in source repositories and associated commit hashes is the right one. Tooling can be made to automate the process of putting together a product from those defined sources. Some languages/systems already have some support for this. E.g. Golang and Rust. The concept of a "binary" artifact is really dead now everyone uses git and builds are quick. It lives on in things like npm and docker hub but we don't actually need it.
For smaller shops (by small I mean <1,000 employees) this isn't even tenable. We (engineering team of about 10 people) mitigate what we can via tooling and cooldown periods/minimum release age. This will work as long as these malicious packages remain reasonably detectable. I think that's the proper balance, because we can adjust the # of days we are willing to risk against the SOTA of detection tooling.
I've made it a habit now to use the --before=2026-05-30 flag when installing packages, where it'll pick the version released before the date you specify, I usually pick around 5 days ago
One thing I've never understood is why NPM allows packages to run code immediately after they are installed. What's the use case for that? A package should just be some code you can call on at runtime
I'm refactoring all my personal and research projects to utilize pure HTML/CSS without any dependency of JavaScript. This was always on the table but the cybersecurity risks from all programming languages and frameworks have increased due to AI.
I know of fundamental issues with JavaScript and see no reason why it's still standard on all web browsers.
Chainguard based images, packages and libraries are first line of defense. Expensive? Yes. Foolproof? No. I think these types services will be mandatory in the near future.
How would that help? These are not general purpose, base system libraries, these are libraries specific to a product that uses them. Either you're not using them and hence they would not be installed in the first place, or you're using them because you have the product installed.
Though I would expect that Insights uses RPM packages to ship components and not the public NPM packages.
Proof that we shouldn't worry about bad AI code and decisions because we have already been suffering from amateur JavaScript devs for at least 15 years.
This repository itself had to previously update from the axios supply chain attack [0] (co-authored by Claude lol). But just by looking at the change itself, the package is unpinned and won't solve the problem if another malicious security update happens again.
So if you have an unpinned version of this package and you run 'npm install', you immediately downloaded the compromised version and that's that.
'No Way to Prevent This,' Says Only package manager Where This Regularly Happens
Edit: some people don't understand that it's a defence to https://en.wikipedia.org/wiki/%27No_Way_to_Prevent_This,%27_...
Let me provide context, since a bunch of people responding with "every package manager can be hit!!!" npm, by design, allows all packages to run package supplied arbitrary code as the logged-in user after an update completes.
That's an INSANE default. pnpm, by contrast, allows you to essentially "opt-in" only specific packages that need this (e.g. four out of thirty, in one of our projects). Then tacks on tons of other security settings, like minimum age, no trust downgrade, etc etc.
All attackers can attack packages by updating how a package functions; but npm is particularly problematic as it runs non-sandbox scripts as the calling user. Putting not just your project at risk, but your entire machine/network.
And this stuff has been known about for YEARS, they've taken no action.
Furthering the idea that not all package managers are the same, there are entire cycles of the moon where I don't open nuget once. Some ecosystems simply don't need to vendor out very often, and these are the ones where you generally find the least news like this.
In about 99% of cases, I have the option to pick between Microsoft, a 3rd party or myself. I'm picking that first option every time I can. If M$ can't handle it, I'm hand rolling it.
Dapper remains the only constant 3rd party dependency in my projects. I don't know how much longer this will last with LLM assistance. The frontier models are very good at writing repositories over arbitrary sql schemas with low level primitives now.
> Furthering the idea that not all package managers are the same, there are entire cycles of the moon where I don't open nuget once. Some ecosystems simply don't need to vendor out very often, and these are the ones where you generally find the least news like this.
This however is only to some degree the package manager's fault. The JavaScript culture is strongly ordering tiny packages by individual people doing small things (left pad) rather than larger utilit libraries maintained by a larger community.
A larger community contributing to a larger library would mean that a larger community feels responsible and checks it.
That small package mentality a trace to web usage: JavaScirpt code is often sent to the client, not having a huge library but having small dedicated libraries means that it is a lot simpler for the bundler to not bundle dead code which is sent to the browser client.
With server side Node.js this lead to tons of dependencies ... which is worsened by npm allowing to have multiple versions of the same package in parallel. So if something depends on leftpad 1.0 and something else in leftpad 1.1 both are fetched and both are available.
Yes, this.
Regarding npm CLIENTS, PNPM is fundamentally different from (and superior to) npm or yarn.
Strongest possible recommendation to use pnpm.
It's also a good idea to use a private registry (eg via jfrog), acting as a proxy / pull-through cache, and point trad SAST and maybe AI scanners at it.
But dropping the npm client in favor of pnpm is a no-brainer. Speed, disk space, security, determinism, flexibility, fine-grained control over your dependency graph...
>Putting not just your project at risk, but your entire machine/network.
Between average hackers and extortion groups, foreign governments and state sponsored actors and last but not least my own government, I don't think there's much room left for non-compromised supply chains these days. Treat everything that can run foreign code as potentially compromized and keep everything compartmentalized. If you keep your crypto wallets or private banking info on the same machine where you do development, you're asking to get shafted one day. Or if you keep your big corporate github keys on the same machine where you do private weekend projects. It doesn't matter what you use in particular, even if some vectors are currently more popular than others.
> they've taken no action.
Not running lifecycle scripts by default is eventually going to be the default behavior. Late is worse than not at all. https://github.com/npm/rfcs/pull/868
Wait how is being late worse than not doing it at all? Is it true for mortgage payments and apologies?
> That's an INSANE default.
It's also the standard, and by far it's the contrast to not allow this. pnpm has a massive advantage of being the non-standard package manager, npm does not have that - what do you suggest that npm does?
> since a bunch of people responding with "every package manager can be hit!!!" npm, by design, allows all packages to run package supplied arbitrary code as the logged-in user after an update completes.
This is semi-common and in no way unique to NPM.
And even in the ones that don't, having to wait until the project executes to begin its attack is a minor inconvenience for malware.
Mosts packages manager, allow that.
pnpm can still be exposed, afterall the worm simply have to wait you run tests locally.
I suppose.
But that's a "Perfect is the enemy of good"-like argument. Wherein: Why even reduce an easy to exploit attack surface when there could be holes elsewhere?! Because, you know, it makes things much more secure even if imperfect.
Plus, to me, it is a culture issue. npm just doesn't take security seriously, so we don't see these improvements, and if there was additional test hardening later, I don't expect we'd see them in npm either. Since, they just don't care.
The biggest problem is not software but culture, not at npm, but in the js ecosystem. The js ecosystem is simply a juicy targets, the attack surface is enormous. The attacker can make their attack more sophisticated, there will always be a maintainer that can seed the worm spread.
Meanwhile in the nuget ecosystem is way smaller and have way less mainteners involved for a single given dependency.
Nearly every package manager I've ever used had post-install scripts. Most run as root, since that's what usually what the package manager runs as.
It's not unreasonable: you're already installing software, which presents risks. If post-install scripts were not a thing, a payload could still run because you ran the software you installed. Or because the installer added it to auto-run. Or because the installer placed it somewhere where it would be dynamically loaded all the time.
Most package managers with postinstall scripts are also heavily curated and have reputation systems. As you say, they run as root, so the high trust requirement is definitely warranted. Anyone can upload an npm package.
I think it’s just a bundle of issues. Deep graph of dependencies, distribution of minimized code (java has jars, but I don’t remember scripts), and nearly impossible to audit. With most projects in other ecosytems, you only have to interact with a few developer/orgs. But with npm, you add one library and you need to essentially trust 10s of entities on the internet.
Nearly every package manager I've ever used had post-install scripts.
You're collapsing two different threat models. The risk isn't that code runs, it's WHEN it runs. This worm spreads because npm install runs arbitrary scripts as you, automatically, just from resolving the tree. You don't have to build it, run it, or even import it. Opening the project in an IDE is enough. apt/dnf scripts run on packages a maintainer signed and a distro gatekept. Not on whatever some rando pushed to a public scope 20 minutes ago that landed in your lockfile six levels deep. "They both technically execute code" is true and beside the point. One runs signed code from a trusted path, the other runs unsigned code from the default automated path. That's the whole ballgame.
> You're collapsing two different threat models. The risk isn't that code runs, it's WHEN it runs.
> You don't have to build it, run it, or even import it
If you just installed something with npm, chances are you'll be running it shortly, either as a tool or a library, probably minutes or seconds later. I imagine the contingent of folks who explicitly install an npm package they don't plan on using, is pretty small.
The big attacks of today are spread across several package ecosystems: TrapDoor and Shai-Hulud have been hitting npm, pypi, composer, and crates with the same malware.
And all of them "thought" of security as an after-after-after-after-after-thought.
Most of these are now building upon techniques that have already been exploited since past 1 years. This attack used 4 of those techniques.
1. Lifecycle Hook Execution
2. CI/CD Identity Plane Attacks
3. Maintainer Account Takeover and Malicious Publish
4. Self-Replicating npm Worms
https://npm-supply-chain-attack-techniques.pagey.site/
Regardless of what these attacks exploit, see elsewhere a larping comment of mine: the solution exists, the implementation already mitigated numerous such and other exploits (it's nice to read "nix is not affected" on discourse or over matrix chat), it predates Docker by a decade, and is older than Ubuntu and Fedora (to give the perspective), yet people prefer to remain ignorant.
People make this joke often. It's package managers and how loose we are with installing them, not NPM.
Cargo,PyPi,Nuget,PHP has had these recent too.
It's not just only NPM. It's frequently repeated here just cause of the average bias against Node.
But this problem isn't isolated to NPM.
The problem is compounded with NPM though thanks to lifecycle scripts: yes, any and all package managers create a risk of supply-chain attack, but NPM makes it dangerous to merely open a project up in an IDE.
[delayed]
It is the same for Crates.io and PyPI they also supply scripts without asking the user so opening an IDE will run them. For PyPI you need to even execute scripts to discover the dependencies!
That's a good point. For me it's getting people to realize they need to take up practice that help minimize these things. It's kinda us and them problem.
We need to ensure we don't just blindly install the latest, patch every CVE by just bumping everything to the latest even if the vulnerability has nothing to do with their system or use of said library.
We should have rules that we install the latest that's older than three days.
We should be running "npm audit" and other stuff like Trivy.
The three day rule alone could save most people.
nuget have targets, and allow to run code on build, it doesn't have this problem because there is less dependencies.
How many package managers allow executing arbitrary code as part of the installation process by default?
There’s actually a blog post with that exact title.
https://kevinpatel.xyz/posts/no-way-to-prevent-this/
https://news.ycombinator.com/item?id=48155690
I've deleted and am rewriting this, to be more explicit, because HN downmodded the first comment to hell but I know I'm right and the crowd is wrong.
So, explicitly:
- pip
- Cargo
- apt/dpkg
- dnf/yum
- Homebrew
- RubyGems
- Composer (limited)
- Maven
...all allow scripts.
We understand the reference, it's just not correct: most package managers allow scripts, npm is the most successful package manager.
npm shouldn't allow scripts, but exploits happen everywhere.
PyPI and Cargo are, 100%, vulnerable to this same class of compromises. That NPM sucks isn't a statement that everyone else doesn't.
tbf this is happening with a lot of package managers now, including pypi and composer
Please stop posting this on every single security incident thread with npm. It was funny once, it's just rehashing the same debate over and over.
On the other hand, if the same problem keeps happening, it's hard to argue that the problem isn't foundational to the design and that it should be called out until either the problem is fixed or the design abandoned.
Opponents of gun control surely feel the same way about the Onion’s story.
Why should they stop? Maybe they want to rehash the issue that's not being adequately addressed. Maybe it's not supposed to be funny.
How do you propose we address this issue? Instead of policing what people say, are you interested in sharing your or someone else ideas?
It's not that there isn't a conversation to be had. It's that it's a low-effort, karma farming, reddit-tier comment that always invites emotional/reactionary responses, typically the same ones as before, that usually shoots to the top of the comments section and drowns out any relevant or interesting (see: curious, as per HN guidelines) discussion.
All programming language package managers are vulnerable. They all have the exact same caveats as the Arch Linux User Repository. There are no trusted maintainers taking responsibility for things. Any random person can make an account and push packages.
I think this is a thought-terminating cliche, and false equivalences. Stating "This area where problems occur at a high rate is not a problem, as problems can happen elsewhere too" is a curt dismissal of a valid concern. It implies the course of action, rather than to address a high-problem area, is to ignore any solutions which aren't global, or equate it to lower-incidence areas.
You bring up a good point that this class of problem, or related ones can occur with other package managers. It was frustrating how long it took the Crates.io team (Rust manager) to address name squatting, in what appeared to be a "no perfect solution exists, so we won't act" line of reasoning.
Eh, it's worse than that. The GP comment is repeating a joke derived from an Onion headline about gun control. Where the very poignant message is about political will to make change. However, the npm ecosystem is very much willing and has already made several changes. If we're going to engage in discussion instead of meme-posting, the GP should have (imo) included real commentary _in addition to_ the meme they really wanted to post. What is the policy they want? Why do they see the NPM ecosystem as still resistant to change?
One easy change would be that before any package can be published, it has to wait a minimum of two weeks in a state where it can be reviewed but it can't be installed without jumping through several hoops with big warning signs, things like "INSTALL_INTENTIONALLY_DANGEROUS_PACKAGES_THAT_WILL_BREAK_MY_COMPUTER=1", selecting yes in a dialogue that asks if they want to install software that likely has viruses, and pointing to a different package repository URL.
If there's some change that must get out sooner, then there can be some fee to pay to npm to have their security team do their own review.
Critically, there must be time for someone to review before it's the default to be selected.
I'm sure there are issues with this, this was off my head, but it seems like a really easy step to at least stem the problem for now. And there are a bunch of ideas like this that would help, but NPM doesn't seem willing to take it seriously as an existential threat to the ecosystem, rather than taking trivial steps.
> where it can be reviewed
By who? No one at npm is reviewing anything.
Linux distributions have trusted maintainers who are responsible for their packages. People who cared enough to figure out PGP and set up an actual web of trust. That's where the verification happens. All these programming language package managers have nothing of the sort. PyPI, Rubygems, crates, npm, it doesn't matter. I can just make an account and push whatever I want.
These package managers are like this because that's what developers actually want. They don't want to deal with Linux distribution maintainers in order to get their software into the official repositories. They want to just run $packager push and have it out there with zero friction.
They didn't back up their meme with real commentary because they have no real commentary to stand on:
They're spreading cheap disdain & scorn for npm ("only package manager" framing). But most other package management systems have similar abilities to run pretty un-sandboxed code.
TrapDoor has hit python, rust, and js repos. https://socket.dev/blog/trapdoor-crypto-stealer-npm-pypi-cra...
While true, tarring Arch here is a little unfair. AUR isn't enabled by default. It can't even be used via the same package front end, and in fact the "official" usage model requires that you clone the source yourself.
Indeed, AUR is bad as a software distribution mechanism (really it's best understood as a proving ground for baby packages before they get real maintainers and distro blessing), but it's less bad than NPM which puts the malware in the trusted/default/automated path.
I'm not tarring Arch, I was praising it. I made sure to explicitly spell out the "User Repository". Arch is the one that does it right.
I didn’t take it that way at all - rather, Arch is the only one that does it “right” with the AUR.
If you want a usable system, you enable AUR. It's not 'doing it right', it's avoiding responsibility.
Nix enters the room.
(Everyone claps.)
Our company uses yarn 4 which has an option to prevent you from installing an npm package for the first number of days of its release. Most of these seem to be caught within that timeframe (1-3 days).
https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e...
uv supports the same for any Python developers out there: https://docs.astral.sh/uv/concepts/resolution/#dependency-co...
pip has recently added a similar option, i.e.
`pip install --uploaded-prior-to P7D pre-commit`
https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-upl...
And somehow poetry doesn’t in 2026.
so? nobody uses it anymore
There is something to be said about the need to keep all the packages as the latest and the greatest at all times. Every minor version update doesn’t need to be immediately applied. And maybe high and critical vulnerabilities don’t need to be a minor version upgrade.
I’m having a real problem at work with security theatre and the growing push to obsess over numbers of “vulnerabilities” in our projects. And then auto Dependabot PRs that encourage churn to fix issues that if an informed person actually reviews easily concludes it doesn’t affect us in the slightest.
"maybe high and critical vulnerabilities don’t need to be a minor version upgrade"
huh? what do you suggest instead?
What happens when everyone adopts this policy? You just change it to two weeks?
The one week cooldown option is not relying on other users to be a canary for you. Its just giving automated scanners a chance to notice. This is the perfect example. I don't think step security found this by accident. They are actively monitoring NPM package releases at some level.
There is something to be said that Microsoft should be scanning packages pre-release. They aren't, though, so for right now there is a ton of value with very little downside if people implement a one week cooldown period.
To answer your question directly, though. If everyone else moves to a one week cooldown, I would absolutely suggest a two week cooldown is a good idea. Being the "slow" moving organization is a good security trade-off so long as you don't take it to extremes and have escape hatches when you actually need to be moving quickly.
Thank you for the thorough response. I got the following from yours and other responses:
* The JS ecosystem has been and will most likely continue to be fast-moving, so it's quite a safe assumption that at no point will a quarantine period be wide-spread.
* This quarantine period is for (semi-)automated scanners to catch the issue. Although considering the above there will always be a non-zero amount of end-user canaries as well.
* Maybe NPM should run scanners before distributing malware?
* If the ecosystem by any chance adopts a week-long quarantine period, you'd be safer if you applied a longer quarantine period.
A large array of automated and semi-automated security scanners are finding things quickly. The main benefit of waiting before updating is to give those scanners time to work.
You rely on the security companies scanning the packages.
@exitb it is much more desirable for security scanning companies to compete to find issues in a timely manor. If npm blessed one as a gatekeeper to the whole system they would be between a rock and a hard place. Unable to priorities high impact packages over the long tail of packages no one uses without pissing people off. Unable to add experimental new detections that may be a little noisy at first due to the huge disruption it would cause. Be trivial to game as obscure packages could brute-force their way though then use the same hole on a mainstream package.
Well, if that actually works, it should be part of the release process, before the packages get placed onto the regular channels.
I think the key right now is that these are semi-automated scanning processes. Right now, companies like step security selectively publish. So, in order for a hacking group to find out if their malware is detected or not, they have to burn access to a useful package.
None of this is to say I think Microsoft shouldn't be doing something as part of the release process on NPM. However, there is real value in giving more independent third parties a window to do things semi-manually.
Then the ... malware will just add delays? Or do they really do manual in-depth analysis of all new code? Just running and seeing it do things is probably a lot easier.
Security scans and authors realizing an unauthorized version was pushed will generally happen regardless of whether regular users updated. Even for compromises that are found by users updating, it'd generally be better to reduce the number of people affected with a slow roll-out rather than everyone jumping on at once.
Always one day more than people on HN tell you. If something is compromised you will hear people complaining here that three days is not enough.
This will never happen unless it's made the default. Most people will always stick with the defaults.
I came across this interesting rant the other day: https://github.com/uNetworking/uWebSockets.js/blob/master/mi...
It does make sense that the right way would be to fork every dependency you use and install from your own repo reviewing and merging from upstream as needed. Would be a giant PITA though. :)
Nothing that couldn't be automated; in Go land this is (arguably) called vendoring (https://go.dev/ref/mod#vendoring). Good to offload or reduce dependencies on 3rd party dependency hosters, pull a dependency into your own code review tools, and to ensure reproducible builds long term.
I mean there’s nothing stopping you from committing node_modules to git (after running something like https://github.com/timoxley/cruft on it) and reviewing code changes on dependency updates.
I even managed to make that part of the workflow on one team I worked with but several other teams since thought it was a crazy idea. :)
The problem would be the dependencies of your dependencies, and keep going many levels.
I think the general idea that your supply chain should be rooted in source repositories and associated commit hashes is the right one. Tooling can be made to automate the process of putting together a product from those defined sources. Some languages/systems already have some support for this. E.g. Golang and Rust. The concept of a "binary" artifact is really dead now everyone uses git and builds are quick. It lives on in things like npm and docker hub but we don't actually need it.
For smaller shops (by small I mean <1,000 employees) this isn't even tenable. We (engineering team of about 10 people) mitigate what we can via tooling and cooldown periods/minimum release age. This will work as long as these malicious packages remain reasonably detectable. I think that's the proper balance, because we can adjust the # of days we are willing to risk against the SOTA of detection tooling.
Should link to the original announcement I think:
https://www.stepsecurity.io/blog/multiple-redhat-cloud-servi...
Yes. Also Red Hat is misspelt in the title.
We have done the complete analysis and there are 32 packages share the same publishing pipeline. https://safedep.io/redhat-cloud-services-hit-by-mini-shai-hu...
I've made it a habit now to use the --before=2026-05-30 flag when installing packages, where it'll pick the version released before the date you specify, I usually pick around 5 days ago
Yarn 4 can automate this
One thing I've never understood is why NPM allows packages to run code immediately after they are installed. What's the use case for that? A package should just be some code you can call on at runtime
Some packages need to build native dependencies. sharp for example needs to build libvips on the system [0] to work
0: https://github.com/lovell/sharp/blob/main/install/build.js
The entire ecosystem is cursed
Hmm, same day as RH and IBM announce Project Lightwell to help detect and fix supply chain vulns.
https://www.redhat.com/en/lightwell
I'm refactoring all my personal and research projects to utilize pure HTML/CSS without any dependency of JavaScript. This was always on the table but the cybersecurity risks from all programming languages and frameworks have increased due to AI.
I know of fundamental issues with JavaScript and see no reason why it's still standard on all web browsers.
Chainguard based images, packages and libraries are first line of defense. Expensive? Yes. Foolproof? No. I think these types services will be mandatory in the near future.
How would that help? These are not general purpose, base system libraries, these are libraries specific to a product that uses them. Either you're not using them and hence they would not be installed in the first place, or you're using them because you have the product installed.
Though I would expect that Insights uses RPM packages to ship components and not the public NPM packages.
it wouldn't surprise me if insights was in fact a wrapper around npm install
Given they use nx my bet is on developer laptop compromise through the nx vscode extension that also compromised GitHub engineer's laptop
the security of their packages should not depend on one laptop being compromised
That’s why I switched to Java.
You are absolutely right. The dangerous part of NPM packages is the post-install script. Therefore moving from JavaScript to Java removes the threat.
Yeah but you don’t have to use that I think. I think us Node people can just pretend to write Ecmascript 2 in Java and be fine.
…. lol
Looks like RedHat got compromised by a Black Hat…
This is a completely unexpected turn of events that no one could have possibly foreseen.
man we gotta do smth with preinstall hooks atp
Lol.. yet again npm and install-scripts abuse at play.
Updated:
1. All exploitation techniques used since May 2025: https://npm-supply-chain-attack-techniques.pagey.site/
2. All attacks that happened since May 2025: https://npm-supply-chain-attacks-25-26.pagey.site/
Proof that we shouldn't worry about bad AI code and decisions because we have already been suffering from amateur JavaScript devs for at least 15 years.
When will npm issues stop ? This has become a big pain !
Oooh now I'm wondering if this may have contributed to their Docker image distribution service getting disrupted earlier today... https://status.redhat.com/incidents/jn6r256zc62c
Same actors again?
if RedHat is unable to secure their packages, what can we expect from mere mortals...
This repository itself had to previously update from the axios supply chain attack [0] (co-authored by Claude lol). But just by looking at the change itself, the package is unpinned and won't solve the problem if another malicious security update happens again.
So if you have an unpinned version of this package and you run 'npm install', you immediately downloaded the compromised version and that's that.
[0] https://github.com/RedHatInsights/javascript-clients/commit/...
At some point, they need a new system for these "packages", you've got to be insane to install any of these right now.
Redhat's entire reason for existence is to prevent this.
not really, no.
So why else do we pay someone to package and certify/verify open source projects? This is absolutely 90++% of what should be RedHats core day job.