Summarizer

Version pinning limitations

Acknowledgment that while lockfiles help, teams using automated update tools like Renovate or Dependabot may still pull compromised versions quickly

← Back to Axios compromised on NPM – Malicious versions drop remote access trojan

The debate centers on the paradox where automated update tools, originally designed to keep systems secure, often become the primary vector for delivering compromised code at "warp speed" before the community can react. While some developers champion aggressive defense strategies like "zero-installs" or pinning dependencies to specific git hashes, others warn that these tactics create a "bitrot" trap that eventually leaves teams vulnerable to known, unpatched exploits. Ultimately, much of the criticism is leveled at the structural flaws of the NPM ecosystem—specifically its deep dependency trees and post-install hooks—leading to calls for a cultural shift toward intentional update delays and stricter publisher verification.

43 comments tagged with this topic

View on HN · Topics
> they just move slower so it’s not as attractive of a target. Well, there’s other things. Maven doesn’t allow you to declare “version >= x.y.z” and doesn’t run arbitrary scripts upon pulling dependencies, for one thing. The Java classpath doesn’t make it possible to have multiple versions of the same library at the same time. That helps a lot too. NPM and the way node does dependency management just isn’t great. Never has been.
View on HN · Topics
This might make things worse not better. Yes - the postinstall hook attack vector goes away. You can do SHA pinning since Git's content addressing means that SHA is the hash of the content. But then your "lockfile" equivalent is just... a list of commit SHAs scattered across import statements in your source? Managing that across a real dependency tree becomes a nightmare. This is basically what Deno's import maps tried to solve, and what they ended up with looked a lot like a package registry again. At least npm packages have checksums and a registry that can yank things.
View on HN · Topics
> But then your "lockfile" equivalent is just... a list of commit SHAs scattered across import statements in your source? Managing that across a real dependency tree becomes a nightmare. The irony is that this is actually the current best practice to defend against supply chain attacks in the github actions layer. Pin all actions versions to a hash. There's an entire secondary set of dev tools for converting GHA version numbers to hashes
View on HN · Topics
Don't do this. Use a package manager that let's you specify a specific version to pin against. Vendoring side steps most automated tooling that can warn you about vulnerabilities. Vendoring is a signal that your tooling is insufficient, 99% of the time.
View on HN · Topics
Why would it get pulled in over the weekend? What automatic deployments are you running if there also isn't a human working to get it out? Do you run automatic dependency updates over the weekend? Wouldn't you rather do that during fully-staffed hours?
View on HN · Topics
Good luck with any `npm audit` in a pipeline. Sometimes you have to pull the latest release because the previous one had a critical vulnerability.
View on HN · Topics
While it's not perfect, pinning specific versions and managing all updates directly has been a solid solution for my team. Things can of course still slip through, but we're never vulnerable to these just because there was a new package release and we opted into it by default. Updating packages takes longer, but we try to keep packages to a minimum so it ends up not being that big deal.
View on HN · Topics
minimumReleaseAge and lockfiles also pin down transitive dependencies.
View on HN · Topics
> Run Yarn in zero-installs mode (or equivalent for your package manager). Every new or changed dependency gets checked in. Idk, lockfiles provide almost as good protection without putting the binaries in git. At least with `--frozen-lockfile` option.
View on HN · Topics
Zero-installs mode does not replace the lockfile. Your lockfile is still the source of truth regarding integrity hashes. However, it’s an extra line of defence against 1) your registry being down (preventing you from pushing a security hotfix when you find out another package compromised your product), 2) package unpublishing attacks (your install step fails or asks you to pick a replacement version, what do you do at 5pm on a Friday?), and 3) possibly (but haven’t looked in depth) lockfile poisoning attacks, by making them more complicated. Also, it makes the size of your dependency graph (or changes therein) much more tangible and obvious, compared to some lines in a lockfile.
View on HN · Topics
Number 1 would only be a win for zero-installs if it happened that registry was up when you made the security hotfix, since you'd need to install the depdencency the first time to get it in VC, but then suddenly down when doing a deploy. Seems like a highly unlikely scenario to me. Also, cases where npm CVEs must be patched with such urgency or bad things will happen are luckily very rare, in my experience. Most npm CVEs are stuff like DDoS vulnerabilities, and you should have mitigations for those in place for at the infra-level anyway (e.g. request timeouts, rate limits, etc), or you are pretty much guaranteed to be cooked sooner or later anyway. The really dangerous stuff like arbitrary command execution from a library that takes end user input is much much more rare. The most recent big one I remember is React2shell. Number 2 hasn't been much of an issue for a long time. npm doesn't allow unpublishing package after 72 hours (apart from under certain rare conditions). Don't know about number 3. Would feel to me that if you have something running that can modify lockfile, they can probably also modify the chekced-in tars. I can see how zero-installs are useful under some specific constraints where you want to minimize dependencies to external services, e.g. when your CI runs under strict firewalls. But for most, nah, not worth it.
View on HN · Topics
> you'd need to install the depdencency the first time to get it in VC, but then suddenly down when doing a deploy. Which dependency? It sounds like you are assuming some specific scenario, whereas the fix can take many forms. In immediate term, the quickest step could be to simply disable some feature. A later step may be vendoring in a safe implementation. The registry doesn’t need to be actually down for you , either; the necessary condition is that your CI infrastructure can’t reach it. > cases where npm CVEs must be patched with such urgency or bad things will happen are luckily very rare, in my experience. Not sure what you mean by “npm CVEs”. The registry? The CLI tool? As I wrote, if you are running compromised software in production, you want to fix it ASAP. In first moments you may not even know whether bad things will happen or not, just that you are shipping malicious code to your users. Even if you are lucky enough to determine with 100% confidence (putting your job on the line) that the compromise is inconsequential, you don’t want to keep shipping that code for another hour because your install step fails due to a random CI infra hiccup making registry inaccessible (as happened in my experience at least half dozen times in years prior, though luckily not in a circumstance where someone attempted to push an urgent security fix). Now imagine it’s not a random hiccup but part of a coordinated targeted attack, and somehow it becomes something anticipated. > Number 2 hasn't been much of an issue for a long time. npm doesn't allow unpublishing package after 72 hours (apart from under certain rare conditions). Those rare conditions exist. Also, you are making it sound as if the registry is infallible, and no humans and/or LLMs there accept untrusted input from their environment. The key aspect of modern package managers, when used correctly, is that even when the registry is compromised you are fine as long as integrity check crypto holds up and you hold on to your pre-compromise dependency tree. The latter is not a technical problem but a human problem, because conditions can be engineered in which something may slip past your eyes. If this slip-up can be avoided at little to no cost—in fact, with benefits, since zero-installs shortens CI times, and therefore time-to-fix, due to dramatically shorter or fully eliminated install step—it should be a complete no-brainer. > Don't know about number 3. Would feel to me that if you have something running that can modify lockfile, they can probably also modify the chekced-in tars. As I wrote, I suspect it’d complicate such attacks or make them easier to spot, not make them impossible.
View on HN · Topics
Exactly. Yarn uses a yarn.lock file with the sha256 hashes of each npm package it downloads from the repo (they are .tgz files). If the hash won't match, install fails. No need to commit the dependencies into your git.
View on HN · Topics
While I agree that my view is narrow, the "best solution" in question is what we used to do, and it was fine. There are still many places that manually manage dependencies. Fundamentally automatic software versioning is an under-developed area in need of attention, and technologies like semantic versioning which are ubiquitous are closer to suggestions, and not true indicators of breaking changes. My personal view is that fully automatic dependency version management is an ongoing experiment and should be treated as such.
View on HN · Topics
If you're developing for the web your attack surface is quite a bit bigger. Your proposed solution of copying a few files might work but how do you keep track of updates? You might be vulnerable to a published exploit fixed a few months ago. A package manager might tell you a new version is available. I don't know how that would work in your scenario.
View on HN · Topics
It is because it has the lowest barrier to entry with no quality control. Ever. This is what happens when there is no barrier to entry and it includes everyone who has no idea what they are doing in charge of the NPM community. When you see a single package having +25 dependencies, that is a bad practice and increases the risk of supply chain attacks. Most of them don't even pin their dependencies and I called this out just yesterday on OneCLI. [0] It just happens that NPM is the worst out of all of the rest of the ecosystems due to the above. [0] https://news.ycombinator.com/item?id=47577183
View on HN · Topics
> trusted input (game assets) Gamedev is its own weird thing, and isn't a model you want to generalize to other industries. It has to optimize for things a lot of software does not, and that skews development. Vendoring libraries is almost always a terrible idea because it immediately starts to bitrot and become a footgun. Sometimes it's necessary , but it's not desirable , and you almost always just want to pin your dependencies instead.
View on HN · Topics
I think you can do copy paste in most languages. But it will be a pain to update when there are improvements / security fixes. You got a project with 1-2 depencies? Sure. But if you need to bring in 100 different libs (because you bring in 10 libs which in turn brings in 10 libs) good luck.
View on HN · Topics
Then you've got ecosystems like Clojure where many projects are just considered done and used by many. You can pin these (and be warned if a new version still comes out, say for an actual security fix). There are Clojure projects so stable, without any know exploit (we're certainly not talking about daily npm exploits here), that haven't been updated in years because they are... Done. Simply done. Perfection. Something to reflect upon too.
View on HN · Topics
Hi, security here. We've tried, but the amount of people you need for this vs the amount of people you have trying to review and click the big button always means that this step will be a bottleneck. Thus this step will be eliminated. A much better approach would be to pin the versions used and do intentional updates some time after release, say a sprint after.
View on HN · Topics
Yes, that's why I recommend intentional updates. Planning at least a sprint later gives you a week or two, hoping the community catches such issues.
View on HN · Topics
Or just lock to a specific version?
View on HN · Topics
Eventually you will want to update it, every update is a risk.
View on HN · Topics
But, pinning has prevented most of the recent supply chain attacks. As long as you don't update your pins during an active supply chain attack, the risk surface is rather low.
View on HN · Topics
The flip side of that is now you're running old software and CVEs get published all the time. Threat actors actively scan the internet looking for software that's vulnerable to new CVEs.
View on HN · Topics
Min release age sucks, but we’ve been here before. Email attachments used to just run wild too, then everyone added quarantine delays and file blocking and other frictions... and it eventually kinda/sorta worked. This does feel worse, though, with fewer chokepoints and execution as a natural part of the expectation. Edit: bottom line is installs are gonna get SOOO much more complicated. You can already see the solution surface... Cooling periods, maintainer profiling, sandbox detonation, lockfile diffing, weird publish path checks. All adds up to one giant PITA for fast easy dev.
View on HN · Topics
To have an initial smoke test, why not run a diff between version upgrades, and potentially let an llm summarise the changes? It’s a baffling practice that a lot of developers are just blindly trusting code repos to keep the security standards. Last time I installed some npm package (in a container) it loaded 521 dependencies and my heart rate jumped a bit
View on HN · Topics
This is exactly to avoid this kind of issue that I decided to work on StableBuild. StableBuild pins and hosts a copy of your dependencies at a specific freeze date, so that your supply chain is never contaminated. This way, a compromised version published after your freeze date (even with the same version number!) would never reach your build.
View on HN · Topics
Literally every package manager already does this.
View on HN · Topics
This is the second major npm supply chain attack this year and the playbook is identical every time: hijack a maintainer account, publish via CLI to bypass CI/CD, inject a dependency nobody's heard of. The fix isn't better scanning (though Socket catching it in 6 minutes is impressive). The fix is npm making Trusted Publishers mandatory for packages above a download threshold. If axios can only be published through GitHub Actions OIDC, a stolen password is useless. We run a fleet of AI agents that depend on npm packages. First thing we did tonight was audit every lockfile. Clean — but only because we aggressively minimise dependencies. The real victims here are the thousands of teams who npm install with ^ ranges and never check what changed.
View on HN · Topics
Ok it's bad, but our npm projects are pinned in the package-lock.json, which I imagine most would be? So who would pull this besides security scanners?
View on HN · Topics
`npm install` might be enough to pull it, unless you pin down to the patch?
View on HN · Topics
I don't think that's right if it's in your package-lock it wouldn't pull it unless you npm update axios, or delete the package-lock.json and then npm install.
View on HN · Topics
Absolute wave of supply chain attacks recently. Hopefully this causes everyone to tighten up their dependencies and update policies.
View on HN · Topics
Why can't we freeze the version of globally installed packages with npm?
View on HN · Topics
Default setting latest should be caught in every static code scanner. How many times has this issue been raised.
View on HN · Topics
This is the part that's tough — we push everyone to keep dependencies updated and automate it with Renovate or Dependabot, but that's exactly the pipeline that would have pulled this in before anyone noticed. Lockfiles and pinning help slow it down, but most teams pair those with automated update PRs which kind of negates the point. You can reduce your dependency surface area to lower the odds but one compromised maintainer on a top-10 package and none of that matters.
View on HN · Topics
Pin your dependencies folks! Audit and don't upgrade to every brand new version.
View on HN · Topics
But also have a regular review of your dependencies to update them when necessary, because as bad as compromised packages may be things do have vulnerabilities occasionally, and upgrading things that are a long way out-of-date can be quite hard.
View on HN · Topics
PSA: Make sure to set a minimum release age and pin versions where possible.
View on HN · Topics
but wouldn't it work in this case? sure if a package was compromised for months/years it wouldn't save you but tell dependabot to delay a week, you'd sleep easy from this nonesense
View on HN · Topics
Log4Shell was hardly a supply-chain attack - just a latent bug in a widely-used library. That can happen anywhere. Maven to this day represents my ideal of package distribution. Immutable versions save so much trouble and I really don't understand why, in the age of left-pad, other people looked at that and said, "nah, I'm good with this."
View on HN · Topics
Completely agree. NPM has the only registry where massive supply chain attacks happen several times a year. Mainly the fault lies with NPM itself, but much of it is just a terrible opsec culture in the community. Most package.jsons I see have semver operators on every dependency, so patches spread incredibly quickly. Package namespacing is not enforced, so there is no way of knowing who the maintainer is without looking it up on the registry first; for this reason many of the most popular packages are basically side projects maintained by a single developer*. Post-install scripts are enabled by default unless you use pnpm or bun. When you combine all these factors, you get the absolute disaster of an ecosystem that NPM is. *Not really the case for Axios as they are at least somewhat organized and financed via sponsors.