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).
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. :)
Built Packj [1] to audit dependencies easily from CLI.
1. Packj (https://github.com/ossillate-inc/packj) detects malicious PyPI/NPM/Ruby/PHP/etc. dependencies using behavioral analysis. It uses static+dynamic code analysis to scan for indicators of compromise (e.g., spawning of shell, use of SSH keys, network communication, use of decode+eval, etc). It also checks for several metadata attributes to detect bad actors (e.g., typo squatting).
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.
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.
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
92 comments
[ 3.1 ms ] story [ 80.4 ms ] threadEdit: some people don't understand that it's a defence to https://en.wikipedia.org/wiki/%27No_Way_to_Prevent_This,%27_...
https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e...
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/
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. :)
1. Packj (https://github.com/ossillate-inc/packj) detects malicious PyPI/NPM/Ruby/PHP/etc. dependencies using behavioral analysis. It uses static+dynamic code analysis to scan for indicators of compromise (e.g., spawning of shell, use of SSH keys, network communication, use of decode+eval, etc). It also checks for several metadata attributes to detect bad actors (e.g., typo squatting).
Gentoo graybeards know.
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/...
https://www.redhat.com/en/lightwell
https://www.stepsecurity.io/blog/multiple-redhat-cloud-servi...