{"id":50499844,"url":"https://github.com/n8tz/fad-checker","last_synced_at":"2026-06-02T11:00:26.993Z","repository":{"id":359536781,"uuid":"1246480484","full_name":"n8tz/fad-checker","owner":"n8tz","description":"Scans ALL Maven, npm, Yarn, Composer, Python, C#/.NET in a source tree ONE SHOT Alone like a big boy, deal with private deps, multi mvn modules, EOL, obsolete, outdated deps \u0026 give fix recos","archived":false,"fork":false,"pushed_at":"2026-05-29T15:26:00.000Z","size":517,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-29T17:06:10.456Z","etag":null,"topics":["code","dependencies","dependency-analysis","dependency-check","maven","security-tools","source","source-code-audit"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/n8tz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-22T08:29:27.000Z","updated_at":"2026-05-29T15:27:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/n8tz/fad-checker","commit_stats":null,"previous_names":["n8tz/fad-checker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/n8tz/fad-checker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n8tz%2Ffad-checker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n8tz%2Ffad-checker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n8tz%2Ffad-checker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n8tz%2Ffad-checker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/n8tz","download_url":"https://codeload.github.com/n8tz/fad-checker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n8tz%2Ffad-checker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33818568,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code","dependencies","dependency-analysis","dependency-check","maven","security-tools","source","source-code-audit"],"created_at":"2026-06-02T11:00:14.742Z","updated_at":"2026-06-02T11:00:26.992Z","avatar_url":"https://github.com/n8tz.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fad-checker\n\n[![npm version](https://img.shields.io/npm/v/fad-checker.svg)](https://www.npmjs.com/package/fad-checker)\n[![npm downloads](https://img.shields.io/npm/dm/fad-checker.svg)](https://www.npmjs.com/package/fad-checker)\n[![license](https://img.shields.io/npm/l/fad-checker.svg)](https://github.com/n8tz/fad-checker/blob/main/package.json)\n[![node](https://img.shields.io/node/v/fad-checker.svg)](https://nodejs.org)\n\n\u003e **F**ucking **A**utonomous **D**ependency **C**hecker\n\n`fad-checker` scans **Maven**, **npm**, **Yarn**, **Composer (PHP)**, **PyPI (Python)**, **NuGet (C#/.NET)**, **Go**, **Ruby** and **vendored JavaScript** in any source tree — multi-module, monorepo, polyglot, whatever you've got — and produces a single self-contained HTML report with CVE (prioritised by **EPSS + CISA KEV**), EOL, obsolete, outdated and **license** findings, plus per-ecosystem fix recipes. It also exports a **CycloneDX 1.6 SBOM** and a **CSAF 2.0 VEX**.\n\n🌐 **[Project site \u0026 docs →](https://n8tz.github.io/fad-checker/)**\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"docs/assets/cli.png\" alt=\"fad-checker terminal output — a [n/N] checklist warming each vulnerability database, then CVE findings coloured by severity\" width=\"760\"\u003e\u003c/p\u003e\n\nIt runs against the source files alone. **No `mvn`, no `npm install`, no `composer install`, no `pip`, no `dotnet restore`, no Docker.** It reads `pom.xml`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `composer.lock`, `poetry.lock`/`Pipfile.lock`/`uv.lock`/`pdm.lock`/`pyproject.toml`/`requirements.txt`, and `packages.lock.json`/`*.csproj`/`*.fsproj`/`*.vbproj`/`packages.config` directly.\n\n\u003e **Supported ecosystems: Maven, npm, Yarn (v1 + Berry/v2+), pnpm, Composer, PyPI, NuGet, Go, Ruby.** Each is a self-contained **codec** (`lib/codecs/`) — adding another is adding a codec, no orchestrator surgery. Vendored JS (jQuery, Bootstrap, PDF.js, etc.) is also scanned via retire.js. **Embedded JARs** committed into the tree — vendored libs, Spring-Boot fat-jars, shaded uber-jars inside `.jar`/`.war`/`.ear` — are unzipped in-memory and their Maven coordinates scanned too (disable with `--no-jars`).\n\n---\n\n## Why \"Autonomous\"?\n\nBecause it doesn't need anything you don't already have on disk:\n\n| You don't need | Why |\n| --- | --- |\n| Maven installed | `pom.xml` files are parsed directly with xml2js. Properties, profiles and local BOMs are resolved in-process. Transitive deps fetched from Maven Central if `--transitive` (cached forever). |\n| `mvn dependency:tree` | Same as above. We walk the tree ourselves. |\n| `npm install` / a `node_modules/` | `package-lock.json` (v1/v2/v3), `yarn.lock` (v1 + Berry/v2+) and `pnpm-lock.yaml` (v5/v6/v9) are parsed as text/JSON/YAML. Versions come from the lockfile — no installation. |\n| `yarn install` / `pnpm install` | Same. We read `yarn.lock` (v1 + Berry) and `pnpm-lock.yaml` directly. |\n| `composer install` | `composer.lock` is parsed directly (concrete versions + transitive). `composer.json` alone → best-effort on pinned versions + warning. |\n| `pip` / `poetry` / a venv | `poetry.lock`, `Pipfile.lock`, `uv.lock`, `pdm.lock` are parsed for concrete versions; `pyproject.toml` (PEP 621 + poetry) and `requirements.txt` (following `-r`/`-c` includes) are best-effort on exact pins. Names normalised per PEP 503. |\n| `dotnet restore` | `packages.lock.json` is parsed; otherwise `*.csproj`/`*.fsproj`/`*.vbproj` (+ `Directory.Packages.props` Central Package Management) and legacy `packages.config`, best-effort on pinned versions. |\n| `go build` / a Go toolchain | `go.mod` is parsed (the full pruned graph on Go ≥1.17, `// indirect` → transitive); `go.sum` is the fallback. No module download. |\n| `bundle install` | `Gemfile.lock` is parsed for the resolved gem set. No Ruby, no bundler. |\n| `snyk` binary | Built-in CVE matching via CVEProject + OSV + NVD (merged), prioritised with EPSS + CISA KEV (see below). Snyk is *optional* (`--snyk`). |\n| A network connection | First run downloads CVE / OSV / EOL data; subsequent runs use cached copies (`--offline` to force). |\n\nExactly **one** runtime dependencies must be on PATH (or installed automatically through npm): Node ≥ 20. Everything else is bundled or fetched lazily.\n\n---\n\n## What it finds\n\n| Chapter | Source | What it catches |\n| --- | --- | --- |\n| **0. Warnings** | local heuristics | Missing lockfiles, unresolved Maven versions (BOM-managed), private libs not on Maven Central |\n| **1. CVE (production)** | CVEProject + OSV.dev + NVD + CPE | Public CVE / GHSA in production deps, per ecosystem, per manifest file — each row **prioritised** by CISA KEV + EPSS + CVSS |\n| **1B. Embedded binaries** | same, on coords read from archives | CVEs in libraries **shipped inside committed `.jar`/`.war`/`.ear`** (vendored libs, Spring-Boot fat-jars, shaded uber-jars) — not declared in any `pom.xml`. Grouped by containing archive |\n| **2. CVE in dev deps** | same | Same, but for `test`/`provided` (Maven) and `dev`/`optional`/`peer` (npm) |\n| **3. Vendored JS** | [retire.js](https://retirejs.github.io/) | Old jQuery/Bootstrap/Angular/PDF.js copies sitting in `static/` or `webapp/` with no lockfile |\n| **4. EOL frameworks** | endoflife.date | Spring Boot 2.5, Hibernate 4.x, EOL JDKs, AngularJS, Laravel/Symfony, Django, .NET, etc. |\n| **5. Obsolete libraries** | curated list (Maven) + registry maintainer flags | log4j 1.x, jackson-mapper-asl, joda-time, …; npm `deprecated`, Composer `abandoned`, PyPI `yanked`/inactive, NuGet `deprecation` |\n| **6. Outdated libraries** | Maven Central + npm / Packagist / PyPI / NuGet registries | Available newer versions, with release dates |\n| **7. Licenses** | registry metadata + Maven POMs → SPDX policy | Each dep's license normalised to SPDX and classified; copyleft (GPL/AGPL/LGPL/MPL), proprietary and unknown flagged for review |\n| **8. Fix Recommendations** | computed | Per-ecosystem pin recipes: Maven `\u003cdependencyManagement\u003e`, npm `overrides`, yarn `resolutions`, `composer require`, `pip install`, `dotnet add package` |\n\nThe HTML report opens in any browser, contains every detail (CVSS vectors, references, full descriptions, CPE configurations, via-paths for transitives) and ships a Word-compatible `.doc` twin. Every match carries a **composite priority** (KEV-exploited \u003e EPSS likelihood \u003e CVSS severity), and the run can additionally emit a **CycloneDX 1.6 SBOM** (`--report-sbom`, vulnerabilities inline) and a **CSAF 2.0 VEX** (`--report-csaf`) for downstream tooling.\n\n---\n\n## Quick start\n\n```bash\nnpm install -g fad-checker\nfad-checker -s ./my-project\n```\n\nThat's it. The report lands in `./fad-checker-report/cve-report.html`.\n\nWant a 10× faster NVD enrichment? [Get a free NVD API key](https://nvd.nist.gov/developers/request-an-api-key) (instant), then:\n\n```bash\nfad-checker --set-nvd-key YOUR_KEY\n```\n\n---\n\n## Common runs\n\n```bash\n# Read-only full scan (default: all sources on)\nfad-checker -s ./proj\n\n# Exclude private/internal libs by groupId regex\nfad-checker -s ./proj -e \"^(com\\.acme|org\\.private)\\.\"\n\n# Also write cleaned POMs (private deps stripped, ready for Snyk)\nfad-checker -s ./proj -t ../proj-clean -e \"^com\\.acme\\.\"\n\n# Then run Snyk on the cleaned tree and merge findings\nfad-checker -s ./proj -t ../proj-clean -e \"^com\\.acme\\.\" --snyk\n\n# Faster: skip Maven Central / no transitive walk\nfad-checker -s ./proj --no-all-libs --no-transitive\n\n# Fully offline (uses cached data only)\nfad-checker -s ./proj --offline\n\n# Pick ecosystems — --ecosystem is a list: auto (default) | all | comma list\nfad-checker -s ./proj --ecosystem maven            # Maven only\nfad-checker -s ./proj --ecosystem maven,npm,pypi   # several\nfad-checker -s ./proj --no-nuget --no-composer     # or opt out per codec\n```\n\nRun `fad-checker --help` for the full flag list.\n\n---\n\n## What a report looks like\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"docs/assets/report.png\" alt=\"fad-checker HTML report — executive summary with severity tiles and a detailed CVE table with CWE, descriptions and fix versions\" width=\"900\"\u003e\u003c/p\u003e\n\nThe console prints a summary; the full detail lives in the self-contained HTML/`.doc`:\n\n```\nExecutive Summary [CRITICAL] — 1708 dependencies scanned\n  • 81 CVE in production deps (critical=5, high=53, medium=12, low=11)\n  • 32 CVE in dev/test deps\n  • 17 vulnerable vendored JS finding(s) (retire.js)\n  • 2 end-of-life frameworks\n  • 13 obsolete / deprecated libs\n  • 172 outdated libs\n  • 4 scan-completeness alerts — see chapter 0\n\n0. Warnings \u0026 scan-completeness (4)\n1. CVE Vulnerabilities — production (81)\n   1.a Maven (49)\n      1.a.0 All (49)\n      By pom.xml (14 files)\n         build/building/pom.xml (17)\n         services/api/pom.xml (17)\n         … 12 more\n   1.b npm (package-lock) (32)\n      1.b.0 All (32)\n      By package-lock.json (1 file)\n         web/package-lock.json (32)\n2. CVE in dev dependencies (32)\n3. Vendored JS scan — retire.js (17)\n4. End-of-Life Frameworks (2)\n5. Obsolete / Deprecated Libraries (13)\n6. Outdated Libraries (172)\n7. Fix Recommendations\n```\n\nEach CVE row shows: severity badge · CVE / GHSA id · dep coord \u0026 version · which manifest file declares it · source(s) (CVEProject / OSV / NVD / Snyk / retire / fad) · fix-version · summary. Click a row for the full panel (CVSS vectors, NVD references categorised by type, transitive paths, CPE configurations).\n\n---\n\n## Install\n\n### As a global CLI\n\n```bash\nnpm install -g fad-checker\n```\n\n### From source\n\n```bash\ngit clone \u003crepo-url\u003e fad-checker\ncd fad-checker\nnpm install\nnode fad-checker.js --help\n```\n\n### Single-binary build (no Node required)\n\n```bash\nnpm install        # one-time, brings in bun\nnpm run build      # → dist/fad-checker-linux + dist/fad-checker.exe\n```\n\n### Shell completion\n\n```bash\nfad-checker --completion bash \u003e /etc/bash_completion.d/fad-checker\n# or for zsh:\nfad-checker --completion zsh  \u003e ~/.zsh/completions/_fad-checker\n```\n\n---\n\n## How it scans without any build tool\n\nThis is the surprising bit. The whole point is that you can run `fad-checker` against a *checkout* with no build environment.\n\n- **Maven** — `pom.xml` files are parsed with xml2js. Property substitution (`${jackson.version}`), parent inheritance, local BOM imports (`\u003cscope\u003eimport\u003c/scope\u003e`) and every profile are resolved in-process. Transitive deps are walked by fetching child POMs from Maven Central (cached forever — POMs are immutable). When the project uses an **external BOM** (`spring-boot-dependencies` etc.), the deps whose version comes from that BOM can't be resolved without `mvn` itself — those are surfaced in chapter 0 as \"unresolved-versions\" so you know what's missing.\n- **npm / Yarn / pnpm** — `package-lock.json` (v1, v2, v3), `yarn.lock` (v1 + Berry/v2+, via `js-yaml`) and `pnpm-lock.yaml` (v5/v6/v9, via `js-yaml`) are parsed directly. Lockfiles already contain every transitive version. No `node_modules/` traversal, no `npm install`.\n- **Composer (PHP)** — `composer.lock` (`packages` + `packages-dev`) gives concrete + transitive versions; `composer.json` alone is best-effort.\n- **PyPI (Python)** — `poetry.lock` / `Pipfile.lock` / `uv.lock` / `pdm.lock` are parsed (TOML via `smol-toml`, or JSON); `pyproject.toml` (PEP 621 `[project]` + `[tool.poetry]`) and `requirements.txt` (following `-r`/`-c` includes recursively, with `-c` constraint pins applied to ranges) are best-effort on exact pins. Package names are PEP 503-normalised (`Flask-SQLAlchemy` → `flask-sqlalchemy`).\n- **NuGet (C#/.NET)** — `packages.lock.json` is authoritative; otherwise `*.csproj` / `*.fsproj` / `*.vbproj` `\u003cPackageReference\u003e` (resolving Central Package Management against `Directory.Packages.props`) and legacy `packages.config`. Ids are case-insensitive.\n- **Go** — `go.mod` `require` entries are the selected versions (full pruned graph on Go ≥1.17; `// indirect` → transitive), `go.sum` as fallback. OSV \"Go\" ecosystem for recall, the Go module proxy for outdated.\n- **Ruby** — `Gemfile.lock` `specs:` give the resolved gem set. OSV \"RubyGems\" for recall, the RubyGems API for outdated + licenses.\n- **Lockfile-first, best-effort fallback** — when a lockfile is present it wins. When it's absent, the loose manifest (`package.json` / `composer.json` / `pyproject.toml` / `requirements.txt` / `*.csproj`) is still parsed for its **pinned exact versions**, with ranges skipped and a `no-lockfile` warning in chapter 0 flagging the partial coverage.\n- **Vendored JavaScript** — `retire.js` shells out and scans `.js` / `.min.js` files by signature, catching old jQuery / Bootstrap / Angular / PDF.js copies that no lockfile knows about.\n- **Embedded JARs** — committed `.jar` / `.war` / `.ear` archives are unzipped **in memory** (via `fflate` — nested fat-jar libs are recursed without ever touching disk, so there's no zip-slip risk) and each artifact's Maven coordinate is read from `META-INF/maven/.../pom.properties` (authoritative), then `MANIFEST.MF`, then the file name. Those coordinates run through the same CVE/OSV/NVD matching as declared deps but report in their own **Embedded binaries** chapter, grouped by containing archive. An archive whose coordinate can't be resolved is flagged in chapter 0 rather than scanned blindly. Auto when archives are present; disable with `--no-jars`. (Embedded coords don't trigger Maven Central transitive resolution — a fat-jar already ships its dependencies, which the recursion finds directly.)\n- **CVE data** — three independent sources merged:\n  - **CVEProject** (the canonical `cvelistV5` bundle, filtered to Maven-relevant entries)\n  - **OSV.dev** (Google + GitHub Security Lab, multi-ecosystem)\n  - **NVD** (official NIST records, used for enrichment: full CVSS, references, CPE configurations)\n- **CPE refinement** — once a CVE is matched, its NVD CPE configurations are checked against the dep version range. A match outside the vulnerable range is flagged `cpeFiltered: true` (likely false positive). A curated `data/cpe-coord-map.json` maps CPE `vendor:product` to Maven `g:a` (60+ entries seeded: log4j, jackson, spring, tomcat, jetty, netty, …).\n- **Prioritization** — each matched CVE is enriched with **EPSS** (FIRST.org exploit-prediction percentile) and **CISA KEV** (known-exploited catalogue), then scored: KEV (exploited in the wild) outranks EPSS-weighted CVSS. The report sorts by this composite priority and badges KEV/EPSS.\n- **Licenses** — each dependency's license is resolved (registry metadata, no extra request; Maven from cached POMs), normalised to SPDX and classified against a copyleft policy (`data/license-policy.json`) — permissive / weak / strong / network copyleft / proprietary / unknown.\n- **Unified outputs** — one `--report-\u003ctype\u003e` flag per output, each with an OPTIONAL path (omit it → a default name under `--report-output`): `--report-html`, `--report-doc`, plus the machine-readable `--report-sbom` (**CycloneDX 1.6**, vulnerabilities inline / VDR), `--report-csaf` (**CSAF 2.0 VEX**), `--report-json` (flat findings, diff-friendly) and `--report-sarif` (**SARIF 2.1.0** for GitHub/GitLab code scanning). With no `--report-*` flag, HTML + `.doc` are written by default; `--no-report` writes nothing (gate-only). purls per ecosystem.\n- **CI gating \u0026 triage** — `--fail-on \u003clow|medium|high|critical|kev\u003e` sets a non-zero exit code (`kev` = fail only on a CISA-known-exploited finding). `--ignore \u003cfile\u003e` (CVE/coord/glob rules) and `--vex \u003cfile\u003e` (ingest a CSAF VEX) suppress accepted-risk / false-positive findings from the report and the gate, while keeping them flagged in the exports — so re-audits stay signal-rich.\n\n---\n\n## Caching\n\nAll cached data lives in `~/.fad-checker/`:\n\n| Cache | Path | TTL |\n| --- | --- | --- |\n| Maven CVE index (CVEProject bundle, filtered) | `cve-data/maven-cve-index.json` | 24 h |\n| OSV per-dep lookups | `osv-cache/\u003cecosystem\u003e__\u003cg\u003e__\u003ca\u003e__\u003cv\u003e.json` | 12 h |\n| OSV vuln details | `osv-cache/vuln_\u003cid\u003e.json` | 12 h |\n| NVD CVE records | `nvd-cache/\u003ccveId\u003e.json` | 7 d |\n| EPSS scores (FIRST.org) | `epss-cache.json` | 24 h |\n| CISA KEV catalogue | `kev-cache.json` | 24 h |\n| Go module proxy (latest) | `go-proxy-cache.json` | 24 h |\n| RubyGems (latest + licenses) | `rubygems-cache.json` | 24 h |\n| endoflife.date cycles | `eol-cache.json` | 7 d |\n| Maven Central latest versions | `version-cache.json` | 24 h |\n| Transitive POMs from Maven Central | `poms-cache/\u003cg\u003e__\u003ca\u003e__\u003cv\u003e.pom` | ∞ (immutable) |\n| retire.js findings | `retire-cache/\u003cmd5(src)\u003e.json` | 24 h |\n| retire.js signature DB | `retire-signatures/jsrepository-v5.json` | warmed online, used offline |\n| User config (NVD key) | `config.json` (mode 0600) | — |\n\nExport the lot to share between machines:\n\n```bash\nfad-checker --export-cache fad-cache.tar.gz\n# on the other box:\nfad-checker --import-cache fad-cache.tar.gz\n```\n\n`--include-config` ships the NVD API key too (off by default).\n\n\u003e The cache export bundles **everything** under `~/.fad-checker/` (except `config.json`),\n\u003e including the retire.js findings **and** the warmed retire.js signature DB — so a\n\u003e machine that imports it can scan vendored JavaScript fully offline.\n\n---\n\n## Air-gapped / PASSI audits: anonymized dependency descriptor\n\nWhen the audited system is **offline / confidential** (typical of a PASSI engagement) it\ncan't reach OSV / NVD / Maven Central / npm. Split the work across machines while keeping\n**zero environment information** off the secure enclave: an anonymized descriptor carries\nonly **public package coordinates** — no filesystem paths, no registry URLs, no\nhostnames/usernames — and the **detailed report is produced back on the offline machine**.\n\nThe transfer relies on a property of fad-checker's caches: they are keyed by *coordinate*\nor *vuln id*, never by path, so they are **machine-independent**. The online step just\n**warms the caches**; the offline step replays the scan and gets cache hits.\n\n```bash\n# ── Phase 1 — OFFLINE (audited machine): export the anonymized descriptor ──\n# Exclude private/internal packages with -e (offline we can't tell private from public).\nfad-checker -s ./proj -e \"^(client|internal)\\.\" --export-anonymized deps.json\n#   → deps.json: public coordinates only. Review it before it leaves the enclave.\n\n# ── Phase 2 — ONLINE (any machine, no source needed): warm the caches ──\nfad-checker --import-anonymized deps.json     # scans coordinates → OSV/NVD/CVE/registry/EOL + retire signatures\nfad-checker --export-cache fad-cache.tar.gz   # bundle the warmed ~/.fad-checker/\n\n# ── Phase 3 — OFFLINE (audited machine): full report, all local context ──\nfad-checker --import-cache fad-cache.tar.gz\nfad-checker -s ./proj --offline               # re-collect locally (real paths) + cache hits\n#   → full HTML/.doc report with manifests \u0026 structure, generated inside the enclave.\n```\n\nWhat the descriptor (`fad-deps/1`) contains vs. drops:\n\n| Kept (needed to scan) | Dropped (environment) |\n| --- | --- |\n| ecosystem, ecosystemType | manifest paths / pom paths |\n| namespace, name | resolved registry URLs |\n| version, versions | integrity hashes |\n| scope, isDev | parent chains, lockfile type |\n\nThe online phase report is itself path-free; vendored-JavaScript (retire.js) findings are\nproduced **offline in phase 3**, since retire needs the actual `.js` files — its signature\nDB is warmed online (phase 2) and carried by `--export-cache`.\n\n---\n\n## Custom Maven repositories\n\nOut of the box `fad-checker` queries Maven Central for transitive POMs and latest versions. If your project depends on artifacts that live on a private Nexus / Artifactory / JBoss repo, add them so transitive resolution and outdated checks work end-to-end.\n\n```bash\n# Persist a repo (lives in ~/.fad-checker/config.json)\nfad-checker --add-repo nexus       https://nexus.acme.com/repository/maven-public/\nfad-checker --add-repo nexus-priv  https://nexus.acme.com/repository/maven-private/  --auth alice:s3cr3t\nfad-checker --list-repos\nfad-checker --remove-repo nexus-priv\n\n# One-off (not persisted) — repeatable\nfad-checker -s ./proj --repo https://nexus.acme.com/repository/maven-public/\n# Inline auth in the URL also works:\nfad-checker -s ./proj --repo https://alice:s3cr3t@nexus.acme.com/repository/maven-public/\n```\n\nRepos are tried **in declared order, Maven Central last**. Auth is sent as a `Basic \u003cbase64\u003e` header. POMs and `maven-metadata.xml` are cached per coord, so subsequent runs are free even against a private repo.\n\n---\n\n## Data sources \u0026 acknowledgments\n\n`fad-checker` is glue around several outstanding public datasets. Each is used per its license terms.\n\n| Source | What we use | License | API / endpoint |\n| --- | --- | --- | --- |\n| [CVEProject `cvelistV5`](https://github.com/CVEProject/cvelistV5) | Daily bulk CVE bundle, filtered to Maven-relevant entries | CC0-1.0 | GitHub release asset (zip) |\n| [OSV.dev](https://osv.dev/) (Google + GitHub Security Lab) | Per-dep vulnerability lookup (Maven, npm, Packagist, PyPI, NuGet, …) | CC-BY 4.0 | `POST api.osv.dev/v1/querybatch`, `GET api.osv.dev/v1/vulns/{id}` |\n| [NIST NVD](https://nvd.nist.gov/) | Canonical CVE description + CVSS vectors + CPE configurations + CWE | US-gov public domain | `GET services.nvd.nist.gov/rest/json/cves/2.0?cveId=…` — free [API key](https://nvd.nist.gov/developers/request-an-api-key) bumps the rate limit 10× |\n| [FIRST.org EPSS](https://www.first.org/epss/) | Exploit-prediction score + percentile per CVE | CC-BY 4.0 | `GET api.first.org/data/v1/epss?cve=…` (batched) |\n| [CISA KEV](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) | Known-exploited-vulnerability catalogue membership | US-gov public domain | `GET cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json` |\n| [endoflife.date](https://endoflife.date/) | Framework / runtime EOL cycle data | MIT | `GET endoflife.date/api/{product}.json` |\n| [Maven Central](https://search.maven.org/) | Latest-version lookups + transitive POM fetches | Free public service | Solr `search.maven.org/solrsearch/select?q=…` + `repo1.maven.org/maven2/\u003ccoord\u003e` |\n| [npm registry](https://registry.npmjs.org/) | Per-version `deprecated` + `dist-tags.latest` | Free public service | `GET registry.npmjs.org/\u003cpkg\u003e` |\n| [Packagist](https://packagist.org/) | Latest stable + `abandoned` flag | Free public service | `GET packagist.org/packages/\u003cvendor\u003e/\u003cpkg\u003e.json` |\n| [PyPI](https://pypi.org/) | Latest + `yanked` + \"Inactive\" classifier | Free public service | `GET pypi.org/pypi/\u003cpkg\u003e/json` |\n| [NuGet](https://www.nuget.org/) | Latest stable + per-version `deprecation` | Free public service | `GET api.nuget.org/v3/registration5-gz-semver2/\u003cid\u003e/index.json` |\n| [Go module proxy](https://proxy.golang.org/) | Latest module version (outdated) | Free public service | `GET proxy.golang.org/\u003cmodule\u003e/@latest` |\n| [RubyGems](https://rubygems.org/) | Latest stable + licenses | Free public service | `GET rubygems.org/api/v1/gems/\u003cgem\u003e.json` |\n| [retire.js](https://retirejs.github.io/retire.js/) | Vendored-JS signature DB + scanner | Apache-2.0 | npm package `retire`, executed locally |\n| [Snyk](https://snyk.io/) (optional) | Additional CVE source via `snyk test --all-projects --json` | Per Snyk EULA; needs a Snyk account | Local CLI `snyk` |\n| [MITRE CWE](https://cwe.mitre.org/) | Weakness category links in the report | Free public reference | Linked by URL only, no API call |\n\nPersistent caches mean each source is hit at most once per its TTL (see [Caching](#caching) table). No telemetry, no third-party analytics — every request listed above is made directly to the named endpoint with a `User-Agent: fad-checker-*` header.\n\n---\n\n## Safety rails\n\nBuilt-in guardrails that fire **before** any disk write:\n\n- `--target` is required unless you're running read-only (no `-t`).\n- `--target` may not equal or be a subdirectory of `--src`.\n- `--target` is `rimraf`'d before being rewritten — never point it at anything precious.\n\n---\n\n## Comparison\n\n`fad-checker` is **not** a Trivy/Grype competitor — those are container-and-SBOM supply-chain\nscanners. It targets a narrower job: a **zero-setup, multi-ecosystem audit of a source\ncheckout, with an audit-ready report and a confidential / air-gapped workflow** — the kind\nof thing a security consultant or an ANSSI-PASSI engagement needs.\n\n| | **fad-checker** | OSV-Scanner | Trivy | Grype + Syft | OWASP DC | Snyk OSS |\n| --- | --- | --- | --- | --- | --- | --- |\n| Ecosystems it targets¹ | Maven, npm, Yarn, **pnpm**, Composer, PyPI, NuGet, Go, Ruby + vendored JS | 11+ langs / 19+ lockfiles | 20+ | 20+ | Java/.NET (others exp.) | many |\n| Reads lockfiles without `install`/build² | ✅ | ✅ | ✅ | ✅ | ⚠️ Java needs Maven Central/build | ❌ build required |\n| Best-effort when **no lockfile** (pinned versions) | ✅ | ❌ | ❌ | ❌ | ⚠️ | ⚠️ |\n| Vulnerability sources | CVEProject + OSV + NVD + EPSS + KEV + retire.js (+ Snyk), merged | OSV.dev | Aqua DB | Anchore DB | NVD / CPE | Snyk DB |\n| False-positive control | CPE/version cross-check | ecosystem-aware | ecosystem-aware | ecosystem-aware | ⚠️ CPE → noisy | ecosystem-aware |\n| **EOL** (end-of-life) detection | ✅ endoflife.date | ❌ | ❌ | ❌ | ❌ | ~ |\n| **Outdated / deprecated** | ✅ registries + curated | ❌ | ❌ | ❌ | ❌ | ~ |\n| Containers / OS packages | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ |\n| SBOM (CycloneDX/SPDX) | ✅ CycloneDX 1.6 (+ CSAF 2.0 VEX) | ✅ | ✅ | ✅ (Syft) | ~ | ✅ |\n| License compliance | ✅ SPDX + copyleft policy | ~ | ✅ | ~ | ❌ | ✅ |\n| EPSS / KEV prioritization | ✅ FIRST.org EPSS + CISA KEV | ~ | ✅ | ✅ | ❌ | ✅ |\n| CI gating (`--fail-on`) + triage | ✅ severity/KEV + ignore/VEX | ✅ | ✅ | ✅ | ⚠️ | ✅ |\n| Auto-remediation / PRs | ❌ (fix recipes only) | ✅ `fix` | ❌ | ❌ | ❌ | ✅ |\n| Offline | ✅ cache | ✅ local DB | ✅ | ✅ | ✅ feed | ❌ mostly online |\n| **Scan without exposing the codebase**³ | ✅ anonymized descriptor | ❌ | ❌ | ❌ | ❌ | ❌ |\n| **Maven private-dep cleanup** (→ Snyk) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |\n| Output | **HTML + Word `.doc`** + JSON / SARIF / CycloneDX / CSAF | table/JSON/SARIF | table/JSON/SARIF | table/JSON/SARIF | HTML/XML/JSON | JSON / cloud UI |\n\n¹ Narrower language coverage — no Rust/Dart/Swift (Go and Ruby are now covered).\n² Reading **lockfiles** without a build is the norm today: OSV-Scanner, Trivy and Grype/Syft\ndo it too. For **Maven `pom.xml`** specifically, *every* tool — `fad-checker` included — must\nreach Maven Central (or rely on a real build / CycloneDX SBOM) to resolve transitive versions;\nTrivy can resolve wrong transitive versions in that mode, while `fad-checker` flags what it\ncan't resolve in chapter 0. The genuine \"no build\" win is **vs Snyk** (requires building the\nproject) and **OWASP DC** (needs Maven Central access for Java accuracy).\n³ Phase 1 exports only public coordinates; the online scan never sees your source tree —\nsee [Air-gapped / PASSI](#air-gapped--passi-audits-anonymized-dependency-descriptor). OSV-Scanner\nhas an offline mode, but it still needs the **source on the scanning machine**.\n\n**Where it fits:** a one-shot audit of a polyglot checkout you may not be able to build, a\npresentable HTML/Word deliverable, and confidential / air-gapped engagements.\n**Where it doesn't:** continuous CI supply-chain security, container/OS scanning,\nreachability analysis, auto-fix PRs — reach for **Trivy** or **Grype + Syft**. (It now\n*does* emit CycloneDX/CSAF and flag licenses + EPSS/KEV, but it isn't a gating CI daemon.)\n\nYou don't have to choose — `fad-checker` takes Snyk's results as input (`--snyk`) and merges them.\n\n\u003e Sources: [OSV-Scanner lockfiles](https://google.github.io/osv-scanner/supported-languages-and-lockfiles/) ·\n\u003e [Trivy Java/`pom.xml` (Maven Central, `--offline-scan`)](https://trivy.dev/docs/latest/coverage/language/java/) ·\n\u003e [Syft `java-pom-cataloger` (source dirs)](https://github.com/anchore/syft/issues/676) ·\n\u003e [OWASP DC needs internet/build for Java](https://jeremylong.github.io/DependencyCheck/data/index.html) ·\n\u003e [Snyk requires building the project](https://docs.snyk.io/supported-languages/technical-specifications-and-guidance) ·\n\u003e [EOL/outdated \"most tools skip\" (Aikido)](https://www.aikido.dev/code/outdated-eol-software)\n\n---\n\n## Docs\n\n- [`docs/USAGE.md`](docs/USAGE.md) — every flag, every workflow, examples.\n- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — internals: codecs, collection, matching, report pipeline.\n- [`CHANGELOG.md`](CHANGELOG.md) — release history.\n- [`CLAUDE.md`](CLAUDE.md) — code-level orientation for contributors.\n\n---\n\n## License\n\nMIT — see [`LICENSE`](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn8tz%2Ffad-checker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fn8tz%2Ffad-checker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn8tz%2Ffad-checker/lists"}