Skip to content(if available)orjump to list(if available)

We all dodged a bullet

We all dodged a bullet

320 comments

·September 9, 2025

Related: NPM debug and chalk packages compromised - https://news.ycombinator.com/item?id=45169657

anon7000

The nx supply chain attack via npm was the bullet many companies did not doge. I mean, all you needed was to have the VS Code nx plugin installed — which always checked for the latest published nx version on npm. And if you had a local session with GitHub (eg logged into your company’s account via the GH CLI), or some important creds in a .env file… that was exfiltrated.

This happened even if you had pinned dependencies and were on top of security updates.

We need some deeper changes in the ecosystem.

https://github.com/nrwl/nx/security/advisories/GHSA-cxm3-wv7...

kardianos

> We need some deeper changes in the ecosystem.

I avoid anything to do with NPM, except for the typescript compiler, and I'm looking forward to the rewrite in Go where I can remove even that. For this reason.

As a comparison, in Go, you have minimum version spec, and it takes great pains to never execute anything you download, even during compilation stage.

NPM will often have different source then the github repo source. How does anyone even trust the system?

homebrewer

It's already solved by pnpm, which refuses to execute any postinstall scripts except those you whitelist manually. In most projects I don't enable any and everything works fine, in the worst case I had to enable two scripts (out of two dozen or so) that download prebuilt native components, although even those aren't really necessary and it could have been solved through other means (proven by typescript-go, swc, and other projects led by competent maintainers).

None of it will help you when you're executing the binaries you built, regardless of which language they were written in.

austin-cheney

I am now using the type remover in Node to run TupeScript natively. It’s great and so fast. Even still I continue to include the TypeScript compiler in my projects so that I can run TSC with the no compile option just for the type auditing.

RVuRnvbM2e

Fucking this.

I have seen so many takes lamenting how this kind of supply chain attack is such a difficult problem to fix.

No it really isn't. It's an ecosystem and cultural problem that npm encourages huge dependency trees that make it impractical to review dependency updates so developers just don't.

alehlopeh

“It’s not difficult to fix, just change the entire culture”

The difficulty comes in trying to change the entire culture.

captn3m0

Yeah, Editor extensions are both auto-updated and installed in high risk dev environments. Quite a juicy target and I am surprised we haven’t seen large scale purchases by bad actors similar to browser extensions yet. However, I remember reading that the VsCode team puts a lot of effort in catching malware. But do all editors (with auto-updates) such as Sublime have such checks?

zenmac

I usually make sure all the packages and db are local, so my dev machine can run in Airplane mode. And only turn on internet when use git push

null

[deleted]

sebstefan

Dodged a bullet indeed

I find it insane that someone would get access to a package like this, then just push a shitty crypto stealer.

You're a criminal with a one-in-a-million opportunity. Wouldn't you invest an extra week pushing a more fledged out exploit?

You can exfiltrate API keys, add your SSH public key to the server then exfiltrate the server's IP address so you can snoop in there manually, if you're on a dev's machine maybe the browser's profiles, the session tokens common sales websites? My personal desktop has all my cards saved on Amazon. My work laptop, depending on the period of my life, you could have had access to stuff you wouldn't believe either.

You don't even need to do anything with those, there's forums to sell that stuff.

Surely there's an explanation, or is it that all the good cybercriminals have stable high paying jobs in tech, and this is what's left for us?

com2kid

> You're a criminal with a one-in-a-million opportunity. Wouldn't you invest an extra week pushing a more fledged out exploit?

Because the way this was pulled off, it was going to be found out right away. It wasn't a subtle insertion, it was a complete account take over. The attacker had only hours before discovery - so the logical thing to do is a hit and run. They asked what is the most money that can be extracted in just a few hours in an automated fashion (no time to investigate targets manually one at a time) and crypto is the obvious answer.

Unless the back doors were so good they weren't going to be discovered even though half the world would be dissecting the attack code, there was no point in even trying.

nialv7

> it was a complete account take over

