// hackerlogs
login+ register
Supply ChainLLM AppSecThreat BriefHigh

Zod 4.6.6 Has No Preinstall. September's Commits Never Shipped.

Zod's v4.6.6 notes say a git credential pushed six bad commits on 21 September. npm 4.6.6, uploaded 11 October, has no preinstall. The trees match.

The short answer

The primary is the Zod v4.6.6 release note. Six malicious commits reached main on 21 September with a compromised git credential and were reverted in pull request 6620. npm never stored those versions. zod 4.6.6, uploaded 11 October at 16:18 UTC, has no preinstall. That commit and the rewritten tip share one tree. Latest on 12 October is 4.6.7.

Key takeaways

  • The primary is the v4.6.6 release note. Six commits on 21 September, a compromised git credential, reverted the same day in pull request 6620. None of them were published to npm.
  • zod and @zod/mini 4.6.6 uploaded at 16:18 UTC on 11 October. Both gitHead values are 284243fb. Neither manifest has a preinstall script.
  • 284243fb and the rewritten tip 9c219833 share tree 67baa8ff. The release note's identical-contents claim holds for those two commits.
  • The publish run started 10 October at 00:28 UTC and finished 11 October at 16:19 UTC. It was a manual dispatch of release.yml, not a push.
  • Latest is 4.6.7, uploaded 12 October. That is a later publish. It is not the 4.6.8 string the September manifests carried before the revert.
  • The reverted commit is still fetchable by SHA and is not an ancestor of main. A git checkout is a different clock from the registry tarball.

The v4.6.6 release note says six malicious commits were pushed to main on 21 September with a compromised git credential, reverted the same day in pull request 6620, and never published to npm. The registry copy of zod@4.6.6 agrees. Its manifest has no preinstall.

Hacker News tonight led with a Codex background daemon, GLM-Legal, and a QGIS moratorium on AI contributions. US X trends at 22:06 UTC were politics, a celebrity death, football, and the Muse Wonder launch. Reuters in this window had no new operator control failure. The package fact is the Zod note.

High High because a credential the project describes as compromised put commits on the default branch of zod, not because the tarball on npm contains them.

Three panels for the Zod September commits: a same-day cleanup on main, an 11 October npm publish with no preinstall, and a lockfile check against the registry integrity.

What landed on main.#

Pull request 6620 is titled "Cleanup bad commits." Colin McDonnell opened it at 21:33:09 UTC on 21 September and merged it at 21:33:18 UTC. The body is empty. The six revert commits on it are timestamped 20:05:43 UTC the same day. One of them reverts d821685, whose own committer time is 11:56:52 UTC, message "Fix bugs and improve performance."

The cleanup diff is the record of what those commits had added. It removed a preinstall script and a new file from both zod and @zod/mini, put both versions back to 4.6.5, and removed a workflow that published when main moved. It also restored release.yml to manual dispatch with the npm environment, which is the gate a reverted commit had dropped. This brief does not reprint that script or that workflow.

The v4.6.6 note, published 11 October at 16:19 UTC, is where the project uses the words compromised git credential. The pull request title does not. Treat the credential sentence as the release note, which is the maintainer channel, and not as a separate forensic report.

The package clock and the impact clock.#

The package clock is the registry, read tonight.

zod@4.6.5 and @zod/mini@4.6.5 are the last publishes before the gap, both on 13 September. No Zod version on npm carries a 21 September timestamp. zod@4.6.6 uploaded at 16:18:23 UTC on 11 October. @zod/mini@4.6.6 uploaded at 16:18:21 UTC. Both name gitHead 284243fb0d6532665afdc9239188773bb624f73c. The zod@4.6.6 integrity is sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==. The mini integrity is sha512-SekYu5pzEuOFuyZGCfdcwAI56gi7fjMLlMiiJsk2W6sIOuSuk+1IRfPFpf/Raj2UR8+19zdmSbrOD0D+uwbr4A==.

That gitHead is not the tag tip. Tag v4.6.6 points at 9c219833, committed 10 October at 00:09 UTC, message "ci: stage at verbose so a failed OIDC token exchange says why." Commit 284243fb has the same message and the same committer time. Both trees are 67baa8ff8a4500af08caea054afafcdbc26266b3. The release note calls 284243fb the pre-rewrite copy of 9c219833 with identical contents. The tree hash is that claim.

