Top
Best
New

Posted by cimi_ 9 hours ago

Keyv and friends compromised in active Shai-Hulud supply chain attack(www.aikido.dev)
201 points | 104 comments
ChrisMarshallNY 3 hours ago|
OW. That's gonna leave a mark.

It sucks that we have this glass-jaw dependency system, which is really the main reason these supply chain attacks work.

Really hard to clean up, too. These days, you (being the blackhat) would likely send agents to leverage every compromised repo/app/Web site, almost the instant it comes online, so even if the original mess is cleaned up, there's still a ton of knock-on compromises.

xnorswap 6 hours ago||
At this point, any package adding a pre-install hook where there previously was not one should be denied and treated with extreme suspicion.

It's time pre-install / post-install hooks were killed off. Start with a moratorium on any new ones.

jitl 5 hours ago||
yeah but they can just put the dropper, etc in index.js, so that it runs at import time rather than at install time, no? i guess first-install time is often a privileged developer machine, and will execute in a "server"-like runtime such as Node, Bun, Deno. but blocking preinstall scripts is basic first aid...
jerf 5 hours ago|||
Nobody is claiming this is a complete solution to security. I would call this "necessary but not sufficient". You won't get far as an engineer if you refuse to implement "necessary but not sufficient" changes because the change doesn't in and of itself one-shot the entire problem.
csomar 4 hours ago|||
These half-measures is why everything has gone to shits. Instead of properly auditing software, reducing the quantity and increasing the quality, we keep pushing more and more garbage where all you find is 2FA that, captcha this, not supported this, app not signed, etc..
woodruffw 2 hours ago||
Defense in depth is the “meat and potatoes” of security.

In other words: people should be auditing their software, but we should also design systems and schemes that provide varying degrees of defense and protection when people invariably fail to review the code they run.

rcxdude 2 hours ago||
Defence in depth is not just 'throw anything in that might improve security' though. The idea is to have multiple strong layers, not a hundred half-measures that are all easily bypassed. A stronger layer might be sandboxing, or separating your build and publishing steps as others have suggested (and also probably worth restricting the credentials the publishing step to just the relevant packages as well). These will at least robustly prevent a malicious dependency from spreading horizontally, but you'll still potentially ship malware to your customers.
woodruffw 2 hours ago||
I would consider 2FA and signing to be strong layers, when applied well. I think everybody agrees we shouldn’t add layers just for the sake of it.
rcxdude 5 hours ago|||
The fact that it's not sufficient also largely means it's not necessary either, because the real solution is auditing and trusting the codebase as a whole. All you do when disabling install hooks is make a lot of situations much more difficult to handle.
jerf 5 hours ago|||
You will also not get very far in engineering if you have a production incident, someone proposes a thing that will mitigate it partially but significantly, and you insist that we can't deploy that mitigation because we need to do the multi-year project that will actually fix it instead. Even if we still need that project, we also need that mitigation.

Sure, solve the problem of "auditing and trusting codebases". Go for it. Shouldn't take you until, oh, let me be generous and give you until next Monday. No sweat.

rcxdude 4 hours ago|||
Feel free to turn it off yourself, just don't be surprised when the attackers switch tactics. And don't make life harder for everyone else by pushing it as mandatory.

