Report methodology

How LPM Firewall reports are produced.

Each public report records the Firewall decision for one npm package version and the evidence behind it. This page explains where that evidence comes from, what each part of a report means, and how to dispute one.

Last reviewed October 23, 2026Applies to every report under /npm
// 01

Where the evidence comes from

Three sources feed a report. Most blocks come from more than one of them.

The full pipeline is described in How LPM Firewall works.

Trusted advisories

OSV and OpenSSF malicious-package advisories, and GitHub malware advisories, identify known-malicious package versions. An exact match becomes a block, and the report links back to the advisory.

Static scan

LPM downloads each new version from the npm registry stream, checks the registry integrity hash, and inspects the tarball without installing or running it. More than 120 checks cover install hooks, entrypoints, source behavior, shipped artifacts and changes from the previous release. The scan is triage: clear evidence can finalize a verdict, and ambiguous or similarity-only results go to review.

Source-aware AI review

Versions the scan routes for review are read at source level by an AI model. The review records how the behavior is triggered, what it does, the files and network endpoints involved, the evidence for and against a block, and a confidence score.

// 02

What a report shows

Reports follow the same layout, so the same question is answered in the same place.

Decision banner

The Firewall decision for the version (blocked, warned or allowed) and the one-line reason.

Security review

The summary, trigger, impact, mechanism and attack narrative from LPM's review, or the advisory text when the report is built on an advisory.

Decision evidence

The evidence for and against a block, and the behaviors the scanner observed in the source, supply chain and manifest.

Source and flagged code

The flagged lines from the published tarball, with line numbers and a link to the file on unpkg.

Findings

Each static finding with its severity and the file it was found in.

Side panel

Confidence, intent, threat type, false-positive risk, the Firewall policy that applied, and package metadata such as maintainers, license and lifecycle scripts.

Package and version pages

/npm/<package> shows the newest version LPM reviewed and lists the recorded versions with their verdicts. /npm/<package>/v/<version> shows a single version.

// 03

LPM's review and advisory-only reports

LPM's own analysis is what a report adds beyond the advisory.

Advisory-only reports

Some reports only restate an OSV or OpenSSF advisory. They stay public because installs and agents rely on them, but LPM has added no analysis of its own.

Reports with LPM's review

Reports with LPM's own review show it as a separate section with the trigger, mechanism and flagged code. Only these reports appear in the threat type lists.

Disagreements

When LPM's review disagrees with an advisory, the advisory decision stands until a disagreement review resolves it, and the report shows both assessments.

// 04

Not every block is a malware claim

Block, warn and allow are install decisions. They are not all claims of malicious intent.

The rules for each decision are in the Firewall policy.

Policy findings

Some blocks are security-policy findings, such as silent writes to AI-agent control files or changes to dependency script approvals. They cross a security boundary without establishing malicious intent, and each report labels which kind of finding it is.

// 05

Dates on a report

A report carries several dates, and each means something different.

Scanned or imported

When LPM scanned the version, or imported the advisory.

Evidence last updated

When the review or the advisory last changed.

Source advisory published

When the advisory was first published, if the report has one.

Published

When the version was published to npm. This is the package's date, not the report's.

// 06

Limits

Read a report as evidence for one version, not as a guarantee.

Reports cover npm package versions with a public malware or security-policy finding. They are not a list of every npm package, and a missing report does not mean a package is safe.

Evidence describes the version as it was scanned. Other versions are scanned separately and keep their own verdicts.

Automated review can be wrong. Confidence, false-positive risk and any disagreement with an advisory are shown on the report.

Package metadata, file names, URLs and code in a report come from the package itself. Treat them as untrusted, and do not run code copied from a report.

// 07

Dispute a verdict or correct a report

Maintainers and users can dispute a verdict or correct a report in public.

Open an issue →lpm-dev/firewall-reportsossf/malicious-packages

On GitHub

Open an issue in the public lpm-dev/firewall-reports repository on GitHub. Every report has a link that fills in the package and the report for you. Disputes are reviewed against the current evidence, and if the decision changes, the report and the Firewall decision are updated.

Advisory-based blocks

A block based only on an OpenSSF or OSV advisory follows that advisory. Please also report it to ossf/malicious-packages.

// 08

Machine-readable reports

Reports are written for people and agents.

Markdown

Every report is also available as Markdown at /npm/<package>/report.md and /npm/<package>/v/<version>.md. Agents should start from /llms.txt.