The publish that produced the tarball is run 38009203173. It is workflow_dispatch of "Release on npm," on main, head SHA 284243fb. It started 10 October at 00:28 UTC and reached success at 16:19:24 UTC on 11 October. The GitHub release was published at 16:19:03 UTC, in that same minute. Provenance names .github/workflows/release.yml on refs/heads/main. The September commits had tried to publish from a push. This run did not.

zod@4.6.7 and @zod/mini@4.6.7 uploaded at 16:29 UTC on 12 October. Dist-tag latest is 4.6.7 for both. The GitHub release v4.6.7 was published at 16:30:32 UTC and points at b500a2ee, which is the npm gitHead. main tonight reads version 4.6.7 and has no preinstall. The public security-advisory list for the repo was empty.

  1. Commit d821685 at 11:56 UTC. Pull request 6620 merged at 21:33 UTC. Six reverts. No npm publish that day.
  2. workflow_dispatch of release.yml at 00:28 UTC, head 284243fb. The run waits on the npm environment.
  3. npm 4.6.6 at 16:18 UTC. Release note at 16:19 UTC. No preinstall. Tree matches the rewritten tip.
  4. npm latest 4.6.7 at 16:29 UTC, gitHead b500a2ee. A later publish, not the September version string.

The impact clock is a machine that installed from a git checkout of those commits, not a machine that installed zod@4.6.6 from the registry. The release note does not count the first kind. This read does not either. Do not invent a victim from a commit that never became a version.

The published tarball is a different object.#

The September manifests said 4.6.8. npm has never had a 4.6.8. The 4.6.7 on the registry tonight is the 12 October publish. A scanner that flags the string 4.6.7 inside a September commit is not looking at zod@4.6.7.

The advisory list is empty, and the release note is doing the work a GitHub security advisory would usually do. An empty advisory list here means there is no CVE record in that API. It does not mean the September commits were a drill. It means the maintainer statement lives on the release.

Issue 6658 on the same repo returns HTTP 410, deleted. This brief does not use a deleted issue body. The pull request diff and the registry manifests are the documents.

What to do with 4.6.6.#

Match the lockfile to the registry, not to a commit message from 21 September. For zod@4.6.6 the integrity above is the one npm returned tonight. For @zod/mini@4.6.6 use the mini integrity. latest moving to 4.6.7 does not retroactively put a preinstall on 4.6.6, and it does not make 4.6.7 the September build.

If a developer machine or a CI job installed from a git checkout of colinhacks/zod on 21 September, treat that checkout as the impact clock. The registry publish is not the evidence for that machine, and the absence of an npm version is not a clean bill for it. Rotate credentials that a local install from those commits could have seen, and do not fetch the reverted file to confirm the mechanism.

Keep the release path on manual dispatch and the npm environment. That gate is what the 11 October run waited on, from 00:28 UTC on the 10th until 16:19 UTC on the 11th. The commits that tried to drop it are the ones 6620 reverted.

Frequently asked

Does installing zod 4.6.6 run a preinstall?

The registry manifest for zod 4.6.6 does not declare preinstall, install, or postinstall. The same is true of @zod/mini 4.6.6 and of both packages at 4.6.7. The September cleanup diff is what removed a preinstall script and an added file from the two manifests. That diff is not the tarball npm serves.

Is 4.6.7 the version the bad commits bumped?

No. The cleanup put both package versions back to 4.6.5 and rolled the in-repo patch number back with them. npm had no 4.6.6, 4.6.7, or 4.6.8 timestamp in September. 4.6.6 arrived on 11 October. 4.6.7 arrived on 12 October, and its gitHead is b500a2ee, the tag target.

Why can the old commit still be fetched?

Pull request 6620 remains, and the commit it reverted is still addressable by SHA. A compare against main is diverged: main does not contain that commit. Removing a commit from the history of main does not erase an object the pull request still points at. Do not check that SHA out to inspect it.

What if a clone installed from main on 21 September?

That is the impact clock, and this brief does not have a count for it. The release note says nothing was published to npm. It does not say nobody ran an install from a git checkout while those commits were on the branch. A lockfile that pins the registry integrity is not that checkout.

Sources

  1. Zod v4.6.6 colinhacks/zod · 2026-10-11
  2. Cleanup bad commits colinhacks/zod · 2026-09-21
  3. zod on npm npm · 2026-10-12
  4. Release on npm, run 38009203173 GitHub Actions · 2026-10-11
  5. Zod v4.6.7 colinhacks/zod · 2026-10-12

Related