In September 2025, a maintainer of several very popular npm packages, including chalk and debug, had their account phished. New versions were published with code that tried to steal cryptocurrency from browsers. The community spotted it quickly, and the bad versions were removed within hours.
The teams that got hit were the ones whose installs ran in those hours. Teams that waited even a couple of days never saw the bad versions at all.
Most bad releases have a short life
Not every bad release is an attack. Most are ordinary mistakes: a broken build published by accident, a regression the tests missed, a missing file. The pattern is the same:
day 0 release published
day 1 issues opened, maybe a security report
day 2 version deprecated or unpublished, fix released
So a simple rule removes most of the risk: don't install a release until it's a few days old. Seven days is a common choice.
Setting it up
Renovate has it built in:
{
"minimumReleaseAge": "7 days"
}
Dependabot has a cooldown option in dependabot.yml for the same idea:
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7
Lockfiles do the rest: with npm ci and a committed package-lock.json, nothing new is installed until a pull request changes the lockfile.
The exception: security fixes
A release that patches a known vulnerability is a different trade-off: the risk is in not installing it. Keep a separate, faster path for security updates, and review them like any other change.
If you installed it in that window
The payload hooked browser wallet calls and swapped addresses, so the real exposure was frontends built during those hours, not Node services. Checking the lockfile isn't enough: the bad code shipped inside the bundle and kept running on users' machines until the next deploy.
- Find every frontend build and deploy from those hours (CI history and deploy timestamps).
- Rebuild from a clean lockfile and redeploy, rather than only bumping the version.
- Purge CI dependency caches and CDN caches, so the old node_modules or the old bundle doesn't come back.
What we do
Versyka's weekly upgrades collect minor and patch updates that are at least 7 days old and open them as one tested pull request, while security fixes take their own path. More in the docs.
Does your dependency bot install releases the day they come out?
Top comments (2)
The payload in that incident hooked browser wallet calls and swapped addresses, so the exposure was mostly frontends built in those hours rather than Node services. Anyone checking whether they were hit should look at the bundles shipped in that window, not only the lockfile.
Good point, and it changes what "check your lockfile" should mean here. The payload only did anything where a browser wallet was present, so a Node API that installed the bad version was mostly exposed in name only. A frontend built in that window is different: the code shipped inside the bundle and kept running on users' machines until the next deploy, even after the lockfile was fixed.
So the practical check is:
Thanks for adding this. I'll fold it into the article.