A poisoned update is a release that carries deliberately malicious code, delivered through a normal upgrade path. A vulnerability is an accidental flaw in honest code. Scanners match known vulnerabilities by identifier. A poisoned update may have no identifier at first, so detection and response differ.
Two different problems
| Vulnerability | Poisoned update | |
|---|---|---|
| Cause | A mistake in the code | A deliberate act |
| Author's intent | None | Malicious |
| Identifier | Usually a CVE, after disclosure | Often none at first |
| Affected versions | A range, fixed later | Specific bad versions, then removed |
| Typical fix | Upgrade to a patched version | Remove, roll back, rotate secrets |
The key practical difference is the direction of the fix. With a vulnerability, upgrading helps. With a poisoned update, upgrading to the newest version may be exactly what hurt you.
How a poisoned update reaches you
The attacker needs one of the entry points from our overview: a stolen publishing credential, a taken-over account, a compromised build, or a tampered mirror or update channel. The SLSA threats overview lists these as separate links: uploading a modified package that does not match the build process, compromising the build platform, and compromising the package registry.
Your tooling then does the rest. A range such as a caret version in a manifest, or an automated update bot, pulls the new release without a person reading it.
Why scanners may not see it at first
Vulnerability scanners compare your inventory to databases of known issues. A freshly poisoned release is not in the database yet. Detection comes from other signals: a package that suddenly adds install scripts, a new network call, a publisher change, or a report from a registry or researcher.
This is not a reason to drop scanning. It is a reason to add controls that work without a database entry.
Controls that help against poisoned updates
- Lockfiles and pinned versions, so builds do not drift to a new release unseen.
- A short delay before adopting new versions. Pnpm's documentation says malware is usually detected quickly and its minimumReleaseAge setting defaults to one day. Dependabot also applies a default three day cooldown to version updates, though not to security updates.
- Reviewing dependency changes in pull requests, including new or changed install scripts.
- Provenance checks where available, which show where a package was built.
- A tested response plan for removing a bad version and rotating secrets.
The response differs too
For a vulnerability you plan an upgrade. For a poisoned update, assume anything the install could reach may be exposed: environment variables, tokens and keys on build machines. Rebuild from known good versions and rotate credentials. Our write-up on dependency cooldown periods explains the delay approach in detail.
Where Safeguard fits
Safeguard's zero-day discovery and continuous monitoring aim to surface newly reported problems in packages you use, and reachability analysis helps you judge what matters. Autonomous remediation with fix PRs is off by default, with every category on Manual.
Quick check
Does a clean vulnerability scan rule out a poisoned update?
No. A scan reports known issues. A new malicious release may not be known yet.
Should I upgrade immediately when a new version appears?
For a security fix, yes, after a quick review. For routine updates, a short wait lowers risk.
Sources
- SLSA: Supply chain threats
- pnpm: Mitigating supply chain attacks
- GitHub Docs: Dependabot options reference
Last reviewed: 19 October 2026.