What PkgFire checks
The signals PkgFire reads for every package - advisories, malicious code, what a release gained, integrity, publishers, age and names - in plain words.
Every package in a scan is checked, not only the ones that changed. Each answer comes from the files that would actually land on your disk, downloaded and verified against the hash your lockfile records, rather than from a package's description of itself. The policy then decides what each answer does to the verdict.
Is this version known to be bad?
- Vulnerability and malware advisories published for npm, Python, Go and Rust packages. A malware advisory blocks by default; a vulnerability counts by its severity.
- Exploitation. A vulnerability that is known to be exploited in the wild is treated more seriously, and one whose estimated chance of exploitation climbs sharply is called out, even when your dependencies did not change.
- Reachability, for Go. Whether your code actually calls the vulnerable function. The analysis runs on your machine; only its result is sent.
Does the code look malicious?
- Malicious patterns in the package's code: data being sent away, obfuscation, downloaders, credential theft.
- Attack-shaped code: rules written for real attacks, such as wallet drainers that replace a page's network functions, worms that publish themselves to the registry, and code that writes CI workflows.
- Secrets shipped by mistake: credentials and tokens left inside the published package.
A code pattern on a version that has been public for a while is shown but not counted by default, because legitimate code reads environment variables and opens network connections too. These checks exist to catch a freshly compromised release.
What did this release gain?
The question that catches a hijack. Each release is compared with the release before it, file by file, for what its code can do: reach the network, run programs, evaluate code built at run time, read credential files or tokens, carry long encoded blobs or native binaries, and run code at install time. A long-established package that suddenly gains install code or starts reading credentials is what a stolen maintainer account looks like from the outside. A pattern its predecessor already had is listed, not counted.
For Go modules, PkgFire also records what each module can do by its call graph: network, files, running programs, unsafe code.
Is it the file the registry published?
- Integrity. The downloaded artifact must match the integrity hash in your lockfile, and for Go the checksum database.
- Registry signatures and provenance. An npm release whose registry signature does not verify, or whose build provenance names a different source than expected, blocks by default. A release published without the provenance its predecessors had warns.
- Republished versions. The same version number with different contents than when it was first seen warns.
Who published it?
- A new publisher: a release from an account that never published this package before. For Python, a release uploaded from a different repository than the release before it.
- A suspect release: PkgFire reviews new releases of the npm and Python packages in use as they are published, comparing each with the one before it. An install script appearing, a days-old dependency being added, or provenance and publisher changing together is the shape of a hijacked release, and blocks by default until it has been checked. If a release you already use turns out to be bad, you are told.
How old is it?
- Release age. A version published less than seven days ago is blocked by default. Most malicious releases are pulled within hours, so a version this new has not had time to be caught. A release that PkgFire reviewed and found unchanged in every way that matters is let through after two days.
- Package age. A package whose first ever release was less than 30 days ago warns.
Is it the package you meant?
Lookalike names. A name one or two keystrokes from a far more popular package, while being barely used itself, warns. Swapping two letters counts as a single slip. Short names, scoped against unscoped names, and packages with a following of their own are left alone.
Upkeep and licences
- Deprecated versions warn: the registry marks them, usually with the publisher's reason.
- Licences are judged against your licence lists, and a package with no licence can be made to warn.
- Downgrades warn: a dependency moving to an older version is worth a look.
What PkgFire says when it could not check
A check that did not run has cleared nothing, and PkgFire never reports it as clean.
- A scanner that failed is recorded, and warns by default. In CI it can be set to block.
- A package a scan did not reach in time is reported as not yet analysed, never as clean, and the verdict is at least WARN. The rest is analysed in the background at no charge, and a registered project is re-checked from the result; its members are emailed if the full picture is worse.
pkgfire scan --waitwaits for that re-check. - A dependency with nothing to download, such as a
git+orfile:dependency, is reported as unverifiable. - A lockfile entry that cannot be read stops the check rather than being dropped.
Watching after you install
The commonest way a project becomes vulnerable is that the dependency stays the same and the advisory changes. With Automatically re-check dependencies turned on (Settings → Policy, off by default), registered projects are re-checked every day against current advisory data. You are emailed only when something changes for the worse: a worse verdict, a genuinely new advisory, or a sharp rise in the chance of exploitation. Alerts can also go to Slack or to a webhook of your own. A scheduled re-check is charged like a scan; see Pricing.
Limits
Stated plainly, because a security tool that overstates itself is worse than one that does less.
- PkgFire is a wrapper: an install run without it is not checked. CI is where it cannot be skipped.
- Static analysis finds code that looks malicious. A careful payload, fetched at run time or hidden in a compiled binary, can pass it. The cooldown and the release comparison exist for that reason.
- Reachability is analysed for Go only. Elsewhere a vulnerability counts whether or not your code reaches it.
- Coverage is narrower for Python and Rust than for npm: no publisher history for Rust, and fewer registry signals for both.