Malicious npm and PyPI packages

Threat model and measurement · this page 31 October 2026

The shape. A package that runs code when it is installed, published under a name one letter away from a popular one, or taken over from its maintainer, reaches a developer the moment npm install or pip install runs. An AI coding agent types those commands for you. The campaigns RepoGates lists are reported in OSV's malicious-package records (MAL- entries) and by researchers such as JFrog's testmetest report, whose 15 npm package names are on the campaign blocklist.

What RepoGates checks on a package

Twelve checks, read from the registry's own record and never from the package's code (the list):

A package the registry no longer serves is not assessable, never a pass. Since 31 October, OSV is asked about such a name too, and a MAL- record blocks it, because a removed name can be registered again.

Measured on 31 October 2026

ListPackagesPASSREVIEWBLOCK
npm, most depended on200186140
PyPI, most downloaded200189110

Most REVIEWs on npm are a new publisher on the latest release (a maintainer change, read from npm's record); most on PyPI are a name the declared repository's manifest does not carry (monorepos). Neither list had a BLOCK. We also ran 98 npm and 100 PyPI packages from the OSV malicious-package dataset: none passed. Most PyPI samples had been removed from the registry and were "not assessed"; that is what led to the OSV lookup for removed names above, which has not been re-measured yet.

Where it runs

In Claude Code with the RepoGates plugin, npm install, pip install, npx and npm create lines are checked before they run; the MCP server answers the same question for any agent that asks. On npmjs.com and pypi.org pages the verdict is answered through the agent surfaces, not the browser board.

What RepoGates does not see

It does not see git clone, package managers or curl — outside Claude Code with the RepoGates plugin, whose hook refuses a clone or install that names a blocked repository on the command line, before it runs. Direct dependencies named on the command line only; transitive dependencies and lockfiles are not resolved. It does not read a package's code or what the package installs after it, and a clean result is not an audit.

Add RepoGates to Chrome or Edge The Claude Code plugin