vulkro slopcheck
Slopsquatting and hallucinated-package check for an AI-generated
dependency list. Paste or pipe the dependencies an AI assistant suggested
and find the names that are known-malicious, documented AI hallucinations,
typosquats of a popular package, or popular-name-plus-suffix decoys BEFORE
you npm install or pip install them.
Offline-first: every category is computed from data baked into the binary
(or the local bundle) with no network call. The one exception is
--online (below).
Input sources
Pick exactly one:
--manifest <path>reads a dependency manifest directory or file (package.json,requirements.txt,go.mod,Cargo.toml,pom.xml, and more). The ecosystem is taken from each parsed entry.--list <path>reads a plain newline-delimited file of bare package names. Use-for the path to read from stdin (handy for pasting an AI-generated list). The--ecosystemflag then says which registry the names belong to.
With neither flag and a non-tty stdin, the list is read from stdin.
Usage
# Check a manifest.
vulkro slopcheck --manifest ./package.json
# Paste an AI-suggested npm list on stdin.
pbpaste | vulkro slopcheck --list - --ecosystem npm
# CI-friendly JSON.
vulkro slopcheck --manifest . --format json
Flags
| Flag | Description |
|---|---|
--manifest <PATH> | Dependency manifest directory or file. Mutually exclusive with --list. |
--list <PATH> | Newline-delimited file of bare package names. Use - for stdin. Mutually exclusive with --manifest. |
--ecosystem <ECO> | Ecosystem for names read via --list / stdin: npm (default) or pypi. Ignored for --manifest (each entry carries its own). |
--format, -f <FORMAT> | table (default), json, and the other standard finding formats. |
--online | Also probe the registry to confirm each name exists. A name the registry never published is a strong hallucination signal. Makes outbound HTTPS calls; refuses when VULKRO_OFFLINE=1 is set. |
Detection categories
| Category | Severity | Meaning |
|---|---|---|
| known-malicious | High | On the curated compromised-release list. |
| hallucinated | High | On the curated AI-hallucination list. |
typosquat-of:<n> | Medium | Edit distance 1-2 (or a separator / scope confusion) from popular <n>. |
| suspicious-suffix | Low | A <popular>-js / -cli / -py decoy. |
Exit codes
0no suspicious packages found.1one or more suspicious packages reported (findings).2error: bad args, unreadable input, or--onlinewithVULKRO_OFFLINE=1.
Related
- Dependencies and CVEs - the SCA pipeline.
vulkro respond- "is THIS package in my project?".- Vulkro Labs - the free keyless slopsquatting tools.
Command reference
Generated from vulkro help slopcheck on vulkro 0.26.0. This block is the
authoritative flag, usage, and exit-code reference for this command; the
prose above is the friendly explanation. Do not edit this block by hand;
run npm run docs:cli after a release.
Check a dependency list for packages that do not exist or look made up by an AI.
Slopsquatting / hallucinated-package check for an AI-generated dependency list. OFFLINE-FIRST: every category below is computed from data baked into the binary (or the local bundle) with no network call.
Paste or pipe the dependency list an AI assistant suggested and find the names that are known-malicious, documented AI hallucinations, typosquats of a popular package, or popular-name-plus-suffix decoys BEFORE you `npm install` / `pip install` them.
Two equivalent input sources (pick exactly one): * `--manifest <path>` - a dependency manifest directory or file (`package.json`, `requirements.txt`, `go.mod`, `Cargo.toml`, `pom.xml`, ...). The ecosystem is taken from each parsed entry. * `--list <path>` - a plain newline-delimited file of bare package names. Use `-` for the path to read the list from stdin (handy for pasting an AI-generated list). The `--ecosystem` flag then says which registry the names belong to (default `npm`). With neither flag and a non-tty stdin, the list is read from stdin.
Detection categories and severity: * known-malicious (High) - on the curated compromised-release list * hallucinated (High) - on the curated AI-hallucination list * typosquat-of:<n> (Medium) - edit distance 1-2 (or a separator / scope confusion) from popular `<n>` * suspicious-suffix (Low) - `<popular>-js` / `-cli` / `-py` decoy
Output: a table by default, or `--format json` for CI.
`--online` adds a registry existence probe: a name the registry has never published is a strong hallucination signal. This is the ONLY path that touches the network and it refuses to run when `VULKRO_OFFLINE=1` is set (exit 2 with guidance).
Exit codes: `0` no suspicious packages found. `1` one or more suspicious packages reported (findings). `2` error: bad args, unreadable input, or `--online` with `VULKRO_OFFLINE=1`.
Usage: vulkro slopcheck [OPTIONS]
Options:
--manifest <PATH>
Dependency manifest directory or file to read package names from (`package.json`, `requirements.txt`, `go.mod`, `Cargo.toml`, `pom.xml`, ...). Mutually exclusive with `--list`
--offline
Hard-disable every outbound network call for this run (sets VULKRO_OFFLINE=1). Blocks the CVE feed, the license heartbeat, the update check, webhooks, and any cloud AI endpoint; a loopback model (http://127.0.0.1, http://localhost) is still allowed. Equivalent to exporting VULKRO_OFFLINE=1, and the flag wins when both are set
--list <PATH>
Plain newline-delimited file of bare package names. Use `-` to read from stdin. Mutually exclusive with `--manifest`
--ecosystem <ECO>
Ecosystem for names read via `--list` / stdin. One of: `npm`, `pypi`. Ignored for `--manifest` (each entry carries its own)
[default: npm]
-f, --format <FORMAT>
Output format: `table` (default) or `json`
Possible values:
- table
- json
- sarif
- gh-pr
- gh-pr-inline-comments: GitHub PR per-finding **inline review comments**. NDJSON, one `{path, line, side, severity, rule_id, fingerprint, body}` object per line. Designed to be piped straight to a `gh api` loop so `vulkro gate` can drop comments next to the offending line on the Files Changed tab without going through a GitHub App. See the GitHub CLI integration guide at vulkro.com/docs
- github-annotations: GitHub Actions / GitLab CI **PR annotations**. One workflow-command line per finding (`::error file=...,line=...,endLine=...,title=<rule id>::<message> (<helpUri>)`). Printed straight to a CI job's stdout, GitHub turns each line into an inline annotation pinned to `file:line` on the Files Changed tab; GitLab CI's annotation parser reads the same grammar. When run against a baseline (`--gate-vs` / a `gate` flow) only NEW findings are annotated so a first run does not paper the PR
- gitlab-mr: GitLab Merge-Request comment: GitLab-flavored Markdown with collapsible blocks
- bitbucket-pr: Bitbucket Pull-Request comment: flat Markdown (Bitbucket does not render `<details>`)
- azure-pr: Azure DevOps Pull-Request comment: flat Markdown (shared with Bitbucket)
- junit
- csv
- cyclonedx: CycloneDX 1.6 JSON SBOM (uses `ScanResult.packages`)
- cyclonedx-1.7: CycloneDX 1.7 JSON SBOM. Same component shape as `cyclonedx`; emits the newer `specVersion`. Offered alongside 1.6 (which stays default)
- spdx: SPDX 2.3 JSON SBOM
- spdx3: SPDX 3.0.1 JSON-LD SBOM (`@context` + `@graph` of typed elements). Offered alongside SPDX 2.3, which stays the default for `--format spdx`
- cbom: CycloneDX 1.6 CBOM (Cryptographic Bill of Materials): one `cryptographic-asset` component per detected weak algorithm (MD5, SHA-1, ECB, RC4, DES, static IV, insecure RNG), with file:line occurrences inlined under `evidence.occurrences`. Compliance buyers (FedRAMP, post-quantum readiness reviews) ask for this as a distinct artefact from the library SBOM
- openvex: OpenVEX 0.2.0 exploitability statements for each dependency CVE (`affected` / `not_affected` / `under_investigation`), with `not_affected` backed by reachability analysis. Pairs with an SBOM
- cyclonedx-vex: CycloneDX 1.6 VEX: the same exploitability verdicts as `openvex`, in a CycloneDX `vulnerabilities[].analysis` document
- cbom-1.7: CycloneDX 1.7 CBOM. Same crypto-asset grouping as `cbom` plus a richer post-quantum descriptor. Offered alongside 1.6 (default)
- pdf: PDF render of the executive HTML report (requires `wkhtmltopdf` on PATH)
- ropa-md: GDPR Article 30 Records-of-Processing template - Markdown
- ropa-html: GDPR Article 30 Records-of-Processing template - HTML
- ndjson: Newline-delimited JSON: one finding per line plus a trailing summary line. Designed for SIEM ingestion and `jq` filter pipelines
- evidence-graph: Evidence-graph JSON (`evidence-graph/1.0`): a stable, versioned, AI-consumable document that composes endpoints, taint source -> sink flows, reachability verdicts, findings, and the dependency SBOM into one graph. Meant to be handed to an external AI agent as deterministic ground truth (Vulkro embeds no model; the agent brings its own). Pairs with `vulkro aggregate` for cross-repo linking. See `docs/ai-tool/`
[default: table]
--online
Also probe the registry to confirm each name exists. A name the registry never published is a strong hallucination signal. Makes outbound HTTPS calls; refuses when `VULKRO_OFFLINE=1` is set
--ai
[Advisory] Attach a local-model plain-language explanation to each flagged name: WHY the name is risky (slopsquat / typosquat / hallucinated dependency) and what to verify before installing. ADDITIVE and OPT-IN: the deterministic classification is unchanged and remains the source of truth; the AI text is a labelled advisory overlay (advisory / non-deterministic / excluded-from-benchmark) and never changes what was flagged or the exit code. Uses the AI layer resolved from flags / env / `vulkro ai use` (defaults to a local loopback model, allowed even under `VULKRO_OFFLINE`; a cloud endpoint is refused offline). If the model is unreachable the overlay is skipped with a stderr note
-h, --help
Print help (see a summary with '-h')