is that so? from the email it looks like they MITM'd the 2FA setup process, so they will have qix's 2FA secret. they don't have to immediately start taking over qix's account and lock him out. they should have had all the time they need to come up with a more sophisticated payload.

pluto_modadic

"found out right away"... by people with time to review security bulletins. There's loads of places I could see this slipping through the cracks for months.

andrewstuart2

I'm assuming they meant the account takeover was likely to be found out right away. You change your password on a major site like that and you're going to get an email about it. Login from a new location also triggers these emails, though I admit I haven't logged onto NPM in quite a long time so I don't know that they do this.

It might get missed, but I sure notice any time account emails come through even if it's not saying "your password was reset."

benoau

There's probably already hundreds of thousands of Jira tickets to fix it with no sprint assigned....

zahlman

Yes, but this is an ecosystem large enough to include people who have that time (and inclination and ability); and once they have reported a problem, everyone is on high alert.

joshuat

The window of installation time would be pretty minimal, and the operating window would only be as long as those who deployed while the malicious package was up waited to do another deploy.

bobbylarrybobby

If they'd waited a week before using their ill-gotten credentials to update the packages, would they have been detected in that week?

jowea

To be fair, this wasn't a super demanding 0-day attack, it was a slightly targeted email phish. Maybe the attacker isn't that sophisticated and just went with what is familiar?

root_axis

Stolen cryptocurrency is a sure thing because fraudulent transactions can't be halted, reversed, or otherwise recovered. Things like a random dev's API and SSH keys are close to worthless unless you get extremely lucky, and even then you have to find some way to sell or otherwise make money from those credentials, the proceeds of which will certainly be denominated in cryptocurrency anyway.

buu700

Agreed. I think we're all relieved at the harm that wasn't caused by this, but the attacker was almost certainly more motivated by profit than harm. Having a bunch of credentials stolen en masse would be a pain in the butt for the rest of us, but from the attacker's perspective your SSH key is just more work and opsec risk compared to a clean crypto theft.

Putting it another way: if I'm a random small-time burglar who happens to find himself in Walter White's vault, I'm stuffing as much cash as I can fit into my bag and ignoring the barrel of methylamine.

jimbo808

And it's probably the lowest risk way to profit from this attack

babypuncher

Ultimately, stolen cryptocurrency doesn't cause real world damage for real people, it just causes a bad day for people who gamble on questionable speculative investments.

The damage from this hack could have been far worse if it was stealing real money people rely on to feed their kids.

jeroenhd

Get in, steal a couple hundred grand, get out, do the exact same thing a few months later. Repeat a few times and you can live worry free until retirement if you know to evade the cops.

Even if you steal other stuff, you're going to need to turn it all into cryptocurrency anyway, and how much is an AWS key really going to bring in.

There are criminals that focus on extracting passwords and password manager databases as well, though they often also end up going after cryptocurrency websites.

There are probably criminals out there biding their time, waiting for the perfect moment to strike, silently infiltrating companies through carefully picked dependencies, but those don't get caught as easily as the ones draining cryptocurrency wallets.

dylan604

> if you know to evade the cops.

step 1: live in a place where the cops do not police this type of activity

step 2: $$$$

scubbo

> do the exact same thing a few months later

> one-in-a-million opportunity

boznz

It is not a one-in-a-million opportunity though. I hate to take this to the next level, but as criminal elements wake up to the fact that a few "geeks" can possibly get them access to millions of dollars expect much worse to come. As a maintainer of any code that could gain bad guys access, I would be seriously considering how well my physical identity is hidden on-line.

pixl97

As foretold by the prophet

https://xkcd.com/538/

jongjong

I just made a very similar comment. Spot on. It's laughable to think that this trivial opportunity that literally any developer could pull off with a couple of thousand dollars is a one-in-a-million. North Korea probably has enough money to buy up a significant percentage of all popular npm dependencies and most people would sell willingly and unwittingly.

In the case of North Korea, it's really crazy because hackers over there can do this legally in their own country, with the support of their government!

