A security warning about a popular npm package can leave developers with an immediate question: Is the version installed in my project affected, or did the problem exist only in the source repository?
The Zod 4.6.6 incident is a useful example of why that distinction matters. On September 21, 2026, malicious commits reached the Zod GitHub repository. The maintainers reverted those changes, and the malicious code was not published in the Zod npm package. The released version 4.6.6 was published later from a clean source tree. The incident also led to changes in the project's release process. <Cite refs={["turn584841search2","turn584841search4"]}/>
This does not mean developers should ignore the warning. If your project uses Zod, check the installed version, inspect the dependency lock file, and determine whether your build process downloaded code from npm or directly from Git.
What Happened in the Zod Incident?
Zod is a TypeScript validation library. Developers use it to check whether incoming data matches an expected structure before passing that data to application code.
For example, an API may receive a request containing a user ID and an email address. Zod can validate those values before the application processes them.
The September incident involved malicious changes to the project's source repository. Those changes were reverted, and the maintainers confirmed that the malicious code did not reach the published Zod npm package.
The confusion arose because the GitHub release information included commits associated with the incident. Seeing a suspicious commit in a release history does not automatically prove that the corresponding npm package contains the same code.
The important distinction is between three things:
- Source code in a Git repository.
- A package published to the npm registry.
- A package actually installed and used by an application.
Each needs to be checked separately.
1. Find the Installed Zod Version
Start in your project's root directory. Run the following command:
npm ls zod
This displays the installed Zod package and its dependency relationships.
For example, the output might show:
my-application
└── [email protected]
This tells you that the displayed dependency tree contains Zod 4.6.5. It does not establish whether the version is affected by a particular security issue.
If you use pnpm, run:
pnpm why zod
For Yarn, use:
yarn why zod
These commands help identify which package requires Zod and whether multiple versions are installed.
Check direct and transitive dependencies. Your application may not list Zod directly in package.json, but another package may depend on it.
2. Inspect package.json and the Lock File
The package.json file declares your project's dependency requirements. The lock file records the versions resolved during installation.
For an npm project, inspect these files:
package.json
package-lock.json
Look for the Zod entry in both files. You can search from the command line:
npm pkg get dependencies.zod
npm pkg get devDependencies.zod
These commands show whether Zod is declared directly as a production or development dependency. They do not reveal every transitive installation, so keep the output of npm ls zod as part of the investigation.
For a quick check of the lock file, use:
npm ls zod --all
The --all option shows nested dependencies as well.
Do not edit the lock file manually to remove a suspicious version. First determine which package introduced it and whether a supported fixed version is available.
3. Check Whether the Project Uses npm Packages or Git Dependencies
This is an important step when investigating a source repository incident.
A dependency can be installed from the npm registry, a Git repository, a Git commit, or a local directory. These installation methods do not necessarily provide the same source contents.
In package.json, a normal npm dependency may look like this:
{
"dependencies": {
"zod": "4.6.6"
}
}
A Git dependency can look like this:
{
"dependencies": {
"zod": "github:colinhacks/zod#main"
}
}
The second example follows the repository's main branch. Its resolved contents can differ from a published npm package, and a branch can change over time.
For reproducible builds, prefer an approved package version and commit the appropriate lock file. If your project deliberately installs from Git, inspect the exact resolved commit and its history.
The dependency declaration alone is not enough to establish what was installed. Check the lock file and the package contents used by the build.
4. Check the Dependency History in Git
If your project uses Git, review when the dependency declaration or lock file changed.
Run:
git log --oneline -- package.json package-lock.json
This lists commits that changed either file. To inspect a particular change, use:
git show <commit-id>
Replace <commit-id> with the relevant commit identifier.
You can also check the current working tree:
git status --short
This helps identify local modifications that could affect your investigation.
For a more focused review, inspect the lock file's history and compare it with the dependency update pull request. Determine who introduced the version, which source was used, and whether the package changed during the incident window.
A normal Git history review cannot prove that a downloaded package is safe. It helps establish how the project selected its dependency. Package provenance and artifact inspection provide additional evidence.
5. Verify the Published Package and Security Advisory
Do not decide that a version is malicious just because a security alert mentions it.
For the Zod incident, the published npm package and the GitHub source history had different security implications. The malicious repository changes were reverted and did not reach the published Zod package. The maintainer's release notes also documented the incident.
You can inspect package metadata using npm:
npm view [email protected] version dist.tarball dist.integrity
This displays the requested version and registry metadata, including the package tarball location and integrity value when available.
To check which versions your project currently has installed, use:
npm ls zod --all
For a general dependency vulnerability scan, run:
npm audit
Review the advisory details and affected version ranges instead of treating every warning as proof of exploitation. Also remember that an audit result can change as advisories are added or updated.
For packages that came from Git, review the resolved commit and inspect the source history. For packages downloaded from npm, verify the registry artifact and its provenance where available.
6. Update Zod Safely
If your investigation identifies an affected version, or a newer release contains a security fix relevant to your project, plan a controlled update.
First, check which version npm currently reports:
npm view zod version
Then update the dependency using your project's package manager. For a direct npm dependency:
npm install zod@latest
This updates the package to the latest version available at the time of installation. In a production application, do not use latest blindly. Review the release notes, compatibility requirements, and changes to the lock file before merging the update.
Run your tests:
npm test
If the project has a separate build command, run that too. Check API validation, form submissions, and other code paths that rely on Zod schemas.
After reviewing the changes, commit the updated dependency declaration and lock file together. This helps CI and other developers reproduce the same installation.
Common Mistakes to Avoid
One common mistake is assuming that a version mentioned in a security headline must contain malicious code. The Zod incident shows why the source repository and published package must be investigated separately.
Another mistake is checking only package.json. A transitive dependency may introduce Zod, or the lock file may resolve a different version than expected.
Developers also sometimes run npm audit and assume that no reported vulnerability means the package is safe. Audit results are useful, but they do not detect every supply-chain compromise or prove that a particular artifact matches its source.
Finally, avoid deleting dependencies or upgrading every package at once. Identify the affected dependency, understand the source of the warning, and make a controlled change.
Best Practices for Dependency Security
- Commit the lock file and use reproducible installations in CI.
- Review both direct and transitive dependencies.
- Prefer published package versions over moving Git branches when practical.
- Verify the affected version range in the relevant security advisory.
- Review package provenance and integrity information when available.
- Keep dependency update changes separate from unrelated application changes.
- Run tests and builds after security updates.
- Review installation scripts and dependency changes before merging updates.
- Keep an audit trail of the version, source, and reason for each security-related change.
Advantages and Disadvantages of Dependency History Checks
Advantages | Disadvantages |
|---|
Helps identify where a dependency came from | Requires time to inspect lock files and Git history |
Distinguishes repository changes from published package contents | Does not automatically prove that an artifact is safe |
Helps find unexpected or outdated dependency versions | Transitive dependencies can make the tree harder to review |
Supports better incident response and reproducible builds | Provenance information may be missing for some packages |
Troubleshooting Common Problems
npm ls shows more than one Zod version
Check which parent packages require each version. Update the responsible dependency where possible, and test before forcing a single version through an override.
The lock file contains a Git reference
Inspect the resolved commit recorded in the lock file. Determine whether the dependency was intentionally installed from Git and whether the commit falls within the relevant incident period.
npm audit reports no problems
Check the specific security advisory and its affected version range independently. An empty audit result is not proof that the package has never been compromised.
The package version looks safe, but the build is suspicious
Review the package source, installation scripts, CI logs, and dependency provenance. If you have evidence that malicious code executed, treat the issue as a potential security incident and follow your organization's incident response process.
Summary
The Zod 4.6.6 incident demonstrates why dependency security checks need more than a version number. Malicious commits reached the source repository, but the changes were reverted and did not reach the published Zod npm package.
Start by checking the installed dependency tree, reviewing the lock file, and determining whether the project uses an npm package or a Git-based dependency. Then compare the evidence with the relevant security advisory and package metadata.
If an update is needed, make the change in a controlled branch, review the lock file, and run the application's tests before deployment. These steps help developers respond to security alerts based on evidence instead of assumptions.
Join the conversation! Your thoughts help the community grow.