(no title)
codemonkey-zeta | 5 months ago
These attacks may just be the final push I needed to take server rendering (without js) more seriously. The HTMX folks convinced me that I can get REALLY far without any JavaScript, and my apps will probably be faster and less janky anyway.
jeswin|5 months ago
However, processes and practices around NodeJS and npm are in dire need of a security overhaul. leftpad is a cultural problem that needs to be addressed. To start with, snippets don't need to be on npm.
spankalee|5 months ago
lenerdenator|5 months ago
> However, processes and practices around NodeJS and npm are in dire need of a security overhaul. leftpad is a cultural problem that needs to be addressed. To start with, snippets don't need to be on npm.
Traditional JS is the reason we have all of these problems around NodeJS and npm. It's a lot better than it was, but a lot of JS tooling came up in the time when ES5 and older were the standard, and to call those versions of the language lacking is... charitable. There were tons of things that you simply couldn't count on the language or its standard library to do right, so a culture of hacks and bandaids grew up around it. Browser disparities didn't help either.
Then people said, "Well, why don't we all share these hacks and bandaids so that we don't have to constantly reinvent the wheel?", and that's sort of how npm got its start. And of course, it was the freewheeling days of the late 00s/early 10s, when you were supposed to "move fast and break things" as a developer, so you didn't have time to really check if any of this was secure or made any sense. The business side wanted the feature and they wanted it now.
The ultimate solution would be to stop slapping bandaids and hacks on the JS ecosystem by making a better language but no one's got the resolve to do that.
WD-42|5 months ago
[1]https://www.npmjs.com/package/uuid
kortilla|5 months ago
The isolated context is gone and a single instance of code talking to an individual client has access to your entire database. It’s a completely different threat model.
skydhash|5 months ago
mewpmewp2|5 months ago
What I'm wondering if it would help the ecosystem, if you were able to rather load raw snippets into your codebase, and source control as opposed to having them as dependencies.
So e.g. shadcn component pasting approach.
For things like leftPad, cli colors and others you would just load raw typescript code from a source, and there you would immediately notice something malicious or during code reviews.
You would leave actual npm packages to only actual frameworks / larger packages where this doesn't make sense and expect higher scrutiny, multi approvals of releases there.
lucideer|5 months ago
I see this odd take a lot - the automatic narrowing of the scope of an attack to the single ecosystem it occurred in most recently, without any real technical argument for doing so.
What's especially concerning is I see this take in the security industry: mitigations put in place to target e.g. NPM, but are then completely absent for PyPi or Crates. It's bizarre not only because it leaves those ecosystems wide open, but also because the mitigation measures would be very similar (so it would be a minimal amount of additional effort for a large benefit).
woodruffw|5 months ago
I ask because think the directionality is backwards here: I’ve been involved in packaging ecosystem security for the last few years, and I’m generally of the opinion that PyPI has been ahead of the curve on implementing mitigations. Specifically, I think widespread trusted publishing adoption would have made this attack less effective since there would be fewer credentials to steal, but npm only implemented trusted publishing recently[1]. Crates also implemented exactly this kind of self-scoping, self-expiring credential exchange ahead of npm.
(This isn’t to malign any ecosystem; I think people are also overcorrect in treating this like a uniquely JavaScript-shaped problem.)
[1]: https://github.blog/changelog/2025-07-31-npm-trusted-publish...
simiones|5 months ago
But NPM has a much, much bigger problem on the client side, that makes many of these mitigations almost moot. And that is that `npm install` will upgrade every single package you depend on to its latest version that matches your declared dependency, and in JS land almost everyone uses lax dependency declarations.
So, an attacker who simply publishes a new patch version of a package they have gained access to will likely poison a good chunk of all of the users of that package in a relatively short amount of time. Even if the projects using this are careful and use `npm ci` instead of `npm install` for their CI builds, it will still easily get developers to download and run the malicious new version.
Most other ecosystems don't have this unsafe-by-default behavior, so deploying a new malicious version of a previously safe package is not such a major risk as it is in NPM.
kees99|5 months ago
But don't brush off "special status" of NPM here. It is unique in that JS being language of both front-end and back-end, it is much easier for the crooks to sneak in malware that will end up running in visitor's browser and affect them directly. And that makes it a uniquely more attractive target.
weinzierl|5 months ago
As far as I know crates.io has everything that npm has, plus
- strictly immutable versions[1]
- fully automated and no human in the loop perpetual yanking
- no deletions ever
- a public and append only index
Go modules go even further and add automatic checksum verification per default and a cryptographic transparency log.
Contrast this with docker hub for example, where not even npm's basic properties hold.
So, it is more like
docker hub ⊂ npm ⊂ crates.io ⊂ Go modules
[1] Nowadays npm has this arguably too
WD-42|5 months ago
jacques_chester|5 months ago
[0] https://github.com/ossf/wg-securing-software-repos
[1] https://alpha-omega.dev/grants/grantrecipients/
worik|5 months ago
reactordev|5 months ago
Supply chain attacks happen at every layer where there is package management or a vector onto the machine or into the code.
What NPM should do if they really give a shit is start requiring 2FA to publish. Require a scan prior to publish. Sign the package with hard keys and signature. Verify all packages installed match signatures. Semver matching isn’t enough. CRC checks aren’t enough. This has to be baked into packages and package management.
lycopodiopsida|5 months ago
While technically true, I have yet to see Go projects importing thousands of dependencies. They may certainly exist, but are absolutely not the rule. JS projects, however...
We have to realize, that while supply chain attacks can happen everywhere, the best mitigations are development culture and solid standard library - looking at you, cargo.
I am a JS developer by trade and I think that this ecosystem is doomed. I absolutely avoid even installing node on my private machine.
HillRat|5 months ago
That's really the core issue. Developer-signed packages (npm's current attack model is "Eve doing a man-in-the-middle attack between npm and you," which is not exactly the most common threat here) and a transparent key registry should be minimal kit for any package manager, even though all, or at least practically all, the ecosystems are bereft of that. Hardening API surfaces with additional MFA isn't enough; you have to divorce "API authentication" from "cryptographic authentication" so that compromising one doesn't affect the other.
rs999gti|5 months ago
How does 2FA prevent malware? Anyone can get a phone number to receive a text or add an authenticator to their phone.
I would argue a subscrption model for 1 EUR/month would be better. The money received could pay for certification of packages and the credit card on file can leverage the security of the payments system.
psychoslave|5 months ago
That is, if some attacker create some dummy trivial but convenient package and 2 years latter half the package hub depends on it somehow, the attacker will just use its legit credential to pown everyone and its dog. This is not even about stilling credentials. It’s a cultural issue with bare blind trust to use blank check without even any expiry date.
https://en.wikipedia.org/wiki/Trust,_but_verify
cxr|5 months ago
NPM has also been sending out nag emails for the last 2+ years about 2FA. If anything, that constituted an assist in the attack on the Junon account that we saw a couple weeks ago.
floydnoel|5 months ago
hoppp|5 months ago
At some point people need to realize and go back to writing vanilla js, which will be very hard.
The rust ecosystem is also the same. Too much dependence on packages.
An example of doing it right is golang.
simiones|5 months ago
rs186|5 months ago
pixl97|5 months ago
Lists of things that won't happen. Companies are filled with node_modules importers these days.
Even worse, now you have to check for security flaws in that JS that's been written by node_modules importers.
That or there could someone could write a standard library for JS?
joquarky|5 months ago
Of course that limits my job search options, but I can't feel comfortable signing off on any project that includes more dependencies than I can count at a glance.
BrouteMinou|5 months ago
jddj|5 months ago
There is a difference, but it's not an order of magnitude and neither is a true island.
Granted, deciding not to use JS on the server is reasonable in the context of this article, but for the client htmx is as much a js lib with (dev) dependencies as any other.
https://github.com/bigskysoftware/htmx/blob/master/package.j...
https://github.com/vuejs/core/blob/main/package.json
yawaramin|5 months ago
tarruda|5 months ago
Unless this lack of scrutiny is exclusive to JavaScript ecosystem, then this attack could just as well have happened in Rust or Golang.
coldpie|5 months ago
Languages without package managers have a lot more friction to pull in dependencies. You usually rely on the operating system and its package-manager-humans to provide your dependencies; or on primitive OSes like Windows or macOS, you package the dependencies with your application, which involves integrating them into your build and distribution systems. Both of those involve a lot of manual, human effort, which reduces the total number of dependencies (attack points), and makes supply-chain issues like this more likely to be noticed.
The language package managers make it trivial to pull in dozens or hundreds of dependencies, straight from some random source code repository. Your dependencies can add their own dependencies, without you ever knowing. When you have dozens or hundreds of unvetted dependencies, it becomes trivial for an attacker to inject code they control into just one of those dependencies, and then it's game over for every project that includes that one dependency anywhere in their chain.
It's not impossible to do that in the OS-provided or self-managed dependency scenario, but it's much more difficult and will have a much narrower impact.
unknown|5 months ago
[deleted]
user34283|5 months ago
Many who claim to fully analyze all dependencies are probably lying. I did not see anyone in the comments sharing their actual dependency count.
Even if you depend only on Jest - Meta's popular test runner - you add 300 packages.
Unless your setup is truly minimalistic, you probably have hundreds of dependencies already, which makes obsessing over some more rather pointless.
zelphirkalt|5 months ago
hsbauauvhabzb|5 months ago
tomjen3|5 months ago
qudat|5 months ago
This works for deps of deps as well, so anything in your node_modules has access to this hook.
It's a terrible idea and something that ought to be removed or replaced by something much safer.
zarzavat|5 months ago
jmull|5 months ago
While npm is a huge and easy target, the general problem exists for all package repositories. Hopefully a supply chain attack mitigation strategy can be better than hoping attackers target package repositories you aren't using.
While there's a culture prevalent in Javascript development to ignore the costs of piling abstractions on top of abstractions, you don't have to buy into it. Probably the easiest thing to do is count transitive dependencies.
yawaramin|5 months ago
But it will cut a large portion of it.
everdrive|5 months ago
mrweasel|5 months ago
If you can sneak malware into a JavaScript application that runs in millions of browsers, that's a lot more useful that getting a some number servers running a module as part of a script, who's environment is a bit unknown.
Javascript really could do with a standard library.
spoiler|5 months ago
Eh... This over-generalises a bit. That can be said of anything really, including native desktop applications.
petcat|5 months ago
koakuma-chan|5 months ago
ZYbCRq22HbJ2y7|5 months ago
Have fun, seems like a misguided reason to do that though.
A. A package hosted somewhere using a language was compromised!
B. I am not going to program in the language anymore!
I don't see how B follows A.
Aeolun|5 months ago
philipwhiuk|5 months ago
bdcravens|5 months ago
> Server-side-rendering without JavaScript is just back to the stuff Perl and PHP give you.
As well as Ruby, Python, Go, etc.
norman784|5 months ago
hosh|5 months ago
EMM_386|5 months ago
HTMX is JavaScript.
Unless you meant your own JavaScript.
yawaramin|5 months ago
junon|5 months ago
kubafu|5 months ago
brazukadev|5 months ago
rs999gti|5 months ago
You all really need to stop using this term when it comes to OSS. Supply chain implies a relationship, none of these companies or developers have a relationship with the creators other than including their packages.
Call it something like "free code attacks" or "hobbyist code attacks."
shermantanktop|5 months ago
“code I somehow took a dependency on when copying bits of someone’s package.json file”
“code which showed up in my lock file and I still don’t know how it got there”
__alexs|5 months ago
pixl97|5 months ago