fad-checker 2.2.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -333
- package/fad-checker.js +59 -22
- package/lib/charts.js +293 -0
- package/lib/codecs/composer.codec.js +4 -1
- package/lib/codecs/go.codec.js +4 -1
- package/lib/codecs/gradle/catalog.js +91 -0
- package/lib/codecs/gradle/parse.js +211 -0
- package/lib/codecs/gradle.codec.js +155 -0
- package/lib/codecs/index.js +3 -2
- package/lib/codecs/maven.codec.js +1 -1
- package/lib/codecs/npm/collect.js +3 -0
- package/lib/codecs/npm.codec.js +1 -1
- package/lib/codecs/nuget.codec.js +8 -2
- package/lib/codecs/pypi.codec.js +37 -14
- package/lib/codecs/recipes.js +18 -1
- package/lib/codecs/ruby.codec.js +3 -1
- package/lib/cpe.js +39 -2
- package/lib/cve-match.js +20 -1
- package/lib/cve-report.js +300 -86
- package/lib/deps-descriptor.js +2 -2
- package/lib/osv-db.js +1 -1
- package/lib/retire.js +1 -1
- package/package.json +2 -3
- package/fad-checker-report/cve-report.doc +0 -10987
- package/fad-checker-report/cve-report.html +0 -11126
package/README.md
CHANGED
|
@@ -8,40 +8,44 @@
|
|
|
8
8
|
> **F**abulous **A**utonomous **D**ependency **C**hecker<br>
|
|
9
9
|
> AKA **F**uckin' **A**utonomous **D**ependency **C**hecker<br>
|
|
10
10
|
|
|
11
|
-
`fad-checker`
|
|
12
|
-
|
|
11
|
+
`fad-checker` audits **Maven · Gradle · npm · Yarn · pnpm · Composer · PyPI · NuGet · Go · Ruby**, vendored JavaScript and committed native binaries in any source tree — multi-module, monorepo, polyglot — and produces a self-contained **HTML + Word report** (CVE prioritised by EPSS + CISA KEV, EOL, obsolete, outdated, licenses) plus **CycloneDX SBOM / CSAF VEX / SARIF / JSON** exports. **No build tools, no Docker, no network needed** — it reads lockfiles and manifests straight off disk.
|
|
13
12
|
|
|
14
13
|
🌐 **[Project site & docs →](https://n8tz.github.io/fad-checker/)**
|
|
15
14
|
|
|
16
|
-
<p align="center"><img src="docs/assets/
|
|
15
|
+
<p align="center"><img src="docs/assets/demo.gif" alt="fad-checker animated terminal demo — a [n/N] checklist warming each vulnerability database, then CVE findings coloured by severity with KEV badges" height="600"></p>
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
## Features
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
- **10 ecosystems in one pass** — Maven, **Gradle**, npm/Yarn/pnpm, Composer (PHP), PyPI, NuGet, Go, Ruby; plus **vendored JS** (retire.js), committed **native binaries** (`.dll`/`.exe`/`.so`/`.dylib`, identified by checksum via deps.dev + CIRCL) and **embedded JARs** (fat-jars/war/ear, unzipped in-memory).
|
|
20
|
+
- **No build tools** — reads `pom.xml`, `build.gradle(.kts)`/`gradle.lockfile`/`libs.versions.toml`, `package-lock`/`yarn.lock`/`pnpm-lock`, `composer.lock`, `poetry`/`Pipfile`/`uv`/`pdm` locks, `packages.lock.json`/`*.csproj`, `go.mod`, `Gemfile.lock` directly. No `mvn`/`gradle`/`npm install`/`pip`/`dotnet restore`/`go build`/`bundle`, no `node_modules/`. → [how it stays build-free](docs/COMPARISON.md#how-its-autonomous-no-build-tools)
|
|
21
|
+
- **CVE, merged & prioritised** — CVEProject + OSV.dev + NVD, CPE/version cross-checked to cut false positives, ranked **CISA KEV → EPSS → CVSS**.
|
|
22
|
+
- **Per-module Maven version mediation** — recovers vulnerable transitive versions that a global `<dependencyManagement>` pin hides in another module (lifted Snyk-corroborated coverage **156 → 181** on a real 25-module reactor, finding CVEs a single Snyk scan missed).
|
|
23
|
+
- **Air-gapped** — **zero network under `--offline`** (regression-tested), offline Maven transitive resolution, and `--osv-db` for cache-independent offline OSV recall. → [Air-gapped](#air-gapped-audits)
|
|
24
|
+
- **Supply-chain risk** — known-**malicious** advisories (`MAL-`, always block the CI gate) + suspected **typosquats** (`--typosquat`).
|
|
25
|
+
- **Lifecycle** — EOL (endoflife.date), obsolete/deprecated, outdated — across every ecosystem.
|
|
26
|
+
- **Licenses** *(opt-in `--licenses`)* — SPDX-normalised, copyleft/proprietary flagged.
|
|
27
|
+
- **Outputs & CI** — HTML + Word `.doc`, CycloneDX 1.6 SBOM, CSAF 2.0 VEX, SARIF 2.1.0, JSON; gate with `--fail-on`, triage with `--ignore`/`--vex`.
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
📖 **[Usage & all flags](docs/USAGE.md)** · **[Architecture](docs/ARCHITECTURE.md)** · **[Comparison vs other tools](docs/COMPARISON.md)** · **[Data sources](docs/DATA-SOURCES.md)**
|
|
23
30
|
|
|
24
|
-
##
|
|
31
|
+
## Quick start
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g fad-checker
|
|
35
|
+
fad-checker -s ./my-project # → ./fad-checker-report/cve-report.html
|
|
36
|
+
```
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
| --- | --- |
|
|
30
|
-
| 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). |
|
|
31
|
-
| `mvn dependency:tree` | Same as above. We walk the tree ourselves. |
|
|
32
|
-
| `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. |
|
|
33
|
-
| `yarn install` / `pnpm install` | Same. We read `yarn.lock` (v1 + Berry) and `pnpm-lock.yaml` directly. |
|
|
34
|
-
| `composer install` | `composer.lock` is parsed directly (concrete versions + transitive). `composer.json` alone → best-effort on pinned versions + warning. |
|
|
35
|
-
| `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. |
|
|
36
|
-
| `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. |
|
|
37
|
-
| `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. |
|
|
38
|
-
| `bundle install` | `Gemfile.lock` is parsed for the resolved gem set. No Ruby, no bundler. |
|
|
39
|
-
| `snyk` binary | Built-in CVE matching via CVEProject + OSV + NVD (merged), prioritised with EPSS + CISA KEV (see below). Snyk is *optional* (`--snyk`). |
|
|
40
|
-
| A network connection | First run downloads CVE / OSV / EOL data; subsequent runs use cached copies (`--offline` to force). |
|
|
38
|
+
A free [NVD API key](https://nvd.nist.gov/developers/request-an-api-key) (instant) gives 10× faster enrichment: `fad-checker --set-nvd-key YOUR_KEY`. A few common runs — full list via `fad-checker --help` or [docs/USAGE.md](docs/USAGE.md):
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
```bash
|
|
41
|
+
fad-checker -s ./proj -e "^com\.acme\." # exclude private libs (coord regex)
|
|
42
|
+
fad-checker -s ./proj -t ../clean -e "^com\.acme\." --snyk # cleaned POM tree + merge Snyk
|
|
43
|
+
fad-checker -s ./proj --offline # fully offline (zero network)
|
|
44
|
+
fad-checker -s ./proj --osv-db --typosquat # offline-complete OSV + typosquat
|
|
45
|
+
fad-checker -s ./proj --licenses --fail-on high # license chapter + CI gate
|
|
46
|
+
```
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
A single self-contained binary (no Node), from-source install and shell completion are in → [docs/USAGE.md](docs/USAGE.md).
|
|
45
49
|
|
|
46
50
|
## What it finds
|
|
47
51
|
|
|
@@ -59,188 +63,13 @@ Exactly **one** runtime dependencies must be on PATH (or installed automatically
|
|
|
59
63
|
| **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` |
|
|
60
64
|
| **6. Outdated libraries** | Maven Central + npm / Packagist / PyPI / NuGet registries | Available newer versions, with release dates |
|
|
61
65
|
| **7. Licenses** *(opt-in: `--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 |
|
|
62
|
-
| **8. Fix Recommendations** | computed | Per-ecosystem pin recipes: Maven `<dependencyManagement>`, npm `overrides`, yarn `resolutions`, `composer require`, `pip install`, `dotnet add package` |
|
|
66
|
+
| **8. Fix Recommendations** | computed | Per-ecosystem pin recipes: Maven `<dependencyManagement>`, Gradle `constraints { }`, npm `overrides`, yarn `resolutions`, `composer require`, `pip install`, `dotnet add package` |
|
|
63
67
|
|
|
64
68
|
The 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 > EPSS likelihood > 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.
|
|
65
69
|
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Quick start
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
npm install -g fad-checker
|
|
72
|
-
fad-checker -s ./my-project
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
That's it. The report lands in `./fad-checker-report/cve-report.html`.
|
|
76
|
-
|
|
77
|
-
Want a 10× faster NVD enrichment? [Get a free NVD API key](https://nvd.nist.gov/developers/request-an-api-key) (instant), then:
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
fad-checker --set-nvd-key YOUR_KEY
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Common runs
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# Read-only full scan (default: all sources on)
|
|
89
|
-
fad-checker -s ./proj
|
|
90
|
-
|
|
91
|
-
# Exclude private/internal libs by groupId/name regex
|
|
92
|
-
fad-checker -s ./proj -e "^(com\.acme|org\.private)\."
|
|
93
|
-
|
|
94
|
-
# Ignore whole sub-paths during the walk (gitignore-style glob, relative to -s)
|
|
95
|
-
fad-checker -s ./proj --exclude-path "packages/legacy/**" --exclude-path "**/fixtures/**"
|
|
96
|
-
fad-checker -s ./proj --no-default-excludes # walk everything (incl. node_modules/.git)
|
|
97
|
-
|
|
98
|
-
# Also write cleaned POMs (private deps stripped, ready for Snyk)
|
|
99
|
-
fad-checker -s ./proj -t ../proj-clean -e "^com\.acme\."
|
|
100
|
-
|
|
101
|
-
# Then run Snyk on the cleaned tree and merge findings
|
|
102
|
-
fad-checker -s ./proj -t ../proj-clean -e "^com\.acme\." --snyk
|
|
103
|
-
|
|
104
|
-
# Faster: skip Maven Central / no transitive walk
|
|
105
|
-
fad-checker -s ./proj --no-all-libs --no-transitive
|
|
106
|
-
|
|
107
|
-
# Fully offline (uses cached data only) — zero network, guaranteed (see Air-gapped below)
|
|
108
|
-
fad-checker -s ./proj --offline
|
|
109
|
-
|
|
110
|
-
# Offline-COMPLETE OSV recall (Maven): import the full OSV DB once, then match offline
|
|
111
|
-
# regardless of the per-dep cache (the OSV-Scanner air-gap model)
|
|
112
|
-
fad-checker -s ./proj --osv-db # online: download (~9 MB) + match
|
|
113
|
-
fad-checker -s ./proj --osv-db --offline # offline: match against the imported DB
|
|
114
|
-
|
|
115
|
-
# Supply-chain risk: known-malicious packages always flagged; add the typosquat heuristic
|
|
116
|
-
fad-checker -s ./proj --typosquat
|
|
117
|
-
|
|
118
|
-
# License + copyleft-policy chapter (off by default)
|
|
119
|
-
fad-checker -s ./proj --licenses
|
|
120
|
-
|
|
121
|
-
# Pick ecosystems — --ecosystem is a list: auto (default) | all | comma list
|
|
122
|
-
fad-checker -s ./proj --ecosystem maven # Maven only
|
|
123
|
-
fad-checker -s ./proj --ecosystem maven,npm,pypi # several
|
|
124
|
-
fad-checker -s ./proj --no-nuget --no-composer # or opt out per codec
|
|
125
|
-
fad-checker -s ./proj --no-binaries # skip the native-binary scan
|
|
126
|
-
|
|
127
|
-
# Private registry + reusable defaults (see "Configuration file & environment")
|
|
128
|
-
fad-checker --add-repo npm verdaccio https://npm.acme.com/ --token "$NPM_TOKEN"
|
|
129
|
-
fad-checker --config ./ci/fad-env.json # all options from a JSON file
|
|
130
|
-
fad-checker --source ./proj # --source / --src are aliases
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Run `fad-checker --help` for the full flag list.
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## What a report looks like
|
|
138
|
-
|
|
139
70
|
<p align="center"><img 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"></p>
|
|
140
71
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
```
|
|
144
|
-
╭───────────────────────────────────────────────────╮
|
|
145
|
-
│ fad-checker v2.2.1 · Autonomous Dependency Checker │
|
|
146
|
-
╰───────────────────────────────────────────────────╯
|
|
147
|
-
Executive Summary [CRITICAL] — 1708 dependencies scanned
|
|
148
|
-
• 81 CVE in production deps (critical=5, high=53, medium=12, low=11)
|
|
149
|
-
• 32 CVE in dev/test deps · 17 vulnerable vendored JS (retire.js)
|
|
150
|
-
• 2 EOL frameworks · 13 obsolete/deprecated · 172 outdated
|
|
151
|
-
• 4 scan-completeness alerts — see chapter 0
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
The HTML report organises this into chapters (0 Warnings, 1 CVE prod, 1B embedded JARs,
|
|
155
|
-
1C native binaries, 1D vendored-JS inventory, 2 vendored-JS vulns, 3 dev CVE, 4 EOL,
|
|
156
|
-
5 obsolete, 6 outdated, 7 Licenses *(opt-in)*, 8 Fix Recommendations), each grouped by
|
|
157
|
-
ecosystem and manifest. Every CVE row carries: severity badge · CVE/GHSA id · coord &
|
|
158
|
-
version · declaring manifest · source(s) · fix-version · priority (KEV/EPSS) — click for
|
|
159
|
-
the full panel (CVSS vectors, references, transitive paths, CPE configs).
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Install
|
|
164
|
-
|
|
165
|
-
### As a global CLI
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
npm install -g fad-checker
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### From source
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
git clone <repo-url> fad-checker
|
|
175
|
-
cd fad-checker
|
|
176
|
-
npm install
|
|
177
|
-
node fad-checker.js --help
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Single-binary build (no Node required)
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
npm install # one-time, brings in bun
|
|
184
|
-
npm run build # → dist/fad-checker-linux + dist/fad-checker.exe
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Shell completion
|
|
188
|
-
|
|
189
|
-
```bash
|
|
190
|
-
fad-checker --completion bash > /etc/bash_completion.d/fad-checker
|
|
191
|
-
# or for zsh:
|
|
192
|
-
fad-checker --completion zsh > ~/.zsh/completions/_fad-checker
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
## How it scans without any build tool
|
|
198
|
-
|
|
199
|
-
**TL;DR** — `fad-checker` never runs your build. For each ecosystem it reads the **lockfile** (or, failing that, the manifest's pinned versions) straight off disk to learn the exact dependency versions, then matches those coordinates against vulnerability/EOL/registry data over the network (cached, `--offline`-able). No `mvn`, `npm install`, `pip`, `dotnet restore`, `go build` or `bundle` — and no `node_modules/`.
|
|
200
|
-
|
|
201
|
-
| Ecosystem | Read directly | Transitive versions come from |
|
|
202
|
-
| --- | --- | --- |
|
|
203
|
-
| Maven | `pom.xml` (+ parents, BOMs, profiles) | child POMs fetched from Maven Central (cached) |
|
|
204
|
-
| npm / Yarn / pnpm | `package-lock.json` · `yarn.lock` (v1+Berry) · `pnpm-lock.yaml` | the lockfile itself |
|
|
205
|
-
| Composer | `composer.lock` (else `composer.json`) | the lockfile |
|
|
206
|
-
| PyPI | `poetry.lock` · `Pipfile.lock` · `uv.lock` · `pdm.lock` (else `pyproject.toml`/`requirements.txt`) | the lockfile |
|
|
207
|
-
| NuGet | `packages.lock.json` (else `*.csproj`/`packages.config`) | the lockfile |
|
|
208
|
-
| Go | `go.mod` (`// indirect` → transitive; `go.sum` fallback) | the module graph in `go.mod` |
|
|
209
|
-
| Ruby | `Gemfile.lock` (`specs:`) | the lockfile |
|
|
210
|
-
| Vendored JS / binaries | the committed `.js` / `.jar` / `.so` files themselves | n/a (read in place) |
|
|
211
|
-
|
|
212
|
-
Highlights of the matching layer: **three CVE sources merged** (CVEProject + OSV.dev + NVD), **CPE/version cross-check** to drop false positives, **EPSS + CISA KEV** prioritisation, lockfile-first with a **best-effort pinned-version fallback** when no lockfile, in-memory **embedded-JAR** unzip (no disk, no zip-slip), and **checksum identity** for native binaries. Outputs: HTML + `.doc` by default, plus opt-in `--report-sbom`/`-csaf`/`-json`/`-sarif`; CI gating via `--fail-on` with `--ignore`/`--vex` triage.
|
|
213
|
-
|
|
214
|
-
Two things set the Maven path apart for multi-module / air-gapped work:
|
|
215
|
-
|
|
216
|
-
- **Per-module version mediation** (automatic). The global transitive pass resolves the whole reactor as one tree; that can let a `<dependencyManagement>` pin in one module hide an *older, vulnerable* transitive of the same library in another module. fad re-resolves each module with **only its own** effective depMgmt and recovers those masked versions — on a real 25-module project that lifted Snyk-corroborated coverage **156 → 181**, recovering CVEs (e.g. `poi 3.11` / CVE-2017-12626) that a single Snyk scan of the tree missed.
|
|
217
|
-
- **Offline-complete OSV** (`--osv-db`). Imports the full OSV database (Maven) once, then matches every dep against it offline — so air-gapped recall no longer depends on which deps the per-dep OSV cache happened to warm (the [OSV-Scanner](https://github.com/google/osv-scanner) `--download-offline-databases` model). On a cold-cache offline run that's the difference between **6** and **117** of 202 findings covered.
|
|
218
|
-
|
|
219
|
-
> Full per-ecosystem and per-stage detail lives in **[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)** and **[`docs/USAGE.md`](docs/USAGE.md)**.
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## Caching
|
|
224
|
-
|
|
225
|
-
All cached data lives in `~/.fad-checker/` — every source is hit at most once per its
|
|
226
|
-
TTL (12 h–7 d, transitive POMs forever as they're immutable). Full per-cache TTL table
|
|
227
|
-
in [`docs/USAGE.md`](docs/USAGE.md). Export the lot to share between machines:
|
|
228
|
-
|
|
229
|
-
```bash
|
|
230
|
-
fad-checker --export-cache fad-cache.tar.gz
|
|
231
|
-
# on the other box:
|
|
232
|
-
fad-checker --import-cache fad-cache.tar.gz
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
`--include-config` ships the NVD API key too (off by default).
|
|
236
|
-
|
|
237
|
-
> The cache export bundles **everything** under `~/.fad-checker/` (except `config.json`),
|
|
238
|
-
> including the retire.js findings **and** the warmed retire.js signature DB — so a
|
|
239
|
-
> machine that imports it can scan vendored JavaScript fully offline.
|
|
240
|
-
|
|
241
|
-
---
|
|
242
|
-
|
|
243
|
-
## Air-gapped / PASSI audits: anonymized dependency descriptor
|
|
72
|
+
## Air-gapped audits
|
|
244
73
|
|
|
245
74
|
> **Zero-data-sent guarantee.** Under `--offline`, fad-checker makes **no network calls
|
|
246
75
|
> whatsoever** — it reads only the warmed `~/.fad-checker/` caches and never transmits a
|
|
@@ -249,10 +78,9 @@ fad-checker --import-cache fad-cache.tar.gz
|
|
|
249
78
|
> auditor-reproducible: `unshare -rn node fad-checker.js -s ./proj --offline …` runs it in a
|
|
250
79
|
> namespace with **no network interface** and yields byte-identical findings. Unlike the
|
|
251
80
|
> mainstream OSS scanners, fad also resolves the **Maven transitive graph** offline — so on
|
|
252
|
-
> an air-gapped multi-module project it finds the transitive CVEs they can't
|
|
253
|
-
> `docs/USAGE.md` → *Zero-data-sent guarantee*).
|
|
81
|
+
> an air-gapped multi-module project it finds the transitive CVEs they can't.
|
|
254
82
|
|
|
255
|
-
When the audited system is **offline / confidential** (typical of a
|
|
83
|
+
When the audited system is **offline / confidential** (typical of a regulated or air-gapped audit) it
|
|
256
84
|
can't reach OSV / NVD / Maven Central / npm. Split the work across machines while keeping
|
|
257
85
|
**zero environment information** off the secure enclave: an anonymized descriptor carries
|
|
258
86
|
only **public package coordinates** — no filesystem paths, no registry URLs, no
|
|
@@ -289,140 +117,16 @@ What the descriptor (`fad-deps/1`) contains vs. drops:
|
|
|
289
117
|
|
|
290
118
|
The online phase report is itself path-free; vendored-JavaScript (retire.js) findings are
|
|
291
119
|
produced **offline in phase 3**, since retire needs the actual `.js` files — its signature
|
|
292
|
-
DB is warmed online (phase 2) and carried by `--export-cache`.
|
|
293
|
-
|
|
294
|
-
---
|
|
295
|
-
|
|
296
|
-
## Custom repositories & registries
|
|
297
|
-
|
|
298
|
-
Register private **Nexus / Artifactory / Verdaccio / devpi / GOPROXY** registries (for **`maven`, `npm`, `pypi`, `ruby`, `go`**) so transitive resolution, outdated/deprecation and license lookups reach them:
|
|
299
|
-
|
|
300
|
-
```bash
|
|
301
|
-
fad-checker --add-repo maven nexus https://nexus.acme.com/repository/maven-public/ --auth alice:s3cr3t
|
|
302
|
-
fad-checker --add-repo npm verdaccio https://npm.acme.com/ --token "$NPM_TOKEN"
|
|
303
|
-
fad-checker -s ./proj --repo npm=https://npm.acme.com/ # one-off, repeatable
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
Tried in declared order, public registry last; auth via `--auth user:pass` / `--token TOK` / inline URL; responses cached per coordinate. NuGet/Composer private feeds aren't supported yet. **Full details, the PyPI/Ruby JSON-API caveat and `--list-repos`/`--remove-repo` → [`docs/USAGE.md`](docs/USAGE.md).**
|
|
307
|
-
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
## Configuration file & environment
|
|
311
|
-
|
|
312
|
-
Don't retype flags every run. Precedence: **CLI flag > `--config <file.json>` / `./.fad-env.json` (JSON, keys = camelCase options) > `FAD_CHECKER_ENV` (a string of CLI flags) > `~/.fad-checker/config.json` > defaults.** A file/env value only fills an option you didn't pass; **registries are merged across every layer**.
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
fad-checker --config ./ci/fad-env.json
|
|
316
|
-
FAD_CHECKER_ENV='--fail-on high --no-nuget' fad-checker -s ./proj
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
`-s` / `--src` / `--source` are aliases. **`-e/--exclude`** is a regex on the **coordinate** (drops deps); **`--exclude-path`** is a gitignore-style glob on the **path** (prunes the walk). Full `.fad-env.json` schema → [`docs/USAGE.md`](docs/USAGE.md).
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## Data sources & acknowledgments
|
|
324
|
-
|
|
325
|
-
`fad-checker` is glue around several outstanding public datasets. Each is used per its license terms.
|
|
326
|
-
|
|
327
|
-
| Source | What we use | License | API / endpoint |
|
|
328
|
-
| --- | --- | --- | --- |
|
|
329
|
-
| [CVEProject `cvelistV5`](https://github.com/CVEProject/cvelistV5) | Daily bulk CVE bundle, filtered to Maven-relevant entries | CC0-1.0 | GitHub release asset (zip) |
|
|
330
|
-
| [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}` |
|
|
331
|
-
| [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× |
|
|
332
|
-
| [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) |
|
|
333
|
-
| [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` |
|
|
334
|
-
| [endoflife.date](https://endoflife.date/) | Framework / runtime EOL cycle data | MIT | `GET endoflife.date/api/{product}.json` |
|
|
335
|
-
| [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/<coord>` |
|
|
336
|
-
| [npm registry](https://registry.npmjs.org/) | Per-version `deprecated` + `dist-tags.latest` | Free public service | `GET registry.npmjs.org/<pkg>` |
|
|
337
|
-
| [Packagist](https://packagist.org/) | Latest stable + `abandoned` flag | Free public service | `GET packagist.org/packages/<vendor>/<pkg>.json` |
|
|
338
|
-
| [PyPI](https://pypi.org/) | Latest + `yanked` + "Inactive" classifier | Free public service | `GET pypi.org/pypi/<pkg>/json` |
|
|
339
|
-
| [NuGet](https://www.nuget.org/) | Latest stable + per-version `deprecation` | Free public service | `GET api.nuget.org/v3/registration5-gz-semver2/<id>/index.json` |
|
|
340
|
-
| [Go module proxy](https://proxy.golang.org/) | Latest module version (outdated) | Free public service | `GET proxy.golang.org/<module>/@latest` |
|
|
341
|
-
| [RubyGems](https://rubygems.org/) | Latest stable + licenses | Free public service | `GET rubygems.org/api/v1/gems/<gem>.json` |
|
|
342
|
-
| [deps.dev](https://deps.dev/) | Native-binary identity by checksum (→ package coordinate) | Free public API (CC-BY) | `GET api.deps.dev/v3/query?hash.type=SHA1&hash.value=<base64>` |
|
|
343
|
-
| [CIRCL hashlookup](https://hashlookup.circl.lu/) | Known-good file identity (NSRL/distro/CDN) + KnownMalicious | Free public service | `GET hashlookup.circl.lu/lookup/sha256/<hash>` |
|
|
344
|
-
| [retire.js](https://retirejs.github.io/retire.js/) | Vendored-JS signature DB + scanner | Apache-2.0 | npm package `retire`, executed locally |
|
|
345
|
-
| [Snyk](https://snyk.io/) (optional) | Additional CVE source via `snyk test --all-projects --json` | Per Snyk EULA; needs a Snyk account | Local CLI `snyk` |
|
|
346
|
-
| [MITRE CWE](https://cwe.mitre.org/) | Weakness category links in the report | Free public reference | Linked by URL only, no API call |
|
|
347
|
-
|
|
348
|
-
Persistent 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.
|
|
349
|
-
|
|
350
|
-
---
|
|
351
|
-
|
|
352
|
-
## Safety rails
|
|
353
|
-
|
|
354
|
-
Built-in guardrails that fire **before** any disk write:
|
|
355
|
-
|
|
356
|
-
- `--target` is required unless you're running read-only (no `-t`).
|
|
357
|
-
- `--target` may not equal or be a subdirectory of `--src`.
|
|
358
|
-
- `--target` is `rimraf`'d before being rewritten — never point it at anything precious.
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
|
-
## Comparison
|
|
363
|
-
|
|
364
|
-
`fad-checker` is **not** a Trivy/Grype competitor — those are container-and-SBOM supply-chain
|
|
365
|
-
scanners. It targets a narrower job: a **zero-setup, multi-ecosystem audit of a source
|
|
366
|
-
checkout, with an audit-ready report and a confidential / air-gapped workflow** — the kind
|
|
367
|
-
of thing a security consultant or an ANSSI-PASSI engagement needs.
|
|
368
|
-
|
|
369
|
-
| | **fad-checker** | OSV-Scanner | Trivy | Grype + Syft | OWASP DC | Snyk OSS |
|
|
370
|
-
| --- | --- | --- | --- | --- | --- | --- |
|
|
371
|
-
| Ecosystems it targets¹ | Maven, npm, Yarn, **pnpm**, Composer, PyPI, NuGet, Go, Ruby + vendored JS + **native binaries** | 11+ langs / 19+ lockfiles | 20+ | 20+ | Java/.NET (others exp.) | many |
|
|
372
|
-
| Reads lockfiles without `install`/build | ✅ | ✅ | ✅ | ✅ | ⚠️ Java needs Maven Central/build | ❌ build required |
|
|
373
|
-
| Best-effort when **no lockfile** (pinned versions) | ✅ | ❌ | ❌ | ❌ | ⚠️ | ⚠️ |
|
|
374
|
-
| Vulnerability sources | CVEProject + OSV + NVD + EPSS + KEV + retire.js (+ Snyk), merged | OSV.dev | Aqua DB | Anchore DB | NVD / CPE | Snyk DB |
|
|
375
|
-
| False-positive control | CPE/version cross-check | ecosystem-aware | ecosystem-aware | ecosystem-aware | ⚠️ CPE → noisy | ecosystem-aware |
|
|
376
|
-
| **EOL** (end-of-life) detection | ✅ endoflife.date | ❌ | ❌ | ❌ | ❌ | ~ |
|
|
377
|
-
| **Outdated / deprecated** | ✅ registries + curated | ❌ | ❌ | ❌ | ❌ | ~ |
|
|
378
|
-
| Containers / OS packages | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
|
379
|
-
| SBOM (CycloneDX/SPDX) | ✅ CycloneDX 1.6 (+ CSAF 2.0 VEX) | ✅ | ✅ | ✅ (Syft) | ~ | ✅ |
|
|
380
|
-
| License compliance | ✅ SPDX + copyleft policy | ~ | ✅ | ~ | ❌ | ✅ |
|
|
381
|
-
| EPSS / KEV prioritization | ✅ FIRST.org EPSS + CISA KEV | ~ | ✅ | ✅ | ❌ | ✅ |
|
|
382
|
-
| CI gating (`--fail-on`) + triage | ✅ severity/KEV + ignore/VEX | ✅ | ✅ | ✅ | ⚠️ | ✅ |
|
|
383
|
-
| Auto-remediation / PRs | ❌ (fix recipes only) | ✅ `fix` | ❌ | ❌ | ❌ | ✅ |
|
|
384
|
-
| Offline | ✅ cache | ✅ local DB | ✅ | ✅ | ✅ feed | ❌ mostly online |
|
|
385
|
-
| Offline Maven **transitive** graph³ | ✅ cached POMs | ❌ disabled offline | ❌ | ❌ | ⚠️ mirror | ❌ |
|
|
386
|
-
| **Scan without exposing the codebase**² | ✅ anonymized descriptor | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
387
|
-
| **Maven private-dep cleanup** (→ Snyk) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
388
|
-
| Output | **HTML + Word `.doc`** + JSON / SARIF / CycloneDX / CSAF | table/JSON/SARIF | table/JSON/SARIF | table/JSON/SARIF | HTML/XML/JSON | JSON / cloud UI |
|
|
389
|
-
|
|
390
|
-
¹ Narrower language coverage — no Rust/Dart/Swift (Go and Ruby are now covered).
|
|
391
|
-
|
|
392
|
-
² Phase 1 exports only public coordinates; the online scan never sees your source tree —
|
|
393
|
-
see [Air-gapped / PASSI](#air-gapped--passi-audits-anonymized-dependency-descriptor). OSV-Scanner
|
|
394
|
-
has an offline mode, but it still needs the **source on the scanning machine**.
|
|
395
|
-
|
|
396
|
-
³ Measured on a 25-module Spring/JSF project, fully air-gapped: fad covered **181/202**
|
|
397
|
-
Snyk-corroborated findings vs OSV-Scanner v2.3.8's **64/202** — **0 on Maven**, because its
|
|
398
|
-
transitive resolution is disabled without network. fad resolves the Maven graph from cached
|
|
399
|
-
POMs (and `--osv-db` makes its offline OSV recall cache-independent).
|
|
400
|
-
|
|
401
|
-
**Where it fits:** a one-shot audit of a polyglot source code, needing a
|
|
402
|
-
presentable HTML/Word deliverable, and confidential / air-gapped engagements.
|
|
403
|
-
|
|
404
|
-
**Where it doesn't:** container/OS scanning,
|
|
405
|
-
reachability analysis, auto-fix PRs — reach for **Trivy** or **Grype + Syft**.
|
|
406
|
-
|
|
407
|
-
You don't have to choose — `fad-checker` takes Snyk's results as input (`--snyk`) and merges them.
|
|
408
|
-
|
|
409
|
-
> Sources: [OSV-Scanner lockfiles](https://google.github.io/osv-scanner/supported-languages-and-lockfiles/) ·
|
|
410
|
-
> [Trivy Java/`pom.xml` (Maven Central, `--offline-scan`)](https://trivy.dev/docs/latest/coverage/language/java/) ·
|
|
411
|
-
> [Syft `java-pom-cataloger` (source dirs)](https://github.com/anchore/syft/issues/676) ·
|
|
412
|
-
> [OWASP DC needs internet/build for Java](https://jeremylong.github.io/DependencyCheck/data/index.html) ·
|
|
413
|
-
> [Snyk requires building the project](https://docs.snyk.io/supported-languages/technical-specifications-and-guidance) ·
|
|
414
|
-
> [EOL/outdated "most tools skip" (Aikido)](https://www.aikido.dev/code/outdated-eol-software)
|
|
415
|
-
|
|
416
|
-
---
|
|
120
|
+
DB is warmed online (phase 2) and carried by `--export-cache`. Full offline/cache control →
|
|
121
|
+
[`docs/USAGE.md`](docs/USAGE.md).
|
|
417
122
|
|
|
418
123
|
## Docs
|
|
419
124
|
|
|
420
|
-
- [`docs/USAGE.md`](docs/USAGE.md) — every flag
|
|
125
|
+
- [`docs/USAGE.md`](docs/USAGE.md) — every flag and workflow: offline/cache control, private registries, config files, recipes, safety rails.
|
|
421
126
|
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — internals: codecs, collection, matching, report pipeline.
|
|
422
|
-
- [`
|
|
423
|
-
- [`
|
|
424
|
-
|
|
425
|
-
---
|
|
127
|
+
- [`docs/COMPARISON.md`](docs/COMPARISON.md) — vs OSV-Scanner / Trivy / Grype / OWASP DC / Snyk, and how it stays build-free.
|
|
128
|
+
- [`docs/DATA-SOURCES.md`](docs/DATA-SOURCES.md) — the public datasets fad-checker uses + their licenses.
|
|
129
|
+
- [`CHANGELOG.md`](CHANGELOG.md) · [`CLAUDE.md`](CLAUDE.md) — release history · code-level orientation for contributors.
|
|
426
130
|
|
|
427
131
|
## License
|
|
428
132
|
|