And most popular npm developers are broke.

null

[deleted]

hombre_fatal

You give an example of an incredibly targeted attack of snooping around manually on someone's machine so you can exfiltrate yet more sensitive information like credit card numbers (how, and then what?)

But (1) how do you do that with hundreds or thousands of SSH/API keys and (2) how do you actually make money from it?

So you get a list of SSH or specific API keys and then write a crawler that can hopefully gather more secrets from them, like credit card details (how would that work btw?) and then what, you google "how to sell credentials" and register on some forum to broker a deal like they do in movies?

Sure sounds a hell of a lot more complicated and precarious than swapping out crypto addresses in flight.

WhyNotHugo

The pushed payload didn't generate any new traffic. It merely replaced the recipient of a crypto transaction to a different account. It would have been really hard to detect. Ex-filtrating API keys would have been picked up a lot faster.

OTOH, this modus operandi is completely inconsistent with the way they published the injected code: by taking over a developer's account. This was going to be noticed quickly.

If the payload had been injected in a more subtle way, it might have taken a long time to figure out. Especially with all the levenshtein logic that might convince a victim they'd somehow screwed up.

balls187

> You're a criminal with a one-in-a-million opportunity. Wouldn't you invest an extra week pushing a more fledged out exploit?

The plot of Office Space might offer clues.

Also isn't it crime 101 that greedy criminals are the ones who are more likely to get caught?

mikewarot

>Saved by procrastination!

Seriously, this is one of my key survival mechanisms. By the time I became system administrator for a small services company, I had learned to let other people beta test things. We ran Microsoft Office 2000 for 12 years, and saved soooo many upgrade headaches. We had a decade without the need to retrain.

That, and like other have said... never clicking links in emails.

mesofile

This is how I feel about my Honda, and to some extent, Kubernetes. In the former case I kept a 2006 model in good order for so long I skipped at least two (automobile) generation's worth of car-to-phone teething problems, and after years of hearing people complain about their woes I've found the experience of connecting my iphone to my '23 car pretty hassle-free. In the latter, I am finally moving a bunch of workloads out of EC2 after years of nudging from my higher-ups and, while it's still far from a simple matter I feel like the managed solutions in EKS and GKE have matured and greatly lessen the pain of migrating to K8S. I can only imagine what I would have gotten bogged down with had I promptly acted on my bosses' suggestion to do this six or seven years ago. (I also feel very lucky that the people I work for let me move on these things in my own due time.)

nottorp

Not in the "npm ecosystem". You're hopelessly behind there if you haven't updated in the last 54 seconds.

ainiriand

Well in this case it makes sense to update fast isn't it?

ohdeargodno

Sorry, the "npm ecosystem" command has been deprecated. You can instead use npm environment (or npm under-your-keyboard because we helpfully decided it should autocorrect and be an alias)

efilife

this seems to be a clever joke. sad to see it dead

pixl97

Works great for new exploited packages. Not so great for already compromised software getting hit by a worm.

RedShift1

I'll reply to you tomorrow

TYPE_FASTER

...by then it might be working again anyway, or the user figured out what they were doing wrong.

"Hey, is it still broken? No? Great!"

blamestross

"Just wait 2 weeks to use new versions by default" is an amazing defense method against supply chain attacks.

kevinrineer

Its also really ineffective defense against 0 days!

easterncalculus

In the context of a single system, there is no such thing as an "effective defense against 0 days" - that's marketing babble. A zero day by definition is an exploit with no defense. That's literally what that means.

ozim

IF I put my risk management hat on - 0 days in npm ecosystem are not that much of a problem.

They stop working before can use them.

blamestross

Sadly we don't have any defense against 0 days if an emergency patch is indistinguishable from an attack itself.

Better defense would be to delete or quarantine the compromised versions, fail to build and escalate to a human for zero-day defense.

monkpit

This article makes one faulty assumption that I think is really common - the author says it could be much worse, which implicitly assumes that we have noticed and caught every other time something like this has happened.

