Check npm and PyPI packages for compromise
Start with the recent changes, not the package name. A clean reputation yesterday does not help much if a new release arrived with a different maintainer, a sudden version jump, or an install script that has no obvious reason to exist. In Node.js and Python, install-time scripts can run code straight away, which gives a malicious update a short but very effective life before anyone notices.
Dependency review needs to include transitive dependencies, not just the package you picked on purpose. One package can drag in several more, and one of those can be the part that has gone bad. Registry activity matters too. A package that starts talking to unfamiliar endpoints, pulls in odd extras, or appears in places it should not can point to compromise rather than routine maintenance.
Spot the signals that a package has gone bad
New maintainers are a warning sign when they appear without context. So are sudden version jumps that do not match the package’s normal release pattern. Fresh install scripts deserve particular suspicion because they can run before any human has had a chance to inspect the payload.
Unexpected transitive dependencies are another common mess. A small package can quietly add a pile of extra code after an update, and that extra code may be where the compromise sits. Watch for registry activity that does not fit the package’s normal behaviour, especially if the package starts reaching out during install or update.
Treat new maintainers, sudden version jumps, and fresh install scripts as suspects
A package takeover does not need to look dramatic. A dormant project can be revived, a maintainer account can be stolen, or a trusted package can get a malicious update that still passes casual review. Install scripts make that worse because they move execution into the update path.
Treat the change itself as the signal. A package that changes hands, changes release cadence, or suddenly adds script logic needs manual review before it reaches production or the build cache.
Look for unexpected transitive dependencies and unfamiliar registry activity
Transitive dependencies are where a lot of supply chain trouble hides. A single update can introduce extra packages that were never part of the original risk assessment. If the tree grows fast, review it.
Registry activity also gives away bad behaviour. If a package begins fetching payloads, talking to unknown domains, or pulling content that has nothing to do with its stated function, stop and inspect it before the update is allowed anywhere near a pipeline.
Inspect the blast radius before you update anything else
The package is only one part of the problem. CI/CD jobs may already have fetched it, developer machines may have executed it, and package install history may show how far it spread. A dependency inventory or SBOM gives a harder boundary than memory and guesswork.
Recent package installs matter because compromise often lands through automation, not deliberate action. If a build system fetches packages without a human in the loop, that path needs checking first. CI/CD logs, network traces, and token use give a better sense of how far the issue moved.
Check CI/CD jobs, developer tokens, and recent package installs
Look at what the pipeline fetched, when it fetched it, and which credentials were used. If a package was pulled during automated builds, inspect the job history and any downstream artefacts that were produced after the update.
Developer tokens are another weak point. Stolen or exposed tokens can turn a single compromise into more package uploads, more registry access, and more spread. Recent installs on developer machines matter too, especially if those machines are allowed to reach internal systems or hold privileged credentials.
Build a dependency inventory from your SBOM and pin the risky bits
An SBOM gives a practical list of what is actually present, including transitive dependencies that rarely get checked by hand. Use it to map the affected package tree, then pin the risky versions so they stop moving while you work through the damage.
Pinning is blunt, but blunt is fine here. Automatic movement is how bad packages keep spreading while everyone is still deciding what the real problem is.
Freeze the damage and verify the fix
Pause automatic updates while the affected tree is under review. If a package has already exposed credentials, rotate them. Registry accounts should use MFA, and if they already do, confirm it is actually enforced rather than merely available.
Once the cleanup is in place, review the package tree again. A second compromise can follow the first if stolen tokens, cached artefacts, or unreviewed update rules are still sitting around.
Pause automatic updates, rotate exposed credentials, and force MFA on registry accounts
Automatic updates are useful until they are not. If compromise is suspected, stop them and move to manual review for the affected packages. Rotate any credentials that may have been exposed through the build system, developer workstation, or registry access.
MFA on package registry accounts should be mandatory, not optional. Registry providers do not all enforce it in the same way, so account settings need checking rather than assuming.
Re-review the package tree after the clean-up and watch for repeat compromise
After the obvious fixes, check the tree again from the top. New maintainers, extra dependencies, and fresh scripts can appear in a later update even if the first issue was removed. Watch for repeat compromise through the same package, the same account, or the same automation path.



