npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sec-npm

v1.1.1

Published

Zero-Trust npm wrapper: audits packages (metadata, AST, import-time shadow execution) for supply-chain malware before install

Readme

🛡️ sec-npm


sec-npm is a zero-trust wrapper around npm install. Before anything touches your node_modules, it audits the package across static analysis, import-time shadow execution, and registry metadata to catch malware — including zero-days that npm audit cannot see.

[!TIP] Generic, not single-campaign. The engine applies the same heuristics to every package — obfuscation, exfil/network behavior, registry anomalies, OSV history. The joyfill/DEV#POPPER RAT was the first case it was hardened against, but the tool is not scoped to it: known-campaign markers live in an extensible threat feed (lib/signatures.js) that grows with each new disclosure, and the heuristic layers detect novel implants on their own.

[!IMPORTANT] Why sec-npm? Tools like npm audit only match known vulnerabilities. sec-npm hunts zero-day implants: it de-obfuscates code, runs entry files in a sandboxed node:vm where host modules are traced stubs, checks for registry anomalies (version floods, prerelease-as-latest), queries the OSV known-malicious database, and blocks before install.


✨ Features

🎭 Import-Time Shadow Sandbox

Package entry files (from main/module/exports/bin) are executed inside a node:vm context built on traced Proxies:

  • fs, child_process, http(s), net, dns, tls, process are stubbed/blocked and logged — a network call or file write triggers an instant block.
  • global.r = require-style primitive stashing is detected.
  • Honeytrap decoys (fake SSH keys, .env) catch credential exfil attempts.
  • Buffer.from(..., 'base64/hex') decodes are logged and fed back into signature detection.
  • ESM entry bundles are transparently transformed (lib/esmTransform.js) and run through the same sandbox.

[!NOTE] Execution happens in-process inside node:vm with every host builtin replaced by a guarded stub. This is a containment boundary, not a full OS sandbox (no Docker). Untrusted code that runs as the same OS user still warrants a throwaway environment for truly hostile specimens.

🔍 Deep AST Static Analysis

acorn parses every .js/.cjs/.mjs file (symlinks and node_modules skipped) and flags:

  • Known C2/IOC matches (domains, IPs) and blockchain C2 endpoints (Tron/Aptos/BSC RPCs — e.g. the @joyfill RAT campaign).
  • Detached child processes (child_process.spawn/exec/fork — including member-expression forms), runtime npm install, dynamic eval/Function chains.
  • constructor property access, string-decoder/truncation payload tricks, high-entropy strings and identifiers.
  • Sensitive module imports and process.env scraping.

🪤 Active Defense (Honey-Traps)

The sandbox ships with decoy credentials. Any attempt to read them triggers a critical alert.

🕒 Registry Anomaly Detection (Time-Travel)

Metadata history is scanned for:

  • Version floods (≥ 50 same-base versions published within a 72h window — e.g. the 2,773-version @joyfill flood; time-aware so legit slow-cadence prereleases are not flagged).
  • Campaign version markers — versions matching a known malicious batch pattern (e.g. joyfill's -2773-beta.*) are instant-blocked even after the registry scrubs the code. Extensible in lib/signatures.js.
  • Prerelease-as-latest and tarball size anomalies.
  • Sudden postinstall/preinstall script additions.

☁️ OSV Known-Malicious Lookup

Queries api.osv.dev (free, no API key) so known-malicious packages are rejected even before static analysis. Disable with --no-osv. Override the endpoint with SEC_NPM_OSV_URL.

🔒 Safe Installation

  • sec-npm i installs via npm install as a child process; on win32 the npm.cmd shim needs a shell, so the install target is character-whitelisted ([a-zA-Z0-9@/._~-]) before it ever reaches the command line — the registry-controlled name/version cannot inject shell syntax.
  • Installs the exact version that was audited (pkg@auditedVersion) — no TOCTOU window where the registry serves a different, newer tarball.
  • --force is the only escape hatch; without it, a danger-level audit aborts the install.

🧠 Extensible Threat Feed

Known-campaign signatures live in lib/signatures.js: C2 IOCs, blockchain endpoints, persistence targets, and campaign version markers. When the next disclosure lands, append its markers to that one file — the analyzer, sandbox, and scanner all read from it. The heuristic layers above keep detecting novel implants without any signature.


🛠️ Usage

1. Secure Installation

sec-npm i <package-spec>
sec-npm install <name>@<version>   # audits exactly this version, then installs it

Flags: -d/--detailed, -t/--threshold <score> (default 50), -f/--force, --no-osv.

2. Deep Security Audit

sec-npm check <package-spec> -d

Flags: -d/--detailed, -t/--threshold <score>, --json, --no-osv.

3. Quick Static Scan

sec-npm scan <package-name>

Flags: --json.

Environment Variables

| Variable | Purpose | | :--- | :--- | | SEC_NPM_REGISTRY | Override registry base URL (default https://registry.npmjs.org) | | SEC_NPM_OSV_URL | Override OSV API base URL (default https://api.osv.dev/v1/querybatch) |


⚖️ Comparison

| Feature | Standard npm | sec-npm | | :--- | :---: | :---: | | Known vulnerabilities (OSV) | ✅ | ✅ | | Zero-day / heuristic detection | ❌ | ✅ | | Import-time shadow execution | ❌ | ✅ | | Typosquatting shield | ❌ | ✅ | | Registry anomaly detection | ❌ | ✅ | | Honey-trap deception | ❌ | ✅ | | Install-time overhead | None | ~1s |


🧪 Tests

npm test          # hermetic suite (fixtures + local mock registry, no external calls)
npm run test:live # optional live test against the malicious @joyfill/layouts specimen