Static-only by design
The core decision behind PkgRadar is that a scanner should never run the thing it is judging. We fetch each release, hash it, unpack the archive, and inspect the bytes. We do not run npm install, pip install, gem install, cargo build, composer install, or any other package code, and we do not stand up a sandbox runtime to watch it execute. Malware in the package never gets a chance to run on our infrastructure.
This is a deliberate trade-off, and it buys three things:
- Safety. A package engineered to detonate on install — the most common shape of registry malware — is inert under static analysis. There is no sandbox to escape and no install hook to fire.
- Speed. Unpack-and-inspect is dramatically cheaper than spinning up an isolated runtime per release, so we can analyze a release the moment it is published rather than hours later.
- Scale. The same engine runs across nine registries — npm, PyPI, RubyGems, Cargo, Maven, NuGet, Composer, Go, and Pub — letting us keep up with the full firehose of new releases instead of sampling a few.
We are honest about the limit: static analysis cannot observe purely dynamic runtime behavior — code that only reveals intent once it executes and reaches out to a live server. That is why PkgRadar is precision-first. We do not chase every theoretical signal; we score concrete static indicators and corroborate them with cross-release campaign correlation and, where available, confirmation against the OSV malicious packages feed. The goal is a verdict an engineer can trust enough to block a build on.
The analysis pipeline
Every release moves through the same path, from registry to verdict:
- Registry feed.A per-ecosystem hunter follows each registry’s publish stream and queues new releases.
- Static unpack. The artifact is downloaded, hashed, and extracted under strict size limits — no install, no build.
- Manifest & code analysis + version diff. We parse the manifest, walk the source, and diff against the prior version to catch newly added lifecycle scripts and newly added remote dependencies — the hallmark of a compromised update to an otherwise-trusted package.
- TTP extraction. Detectors emit typed findings (the taxonomy below), each tied to a tactic or technique.
- Scoring. Each finding contributes points, capped per kind so a single noisy detector cannot dominate a verdict.
- Risk verdict. The score resolves to
high,review, orlow. - CI gate decision. The gate blocks or passes a release against a configurable
fail_onthreshold.
Running alongside the per-release pipeline, cross-release campaign correlation clusters packages that share payload URLs, file hashes, or publisher bursts. A single suspicious package is a signal; a dozen packages phoning the same host within an hour is a campaign — and the correlation raises confidence on every member of the cluster.
Detector & TTP taxonomy
These are PkgRadar’s finding kinds, grouped by intent. Each is mapped to a MITRE ATT&CK technique and to a category from the OpenSSF Malicious Packages project — the same install-time-vs-runtime, exfiltration, dropper, and obfuscation buckets popularized by the “Backstabber’s Knife Collection” survey of real registry malware. Where a technique has no clean framework mapping, we say so rather than force one.
Credential & secret access
Reads of credential stores, dotfiles, and process environment — the staging step before exfiltration.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
credential_paths | Credential file access | T1552 — Unsecured Credentials | Data exfiltration (collection) |
env_access | Environment variable read | T1552.001 / T1083 — Credentials in files / File & directory discovery | Data exfiltration (collection) |
Exfiltration & outbound network
Code that moves data off the host, including covert channels that evade naive HTTP monitoring.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
dns_or_oast_exfil | DNS / OAST exfiltration | T1048 — Exfiltration Over Alternative Protocol | Data exfiltration |
network_post | Outbound network POST | T1041 / T1071 — Exfiltration Over C2 Channel / Application Layer Protocol | Data exfiltration |
suspicious_url | Suspicious URL reference | T1071 — Application Layer Protocol | Data exfiltration / dropper |
Install-time & lifecycle triggers
Code wired to run automatically on install. In the OpenSSF framework these are the install-time trigger that makes a supply-chain package weaponizable without the victim ever importing it.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
install_lifecycle_script | Install-time lifecycle script | T1195.002 / T1059 — Compromise Software Supply Chain / Command & Scripting Interpreter | Install-time trigger |
diff_added_lifecycle_script | Lifecycle script added vs prior version | T1195.002 — Compromise Software Supply Chain (version-diff signal) | Install-time trigger |
Payload retrieval & dependency injection
Second-stage delivery: fetching remote code at install or runtime, or pinning a dependency to an attacker-controlled tarball.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
remote_payload_fetch | Remote payload fetch | T1105 — Ingress Tool Transfer | Dropper / second-stage download |
manifest_remote_dependency | Manifest dependency on remote tarball | T1195.001 — Compromise Software Dependencies & Development Tools | Dropper / dependency manipulation |
diff_added_remote_dependency | Remote dependency added vs prior version | T1195.001 — Compromise Software Dependencies & Development Tools (version-diff signal) | Dropper / dependency manipulation |
Obfuscation & evasion
Techniques used to hide intent from human reviewers and naive scanners.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
obfuscated_code | Obfuscated code | T1027 — Obfuscated Files or Information | Obfuscation |
encoded_payload | Encoded payload | T1027 — Obfuscated Files or Information | Obfuscation |
base64_decode | Base64 decode | T1027 — Obfuscated Files or Information | Obfuscation |
eval_call | Dynamic eval / Function() construction | T1059 / T1027 — Command & Scripting Interpreter / Obfuscation | Obfuscation / runtime trigger |
Execution & host effects
Direct command execution, process creation, and filesystem manipulation on the host.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
shell_exec | Shell execution | T1059 — Command & Scripting Interpreter | Runtime trigger / execution |
process_spawn | Process spawn | T1059 — Command & Scripting Interpreter | Runtime trigger / execution |
filesystem_write | Filesystem write | T1105 / T1564 — Ingress Tool Transfer / Hide Artifacts | Dropper / persistence |
Identity, naming & publisher signals
Account-level and naming signals that surround compromised or impersonating releases.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
typosquat_distance | Typosquat distance | T1195.002 / T1036 — Compromise Software Supply Chain / Masquerading | Typosquatting / masquerading |
publisher_change | Publisher change | T1195.002 — Compromise Software Supply Chain (account compromise) | Account compromise |
publisher_high_risk | Publisher / release-actor burst | T1195.002 — Compromise Software Supply Chain (coordinated bursts) | Account compromise / coordinated campaign |
Emerging: AI-targeted supply chain
A new class of payload that targets the AI coding agent reading the package, not the machine running it.
| Finding kind | What it detects | MITRE ATT&CK | OpenSSF category |
|---|---|---|---|
llm_injection_payload | Prompt-injection-in-package | No clean ATT&CK technique yet — emerging LLM-targeted supply-chain TTP | Emerging (not yet categorized) |
Scoring & verdicts
Findings do not block on their own — they accumulate into a score, and the score maps to one of three verdicts:
- High risk. Stacked, high-severity indicators — for example an install-time lifecycle script that fetches a remote payload and reads credential files. This is the shape of an actual attack, and it is what the gate is built to block.
- Review. A single weaker signal, or a combination that is suspicious but not conclusive. We surface it for a human rather than asserting compromise.
- Low.No meaningful static indicators, or only signals that are normal for the package’s class.
The scoring is precision-first on purpose: a lone weak indicator lands in review, not block, while corroborated high-severity indicators escalate to block. In CI, the gate enforces a configurable fail_on threshold, so a team can choose to fail builds only on high, or also on review for a stricter posture.
See it in practice
For the real-world record — named campaigns and the specific attacks PkgRadar caught, often before public disclosure — see the attacks we have caught. For our measured precision and recall — and how we handle false positives — see the accuracy page; for detection coverage and lead time against the OSV malicious-packages feed, see the coverage page and the lead-time benchmark.