Internally, we only noticed this because it caused a bunch of random junk to get barfed out into some CI logs.

You really can’t say that nobody has ever done this better. Maybe they just did it so well that nobody noticed.

kumavis

> all the malware did was modify the destination addresses of cryptocurrency payments mediated via online wallets like MetaMask

A clarification: Despite MetaMask depending on the compromised packages it was not directly affected because: 1) packages were not updated while the compromise was live 2) MetaMask uses LavaMoat for install-time and run-time protections against compromised packages

However the payload did attempt to compromise other pages that interact with wallets like MetaMask.

Disclaimer: I worked on LavaMoat

LavaMoat: https://github.com/lavamoat/lavamoat

_fat_santa

I know this isn't really possible for smaller guys but larger players (like NPM) really should buy up all the TLD versions of "npm" (that is: npm.io, npm.sh, npm.help, etc). One of the reasons this was so effective is that the attacker managed to snap up "npm.help"

quectophoton

Then you have companies like AWS, they were sending invoices from `no-reply-aws@amazon.com` but last month they changed it to `no-reply@tax-and-invoicing.us-east-1.amazonaws.com`.

That looks like a phishing attempt from someone using a random EC2 instance or something, but apparently it's legit. I think. Even the "heads-up" email they sent beforehand looked like phishing, so I was waiting for the actual invoice to see if they really started using that address, but even now I'm not opening these attached PDFs.

These companies tell customers to be suspicious of phishing attempts, and then they pull these stunts.

simoncion

> These companies tell customers to be suspicious of phishing attempts, and then they pull these stunts.

Yep. At every BigCo I've worked at, nearly all of the emails from Corporate have been indistinguishable from phishing. Sometimes, they're actual spam!

Do the executives and directors responsible for sending these messages care? No. They never do, and get super defensive and self-righteous when you show them exactly how their precious emails tick every "This message is phishing!" box in the mandatory annual phishing-detection-and-resistance training.

cyphar

A few years ago our annual corporate phishing training was initiated by an email sent from a random address asking us to log in with our internal credentials on a random website.

A week later some executive pushing the training emailed the entire company saying that it was unacceptable that nobody from engineering had logged into the training site and spun some story about regulatory requirements. After lots of back and forth they still wouldn't accept that it obviously looked like a phishing email.

Eventually when we actually did the training, it literally told us to check the From address of emails. I sometimes wonder if it was some weird kind of performance art.

Macha

I remember an email I once got.

Title: "Expense report overdue - Please fill now"

Subject:

<empty body>

<Link to document trying it's best to look like google's attachment icon but was actually a hyperlink to a site that asked me to log in with my corporate credentials>

---

So like, obviously this is a stupid phishing email, right? Especially as at this time, I had not used my corporate card.

A few weeks later I got the finance team reaching out threatening to cancel my corporate card because I had charges on it with no corresponding expense report filed.

So on checking the charge history for the corporate card, it was the annual tax payment that all cards are charged in my country every year, and finance should have been well aware of. Of course, then the expense system initially rejected my report because I couldn't provide a receipt, as the card provider automatically deducts this charge with no manual action on the card owner's side...

mhh__

Yielding to anything you say is a no-no because part of the deal is that you, as a geek, must bend over to their unilateral veto over everything in the company

charlieyu1

I thought facebookmail.com was fake. No, it is actually legit

jowea

Is that for user email? I think that is semi-understandable as Facebook wouldn't want to mix their authority with that of the users, like github.com vs github.io.

Edit: nvm it seems it's not the case

VectorLock

There's like 1500 TLDs, now some of them are restricted and country-code TLDs but now it makes me wonder how much it would actual cost per year to maintain registration of every non-restricted TLD. I'm sure theres some SaaS company that'll do it.

saghm