(if you want a better mitigation: don't automatically update dependencies in CI. At a minimum have a cooling-off period that you only bypass on manual review. This is not hard to implement and at least gives some time for alarm bells to be sounded before you're pwned. Probably while doing the updates you can also just do a quick sanity check on the changes, that'll also catch the ones using a blatant install hook)

esseph 3 hours ago||
> if you want a better mitigation: don't automatically update dependencies in CI. At a minimum have a cooling-off period that you only bypass on manual review. This is not hard to implement and at least gives some time for alarm bells to be sounded before you're pwned.

One of the problems a lot of companies are having right now is trying to determine a proper window size between CVE release and patching.

On one hand, you have LLM created 0days and attacks are happening almost as fast as CVEs can be posted, and CVEs are being posted at lightning speed. You maybe had a month or a few weeks to patch before, now the window may be down to days or even hours.

On the other hand, you want to prevent these repo bombing attacks.

There's a tension there but I think we're going to end up measuring that window in hours within the year, if we're not already there.

rcxdude 3 hours ago||
If you need quick responses to such things, you're gonna need some intelligence in the loop regardless, even if it's just deciding when it's worth pushing a new release to prod.
esseph 2 hours ago||
What if it needs to get patched and pushed while you and everyone else in the org are asleep?

I mean that's a big window of time now.

rcxdude 2 hours ago||
Always has been, arguably. Either way I don't think most people have their CI configured to automatically re-run when a dependency updates (imagine the thundering herd!), the compromises are more incidental to runs happening for other reasons, and that configuration neither guarantees a quick response nor protects against supply chain attacks.

(If you find you do need updates when you're sleeping, you probably need to delegate that process or at least the process of checking the update to someone you trust, and you're probably paying for the service. This blog post is in large part an ad for just such a service).

BigTTYGothGF 3 hours ago|||
> You will also not get very far in engineering if

Man, I wish.

lkjdsklf 4 hours ago||||
Missile defense systems are unnecessary because they could just use tanks

Anti-tank measures are unnecessary because they can just use missiles

rcxdude 3 hours ago||
What's your solution to using a library without executing the code in it?
fhdkweig 4 hours ago||||
The term you are looking for is Defense in Depth/Layers
rcxdude 4 hours ago||
That makes sense if it's actually a layer. You can create a thousand minor obstacles and it still won't be a very secure system.
jitl 5 hours ago|||
"make no mistakes" is not the "real solution"
rcxdude 5 hours ago||
Neither is 'close the gate with no fence on either side of it'. If you want to run code, you either need to run it in a sandbox or trust it. Choosing to run only part of the code is not really a solution.

(if you want to disable such hooks yourself, then you may get some security by diversity because you're not using the common configuration. But if it becomes the default then these worms will switch to a different vector)

insanitybit 5 hours ago||||
Prod tends to have less privileges than CI/CD. CI/CD tends to be full admin, so it's far more sensitive. Prod tends to have tooling for detecting breaches, better logging, etc. People tend to use containers, which act as a sandbox.

Prod also won't be wormable the way that CI/CD is. With CI/CD I can own another dev, use their creds to push another malicious build script, etc. "Attacker is in my prod env" isn't wormable.

Yes, capabilities in prod would be hugely beneficial but removing CI/CD is massive as a win.

JustSkyfall 5 hours ago||
Wouldn't the dropper get executed once tests are run within CI though?
insanitybit 4 hours ago|||
Yes, you should separate "tests execute" into their own unprivileged workflows that don't have "deploy" secrets.
rcxdude 4 hours ago||
You can also do the same for the build workflow, no?
insanitybit 3 hours ago||
Yep, I'd recommend it.
jitl 5 hours ago|||
yeah, or when a dev starts the local development server (unless that server is containerized).
insanitybit 4 hours ago||
Dev laptops tend to have better monitoring than CI/CD so I still think this is a better option. You can also have devs use VMs or separate dev environments like an ec2 instance.

To be clear, just solving the CI/CD portion is insufficient, but it is a massive win.

sysguest 5 hours ago|||
well Deno has the necessary ingredients for defense: file-system permission by path
mechazawa 6 hours ago|||
iirc does pnpm not allow them by default. But even if we killed them off there would still be a chance of the malware hooking into something else or only working in cli applications.
madeofpalk 3 hours ago|||
The latest version of all node package managers (npm, yarn, pnpm) now deny this by default. pnpm was ahead of the curve.
jonchurch_ 3 hours ago|||
npm v12 released last month also defaults into blocking them by default
insanitybit 5 hours ago||
You'll just end up with people running `./configure` scripts or whatever instead. The solution I've currently landed on is:

1. Audit build scripts/ proc macros for rust code (and mark with cargo-vet).

2. Have an isolated workflow for "build/test/push artifact to temporary place" (s3, github artifact, whatever). No API keys in this workflow.

3. Have another workflow that has the API keys to publish that grabs the artifact and then places it into a registry.

This creates clear separation of "code runs here" and "environment has privileges".

In my own slop-driven programming language I have build scripts declare their capabilities upfront so that you can statically reason about them (same with runtime permissions).

jesse_dot_id 2 hours ago||
echo "min-release-age=5" >> ~/.npmrc

This should be your default minimum if you work with node.

freakynit 1 hour ago||
Updated my docs covering these attacks since 2025:

1. NPM Supply Chain Attack Techniques: https://npm-supply-chain-attack-techniques.pagey.site/

2. NPM Ecosystem Threat Report: https://npm-supply-chain-attacks-25-26.pagey.site/

mittermayr 6 hours ago||
Does anyone happen to have a grep or similar that helps me check if this is showing up anywhere in the trillions of files in node_modules (or pnpm store)?
rhdunn 5 hours ago||
The what happened section mentions the addition of the `setup.mjs` and `Math_Symbol.js`, along with a change in `package.json` to add `"preinstall": "node setup.mjs"`, so presumably checking for any of those would be a good indication to check further.

For example:

    find . -type f | grep -P "/Math_Symbol\.js$"
yread 4 hours ago||
Crucially, Math_Symbol.js that is almost 800KB, not the innocent 1KB one from regenerate-unicode-properties
somebudyelse 3 hours ago||
when i was searching i got a heartattack when i saw Math_Symbol.js. Thankfully my agent was able to figure it out.
chime 3 hours ago|||
Highly recommend `fd` for the sheer speed:

    fd -HI "^(setup\.mjs|Math_Symbol\.js|math_init\.js)$"
1. https://github.com/sharkdp/fd

2. `brew install fd`

byutifu 5 hours ago|||
This article has a lot of information and ways to check & clean: https://safedep.io/keyv-npm-supply-chain-compromise/
somebudyelse 3 hours ago||
I ended up asking my agent with auto mode:

can you search all installed node modules for any sign of the shai hulud supply chain attack? What happened Every package in the family received two new files, setup.mjs and Math_Symbol.js, along with a "preinstall": "node setup.mjs" entry added to each package.json. Anyone who ran npm install against an affected version would have had setup.mjs execute automatically before their install completed.

setup.mjs is a heavily obfuscated dropper. Its only job is to silently download the Bun JavaScript runtime from github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/ and use it to execute the real payload, Math_Symbol.js:

execFileSync(<bun binary>, ['<script_dir>/Math_Symbol.js'], { stdio: 'inherit', cwd: <script_dir> }) The Math_Symbol.js is a heavily obfuscated 728 KB JavaScript file containing credential stealers that harvest secrets from the victim's environment, encrypt the findings, and exfiltrate them to a public GitHub repository whose description reads "Shai-Hulud: Here We Go Again". The payload also contains worm-like propagation functionality to infect packages of other maintainers that have installed one of the compromised packages.

orheep 5 hours ago||
find . -type d -name node_modules -prune -exec find {} \( -name setup.mjs -o -name math_init.js -o -name Math_Symbol.js \) \; 2>/dev/null
evertheylen 2 hours ago||
Once again, I ask myself: should we start "shaming" developers who don't use isolation? It still seems I am the exception and most people run their dev environment with full permissions. Why?

I also wrote an article (https://evertheylen.eu/p/shame-devs-without-isolation/) to flesh out my thoughts, but I'd be really happy to discuss this in the comments.

avaer 7 hours ago||
I am kind of surprised GitHub doesn't seem to have built a simple classifier for public repos to proactively lock the account of anyone uploading such obviously fishy things (for their own good, at least before the repo is publicly findable), so it can't be used as a rendezvous.

Surely Github's software is good enough that an intern can slop the 80/20 together in a day? It would be an actually good use of AI spending.

abhisek 6 hours ago||
GitHub announced this a while back:

https://github.blog/changelog/2026-07-28-npm-publish-time-ma...

twistedpair 29 minutes ago|||
Ah, I see your problem there

> This requirement will be progressively enforced over time.

drakythe 2 hours ago|||
"A while back" -- One week ago.

I am curious if they are still implementing the process or if this particular attacker already figured out a way around it.

hulitu 6 hours ago||
> I am kind of surprised GitHub doesn't seem to have built a simple classifier for public repos to proactively lock the account of anyone uploading such obviously fishy things (for their own good, at least before the repo is publicly findable), so it can't be used as a rendezvous.

Maybe that's the idea. Regards, the <insert your favourite 3 letter agency here>

tomjen3 1 hour ago||
Where is the fbi in this? Why has no one been arrested? This is a massive crime.
ethanwillis 5 hours ago||
You know with all this AGI swirling around nowadays that is stronger than nation state hackers you think one of these companies would demonstrate just how capable they are by defending public infrastructure.

Unless...

Maybe in 6 months.

pixl97 3 hours ago|
LLMs are better at attacking than writing secure code.

LLMs aren't terrible at securing systems, humans are bad at using secure systems and typically disable measures with insecure workarounds.

codeduck 5 hours ago|
Oh boy, it's a big one.
TacticalCoder 5 hours ago|
> Oh boy, it's a big one.

Yup the "Update" in TFA is scary:

"Update — August 4, 2026, 13:37 CEST: At least 434 packages (across 1381 versions) have been compromised by the worm, with a combined total of over 2 billion monthly installs at the time of writing."

Lots of pain ahead.

twistedpair 28 minutes ago|||
2,523 and counting
somebudyelse 4 hours ago|||
the irony of the update being at 1337
More comments...