Rendered at 01:34:19 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
yuvalkarmi 17 hours ago [-]
This is 3 weeks back, folks. It WAS real repository compromise - it made it to Zod's main, but not to npm.
On September 21, someone used Colin's git credentials to push this compromised code into the project, Colin caught it, and reverted it that same day (PR #6620). He subsequently did release 4.6.6 on October 11, but it did NOT contain the infected code.
Btw, Zod wasn't the only package targeted - same attack was attempted against standard-schema and nub. Nub DID make it to npm, but npm's malware scanning blocked it.
Looks like a legit (well, illegitimate) attempted supply-chain attack, but no actual Zod release was compromised.
So I think it's not a great leap to think this commit actually made it to 4.6.6 on npm.
Good that it didn't though!
pier25 5 hours ago [-]
> it made it to Zod's main, but not to npm
Thank god. Zod reached like 350M weekly downloads recently.
Rapzid 16 hours ago [-]
Viewed through the lens of Zod's responsibilities and processes I'd say a release was absolutely compromised. They cut and submitted a compromised release to npm; npm just happened to block the publishing.
colinmcd 9 hours ago [-]
This is not the case. Zod's release CI was not triggerable via commits/tags by design. It used environment-scoped trusted publishing, which requires a GitHub token with elevated permissions. No releases of Zod or Standard Schema were sent to npm. Their security advisory is very misleading in this regard, which is why I tried to clarify the situation in my comment. [0]
nowhere in gp's comment do they claim it was published
sdthjbvuiiijbb 16 hours ago [-]
The comment you replied to meant never submitted for publishing.
>They cut and submitted a compromised release to npm; npm just happened to block the publishing.
The point is that this is incorrect. A compromised release was not submitted to npm. It didn't make it beyond the git repo.
calyhre 15 hours ago [-]
It claims a release was sent to NPM, and this is not true. The maintainer of Zod made sure even this kind of attack could not proceed with a publication. The comment I answered to is dismissing these efforts put in place by Colin.
jaynetics 17 hours ago [-]
The compromised code wasn't actually released. This write-up has a lot of information:
A very pertinent comment from zod's maintainer, from that page:
> EDIT Sept 24 — All of my packages on npm have migrated to use environment-scoped staged publishing triggerable only by workflow_dispatch. This means 2FA is always required, so even if (god forbid) an npm or GitHub token is compromised, it will not be possible for the attacker to publish new versions.
So at least that's good to see. It would be nice for them to actually remove the commit from git history, though...
luggage_bazooka 17 hours ago [-]
Close call, nevertheless, it's silly to keep that commit on the release page.
steve_taylor 17 hours ago [-]
It's silly to not have rewritten it out of git history.
sigotirandolas 15 hours ago [-]
Yeah. A git bisect can still hit it.
It definitely doesn't inspire confidence in the project taking security seriously.
(Also the "write-up" is almost surely a "Claude-up", though it appears generated by someone external to the project).
arcfour 13 hours ago [-]
He is (evidently) the product manager of NPM, so while external, I guess he should have a good idea of what's going on. Claude generated, yes, appears so, though it appears to be factually correct and fairly brief, from my quick perusal.
andy_ppp 15 hours ago [-]
They still have the opportunity to remove it I guess?
Not looking great is an understatement. You should raise more alarms at github. And people should try to reach the maintainers.
thesimon 17 hours ago [-]
[dead]
jaapz 17 hours ago [-]
Might is pretty tame, it is infected - EDIT: title was changed, it said "might be infected".
The malware seems to inject some JS payload to execute when zod is installed, by fetching it from an ethereum smart contract (if I understand it correctly).
Right, 3 seconds in, as soon as I saw “ethereum” in a typescript validator the first thought was the same.
xx_ns 17 hours ago [-]
Interestingly, they added the `preinstall` key (that is supposed to run the malicious script when installed) under the package.json root, and not under `scripts`, so from what I can tell this wouldn't run on install.
Otherwise, yeah, this seems like a stage-1 loader for fetching and running a payload off the Ethereum mainnet.
nicce 17 hours ago [-]
Great reminder to always disable these scripts unless going through the hassle to verify if it does something absolutely useful.
chrisweekly 13 hours ago [-]
Use pnpm!
madeofpalk 13 hours ago [-]
Every node package manager disables preinstall scripts by default now!
nicce 13 hours ago [-]
You need to explicitly update npm to 12 before this is true in Node.
ameliaquining 13 hours ago [-]
That's no longer necessary for security; npm doesn't run install scripts by default anymore.
chrisweekly 12 hours ago [-]
Pnpm is still better in every way.
nicce 13 hours ago [-]
Default npm version is still 11 on every Node install. Almost there, but not yet!
ameliaquining 13 hours ago [-]
Huh, I already got the new behavior last time I tried this, and I didn't manually enable it. I wonder why.
nicce 11 hours ago [-]
You will get the warnings but default npm in Node will still run the scripts.
Zod maintainer here. As others have noted, this was three weeks ago and no malware was shipped in any release.
Zod's releasing CI was never triggered and it was not vulnerable to this kind of attack. It uses environment-scoped trusted publishing, so a regular push credential is not enough to trigger releasing. There's a security writeup from the NPM team here[0], though it strongly implies that malicious versions of Zod and Standard Schema were caught by their malware scanner. That's not the case. The attacker was not able of triggering Zod's release CI in the first place. I clarified this in my followup comment[1] and asked them to pick more accurate wording to avoid unnecessary FUD like this.
It seems like a git push credential, probably an SSH key, was exfiltrated from my local computer. The attacker used this to try to push malicious versions of Zod, Standard Schema, and nub. The release workflows for Zod and Standard Schema were not vulnerable against this. (Nub was, however, a release run was triggered, and npm's malware detector did flag it and prevent publication.)
It seemed shady to scrub the commits from history, and it still isn't obvious that doing so is better from a security standpoint. But since there are concerns around git bisect, etc, I've done so anyway. v4.6.6 will lose provenance, v4.6.7 is being released.
Since I don't know exactly what else what compromised, I've also done a fresh OS re-install and rotated all creds present on the old machine at the time of the compromise. All my packages have been switched over to staged publishing, which requires 2FA for any release.
Ironically this likely happened due to some work on an OS-level sandbox for Nub's package manager, designed to limit the blast radius of malicious lifecycle scripts. The attack is consistent with an more primitive precursor to the modern Shai-Hulud-style worms. While working on the sandbox, an ersatz agent likely executed a compromised version of some package on npm in a test run. I had safeguards against this (filtering out any OSV-flagged packages, etc) but perhaps there's an undiscovered malicious package. Future work on this feature will happen on an isolated VM.
Those are autogenerated release notes that list all commits in the diff. The bad commits were reverted before publication.
throwawayy6767 17 hours ago [-]
What are we looking at exactly? Gia Tan situation? Prompt injection?
ameliaquining 13 hours ago [-]
Nothing so exotic; a GitHub credential just got compromised. Happens all the time.
hizlikovboy27 17 hours ago [-]
I have many projects using this library. do u think the situtation is urgent, a code red?
I will need to talk to clients accordingly.
arcfour 13 hours ago [-]
This happened 3 weeks ago and no release was published on NPM containing the code.
ralusek 16 hours ago [-]
Never made it to npm you're fine
MisterMunchkin 17 hours ago [-]
That is 100% a compromised repo. It's a malware downloader.
I feel like they could have done a better job here. Having just a few changes, one of which is a huge blob of blatantly compromising code, is just too obvious.
The URLs are interesting, I don't do anything in this area but I didn't know that you could use the blockchains to hide your command and control URL, in a way that allows you to remotely update the URL whenever you want. It turns out there is a use for blockchain! Making control URLs immune to takedowns!
17 hours ago [-]
17 hours ago [-]
erzhan89 17 hours ago [-]
malicious remote-code loader
blueblazin 17 hours ago [-]
How is this even possible? The change is small and literally has an ethereum URL in the code changes. How did it go through?
ozyschmozy 17 hours ago [-]
From the repo owner:
> Seems like a git push credential of some kind was compromised, not an npm or GitHub token. Still working with the GitHub team to get some better forensics on what/how. The attack consisted of malicious commits and tagged pushes to main.
So it didn't go through review, it was pushed straight to main. It also seems their publishing pipeline was already secured against this sort of thing:
> Zod's release flow was already secured against kind of attack via trusted publishing and a dedicated GitHub environment for secure deployments. Zod's release CI worked as designed and was already secure against this; NPM's malware scanning didn't prevent any malicious here.
rfgplk 17 hours ago [-]
LGTM
rjfernandes 12 hours ago [-]
[flagged]
SquidJack 17 hours ago [-]
[flagged]
eviks 16 hours ago [-]
[flagged]
rfgplk 17 hours ago [-]
[flagged]
whstl 17 hours ago [-]
This problem definitely exists in C++ or Rust.
The solution in those languages is either to use something like serde validator, garde (for Rust), or go all the way to protobufs... or write your own data validation/parsing by hand.
Rust and C++ don't even have a Javascript deserializer.
oraro 17 hours ago [-]
Agree with you on it being the fault of the ecosystem. But, Zod is pretty good for parsing (rather than validating). It is IMO what makes TS (or should I say Zodscript) very successful
oraro 17 hours ago [-]
classic crypto people doing classic crypto things
rarisma 17 hours ago [-]
Yep, def looks bad.
Just pasted the code into claude to try and decipher the minified js and looks like it tries to find the server via the blockchain? and then download further stuff from there.
SlightlyLeftPad 17 hours ago [-]
Don’t even need to go that far, it refers to ethereum in plain text.
On September 21, someone used Colin's git credentials to push this compromised code into the project, Colin caught it, and reverted it that same day (PR #6620). He subsequently did release 4.6.6 on October 11, but it did NOT contain the infected code.
Btw, Zod wasn't the only package targeted - same attack was attempted against standard-schema and nub. Nub DID make it to npm, but npm's malware scanning blocked it.
Looks like a legit (well, illegitimate) attempted supply-chain attack, but no actual Zod release was compromised.
So I think it's not a great leap to think this commit actually made it to 4.6.6 on npm.
Good that it didn't though!
Thank god. Zod reached like 350M weekly downloads recently.
[0] https://github.com/orgs/community/discussions/208477#discuss...
>They cut and submitted a compromised release to npm; npm just happened to block the publishing.
The point is that this is incorrect. A compromised release was not submitted to npm. It didn't make it beyond the git repo.
https://github.com/orgs/community/discussions/208477
> EDIT Sept 24 — All of my packages on npm have migrated to use environment-scoped staged publishing triggerable only by workflow_dispatch. This means 2FA is always required, so even if (god forbid) an npm or GitHub token is compromised, it will not be possible for the attacker to publish new versions.
So at least that's good to see. It would be nice for them to actually remove the commit from git history, though...
It definitely doesn't inspire confidence in the project taking security seriously.
(Also the "write-up" is almost surely a "Claude-up", though it appears generated by someone external to the project).
I didn't study what packages/mini/meta.test.mjs is doing in particular but it's not looking great
The malware seems to inject some JS payload to execute when zod is installed, by fetching it from an ethereum smart contract (if I understand it correctly).
Don't forget to flag the version on npm.
EDIT: looks like the update never got on NPM: https://news.ycombinator.com/item?id=50053253
Otherwise, yeah, this seems like a stage-1 loader for fetching and running a payload off the Ethereum mainnet.
npm 12 has the relevant breaking changes: https://github.blog/changelog/2026-06-09-upcoming-breaking-c...
Node 27 will likely ship with it:
https://github.com/nodejs/Release/issues/1161
https://github.com/npm/cli/issues/9997
Zod's releasing CI was never triggered and it was not vulnerable to this kind of attack. It uses environment-scoped trusted publishing, so a regular push credential is not enough to trigger releasing. There's a security writeup from the NPM team here[0], though it strongly implies that malicious versions of Zod and Standard Schema were caught by their malware scanner. That's not the case. The attacker was not able of triggering Zod's release CI in the first place. I clarified this in my followup comment[1] and asked them to pick more accurate wording to avoid unnecessary FUD like this.
It seems like a git push credential, probably an SSH key, was exfiltrated from my local computer. The attacker used this to try to push malicious versions of Zod, Standard Schema, and nub. The release workflows for Zod and Standard Schema were not vulnerable against this. (Nub was, however, a release run was triggered, and npm's malware detector did flag it and prevent publication.)
It seemed shady to scrub the commits from history, and it still isn't obvious that doing so is better from a security standpoint. But since there are concerns around git bisect, etc, I've done so anyway. v4.6.6 will lose provenance, v4.6.7 is being released.
Since I don't know exactly what else what compromised, I've also done a fresh OS re-install and rotated all creds present on the old machine at the time of the compromise. All my packages have been switched over to staged publishing, which requires 2FA for any release.
Ironically this likely happened due to some work on an OS-level sandbox for Nub's package manager, designed to limit the blast radius of malicious lifecycle scripts. The attack is consistent with an more primitive precursor to the modern Shai-Hulud-style worms. While working on the sandbox, an ersatz agent likely executed a compromised version of some package on npm in a test run. I had safeguards against this (filtering out any OSV-flagged packages, etc) but perhaps there's an undiscovered malicious package. Future work on this feature will happen on an isolated VM.
[0] https://github.com/orgs/community/discussions/208477
[1] https://github.com/orgs/community/discussions/208477#discuss...
https://github.com/colinhacks/zod/commit/10dda3a3a4bc76ed0bf...
I feel like they could have done a better job here. Having just a few changes, one of which is a huge blob of blatantly compromising code, is just too obvious.
The URLs are interesting, I don't do anything in this area but I didn't know that you could use the blockchains to hide your command and control URL, in a way that allows you to remotely update the URL whenever you want. It turns out there is a use for blockchain! Making control URLs immune to takedowns!
> Seems like a git push credential of some kind was compromised, not an npm or GitHub token. Still working with the GitHub team to get some better forensics on what/how. The attack consisted of malicious commits and tagged pushes to main.
So it didn't go through review, it was pushed straight to main. It also seems their publishing pipeline was already secured against this sort of thing:
> Zod's release flow was already secured against kind of attack via trusted publishing and a dedicated GitHub environment for secure deployments. Zod's release CI worked as designed and was already secure against this; NPM's malware scanning didn't prevent any malicious here.
The solution in those languages is either to use something like serde validator, garde (for Rust), or go all the way to protobufs... or write your own data validation/parsing by hand.
Rust and C++ don't even have a Javascript deserializer.
Just pasted the code into claude to try and decipher the minified js and looks like it tries to find the server via the blockchain? and then download further stuff from there.