OTOH, doesn't ICANN already sometimes restrict who has access to a given TLD? Would it really be that crazy for them to say "maybe we shouldn't let registrars sell npm.<TLD> regardless of the TLD", and likewise for a couple dozen of the most obvious targets (google., amazon., etc.)? No one needs to pay for these domains if no one is selling them in the first place. I don't love the idea of special treatment for giant companies in terms of domains, but we're already kind of there with the whole process they did when initially allowing companies to compete for exclusive access to TLDs, so we might as well use that process for something actually useful (unlike, say, letting companies apply for exclusive ownership of ".music" and have a whole legal process to determine that maybe that isn't actually beneficial for the internet as whole: https://en.wikipedia.org/wiki/.music)

VectorLock

The TLDs run the whole gamut from completely open to almost impossible to get.

osmsucks

There are way too many TLDs for this to be even practical: https://data.iana.org/TLD/tlds-alpha-by-domain.txt

I agree that especially larger players should be proactive and register all similar-sounding TLDs to mitigate such phishing attacks, but they can't be outright prevented this way.

karmakaze

First thing I do is check any domain that I don't recognize as official.

  Domain: NPMJS.HELP (85 similar domains)
  Registrar: Porkbun, LLC (4.84 million domains)
  Query Time: 8 Sep 2025 - 4:14 PM UTC  [1 DAY BACK] [REFRESH]

  Registered: 5th September 2025  [4 days back]
  Expiry: 5th September 2026  [11 months, 25 days left]
I'd be suspicious of anything registered with Porkbun discount registrar. 4 days ago, means it's fake.

> It sets a deadline a few days in the future. This creates a sense of urgency, and when you combine urgency with being rushed by life, you are much more likely to fall for the phishing link.

Any time I feel like I'm being rushed, I check deeper. It would help if everyone's official communications only came from the most well known domain (or subdomain).

jacobsenscott

This won't work - npm.* npmjs.* npmjs-help.* npm-help.* node.* js.* npmpackage.*. The list is endless.

You can't protect against people clicking links in emails in this way. You might say `npmjs-help.ph` is a phishy domain, but npmjs.help is a phishy domain and people clicked it anyway.

eddythompson80

there is also the more recent style of phising domains that look like healthcare.gov-profile.co/user

IncreasePosts

That seems like a bad idea compared to just having a canonical domain - people might become used to seeing "npm.<whatever>" and assuming it is legit. And then all it takes is one new TLD where NPM is a little late registering for someone to do something nefarious with the domain.

macintux

Just because you buy them doesn't mean that you have to use them. Squatting on them is no more harmful (except financially) than leaving them available for potentially hostile 3rd parties.

IncreasePosts

Sure, I guess buying up every npm.* you can find and then having a message "never use this, only use npm.com" could work. I thought OP was saying have every npm.* site be a mirror of the canonical site

ozim

That’s like insane proportion.

croemer

npmjs.help not npm.help - the typo is also in the article.

benreesman

Now imagine if someone combined Jia Tan patience with swiss-cheese security like all of our editor plugins and nifty shell user land stuff and all that.

Developer stuff is arguably the least scrutinized thing that routinely runs as mega root.

I wish I could say that I audit every elisp, neovim, vscode plugin and every nifty modern replacement for some creaky GNU userland tool. But bat, zoxide, fzf, atuin, starship, viddy, and about 100 more? Nah, I get them from nixpkgs in the best case, and I've piped things to sh.

Write a better VSCode plugin for some terminal panel LLM gizmo, wait a year or two?

gg

jowea

Someday, someone, hopefully, will fix xkcd 1200.

mlinksva

As the post mentions wallets like MetaMask being the targets, AFAIK MetaMask in particular might be one of the best protected (isolated) applications from this kind of attack due to their use of LavaMoat https://x.com/MetaMask/status/1965147403713196304 -- though I'd love to read a detailed analysis of whether they actually are protected. No affiliation with MetaMask, just curious about effectiveness of seemingly little adopted measures (relative to scariness of attacks).

Added: story dedicated to this topic more or less https://news.ycombinator.com/item?id=45179889

Zak

