← All guides

Dependency health: malicious and deprecated packages

Cross-cutting
On this page

In plain terms

A vulnerability scanner reports flaws in the packages you use. It says nothing about the packages themselves, and two facts about a package change how urgent its flaws are:

  • Malicious. The package was published to do harm: it steals credentials, installs a backdoor, or impersonates a popular package under a similar name. Everything it contains is the problem, not one function.
  • Deprecated. The publisher has marked this version as no longer supported, often with a reason and a replacement. A flaw found in it next month may never be fixed.

Neither is in your code, which is why no scanner reading your code can report either.

Why it matters

A CVE in a maintained package and the same CVE in one its publisher has walked away from look identical in a scan.

Maintained

A fix ships in a later version. Upgrade, and the finding closes.

Deprecated

No fix is coming, and the next flaw found in it will not get one either. Replace it, often with the package its publisher names as the successor.

A malicious package is a different kind of problem again. It does not need a vulnerability to hurt you, because running its install script or importing it is the attack.

How it works

Both statements come from named parties, and both reach Draugr through deps.dev, Google's index of open source packages.

MaliciousDeprecated
Who says sothe OSSF Malicious Packages Project, an OpenSSF projectthe package's own publisher
Howresearchers and automated detectors contribute reports, published in the OSV vulnerability formatthe publisher marks a version deprecated in its registry, for example npm deprecate, or a Deprecated: comment on a Go module
Coversevery version of the packagethe version marked
When it is wronga confirmed false positive is withdrawn from the dataset and kept on record, not deletedthe publisher can lift the mark

deps.dev indexes Cargo, Go, Maven, npm, NuGet, PyPI and RubyGems. Operating-system packages inside a container image are not among them.

Why health scores are not in the list

Scorecards that grade a project on activity, review practice and release cadence are useful for choosing a dependency. They are a poor basis for ranking one of its flaws. Research on OpenSSF Scorecard found reported vulnerability counts rose with the aggregate score, explaining 9% to 12% of the variation, and the Maintained check scores PyYAML zero because it reads a 90-day activity window and PyYAML is stable rather than abandoned.

A statement somebody can be named for, this package is hostile or this version is no longer supported, is evidence. A score is a heuristic about the project around it.

Common pitfalls

The pitfallWhy it bites
Unflagged is not safethe dataset lists packages somebody reported. A new malicious package is unlisted until somebody does
Deprecated is not vulnerableit says who maintains the package, not whether a flaw in it can run in your code
Replacing is not upgradinga deprecated package often names a different package as its successor, so the fix is a code change rather than a version bump
How Draugr fits. Turn it on with config.dependencyHealth. A finding in a malicious package is ranked critical; a finding in a deprecated version rises one band, and the publisher's reason travels into the report. Absence moves nothing: a package nobody has flagged is ranked as it would be with the signal off. Draugr sends deps.dev the names and versions of the packages a scan found and nothing else. See dependency health in the Saga reference.

Keep learning