> If you were targeted with such a phishing attack, you'd fall for it too and it's a matter of when not if. Anyone who claims they wouldn't is wrong.

I like to think I wouldn't. I don't put credentials into links from emails that I didn't trigger right then (e.g. password reset emails). That's a security skill everyone should be practicing in 2025.

gcau

"'such' a phishing attack" makes it sound like a sophisticated, indepth attack, when in reality it's a developer yet again falling for a phishing email that even Sally from finance wouldn't fall for, and although anyone can make mistakes, there is such a thing as negligent, amateur mistakes. It's astonishing to me.

greycol

Every time I bite my tongue (literal not figurative) it's also astonishing to me. Last time I did was probably 3 years ago and it was probably 10 years earlier for the time before that. Would it be fair to call me a negligent eater? Have you been walking and tripped over nothing? Humans are fallible and unless you are in an environment where the productivity loss of a rigorous checklist and routine system makes sense these mistakes happen.

It would be just as easy to argue that anyone who uses software and hasn't confirmed their security certifications include whatever processes you imagine avoids 'human makes 1 mistake and continues with normal workflow' error or holds updates until evaluated is negligent.

gcau

Humans are imperfect and anyone can make mistakes, yes. I would argue there's different categories of mistakes though, in terms of potential outcomes and how preventable they are. A maintainer with potentially millions of users falling for a simple phishing email is both preventable and has a very bad potential outcome. I think all parties involved could have done better (the maintainer/npm/the email client/etc) to prevent this.

jowea

I feel that most everyone has some 0.0001% chance of falling for a stupid trick. And at scale, a tiny chance means someone will fall for it.

Havoc

Really feels like these big open packages repos need a better security solution. Or at least a core subset of carefully vetted ones.

Same issue with python, rust etc. It’s all very trust driven

cgh

Is the fundamental problem with npm still a lack of enforced namespacing?

In the Java world, I know there’s been griping from mostly juniors re “why isn’t Maven easy like npm?” (I work with some of these people). I point them to this article: https://www.sonatype.com/blog/why-namespacing-matters-in-pub...

Maven got a lot of things right back in the day. Yes POM files are in xml and we all know xml sucks etc, but aside from that the stodgy focus on robustness and carefully considered change gets more impressive all the time.

hyperpape

Nothing about this attack would be solved by namespacing, but it might have been solved by maven's use of GPG keys.

zenmac

isn't time NPM start to use that? Why has this taken soo long?

lpln3452

In a case like this, the package maintainer's account itself has been hacked, so I'm not sure if that would be meaningful.

The only solution would be to prevent all releases from being applied immediately.

dherls

A solution could be enforcing hardware keys for 2FA for all maintainers if a package has more than XX thousand weekly downloads.

No hardware keys, no new releases.

ozim

Passkeys - no need for hardware key.

They have it implemented.

I created NPM account today and added passkey from my laptop and hardware key as secondary. As I have it configured it asked my for it while publishing my test package.

So the guy either had TOTP or just the pw.

Seems like should be easy to implement enforcement.

dsff3f3f3f

There needs to be a massive push from the larger important packages to eliminate these idiotic transitive dependencies. Core infrastructure shouldn't rely on trivial packages maintained by a single random person from who knows where that can push updates without review. It's absolutely insane.

ozim

Linux distributions packages are also very trust driven — but you have to earn trust to publish. Then there is whole system to verify trust. NPM is more like „everything goes”.

johnny22

It woudl'nt have solved this, because this publisher would have been trusted.

karel-3d

"there is no way to prevent this", says the only ecosystem where this regularly happens

dzogchen

Exactly! Extremely lazy conclusion.

dang

Related. Others?

DuckDB NPM packages 1.3.3 and 1.29.2 compromised with malware - https://news.ycombinator.com/item?id=45179939 - Sept 2025 (209 comments)

NPM debug and chalk packages compromised - https://news.ycombinator.com/item?id=45169657 - Sept 2025 (719 comments)