fad-checker 2.1.2 → 2.2.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/CHANGELOG.md CHANGED
@@ -3,6 +3,43 @@
3
3
  All notable changes to `fad-checker` are documented here.
4
4
  This project adheres to [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [Unreleased]
7
+
8
+ ### Added
9
+ - **Custom registries for npm, PyPI, Ruby and Go** (previously Maven-only). Point
10
+ fad-checker at private Verdaccio/Artifactory/GitHub Packages (npm), devpi (PyPI),
11
+ Gemfury/Geminabox (Ruby) or a private GOPROXY/Athens (Go). They are tried in
12
+ declared order, the public registry last; auth via `--auth user:pass` (→ Basic)
13
+ or `--token TOK` (→ Bearer), inline `https://user:pass@host/` also accepted.
14
+ CRUD: `--add-repo <eco> <name> <url>`, `--remove-repo <eco> <name>`,
15
+ `--list-repos` (grouped by ecosystem); one-off repeatable `--repo <eco>=<url>`.
16
+ New `lib/registries.js`; per-codec fetchers honour `opts.registries`.
17
+ - **Layered configuration.** Defaults can come from a JSON config file
18
+ (`--config <file.json>`, else auto-discovered `./.fad-env.json`) and from the
19
+ `FAD_CHECKER_ENV` environment variable (a string of CLI flags). Precedence:
20
+ **CLI flag > config file > `FAD_CHECKER_ENV` > `~/.fad-checker/config.json` >
21
+ defaults**; `registries` are unioned across every layer. New `lib/options-env.js`.
22
+ - **`--source` alias** for `-s`/`--src` (and the JSON config key `"source"`/`"src"`).
23
+ - **Vendored-JS inventory (report chapter 1D + JSON `vendoredJs`).** retire.js now
24
+ runs with `--verbose`, so fad lists **every** identified standalone JS library
25
+ committed into the tree (jQuery, Bootstrap, PDF.js, …) — **vulnerable or not** —
26
+ as a cyber-hygiene inventory of unmanaged third-party code (the JS twin of the
27
+ native-binary chapter 1C). Each entry: component, version, file, detection
28
+ method, and vulnerability status. Vulnerable libs remain detailed in chapter 2.
29
+ On by default; `--no-vendored-js-inventory` keeps only the vulnerable findings.
30
+ - **`--exclude-path <glob...>`** — ignore sub-paths during the directory walk,
31
+ gitignore-style (matched relative to `--src`, prunes the dir + its subtree),
32
+ across every ecosystem. Repeatable; also `excludePath: [...]` in `.fad-env.json`,
33
+ unioned across config layers. **`--no-default-excludes`** walks the normally
34
+ pruned dirs (`node_modules`, `vendor`, `target`, `.git`, …). New `lib/path-filter.js`.
35
+
36
+ ### Changed
37
+ - **BREAKING:** the persisted-registry store moved from the Maven-only
38
+ `maven_repos` config key + 2-arg `--add-repo <name> <url>` to a per-ecosystem
39
+ `registries` map + `--add-repo <ecosystem> <name> <url>`. `--repo` now requires
40
+ the `<ecosystem>=<url>` form (a bare URL is rejected). Re-add any private Maven
41
+ repos with `--add-repo maven <name> <url>`.
42
+
6
43
  ## [2.1.0]
7
44
 
8
45
  ### Added
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  > **F**ucking **A**utonomous **D**ependency **C**hecker
9
9
 
10
- `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**.
10
+ `fad-checker` scans **Maven**, **npm**, **Yarn**, **Composer (PHP)**, **PyPI (Python)**, **NuGet (C#/.NET)**, **Go**, **Ruby**, **vendored JavaScript** and **committed native binaries** 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**.
11
11
 
12
12
  🌐 **[Project site & docs →](https://n8tz.github.io/fad-checker/)**
13
13
 
@@ -15,7 +15,7 @@
15
15
 
16
16
  It 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.
17
17
 
18
- > **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`).
18
+ > **Supported ecosystems: Maven, npm, Yarn (v1 + Berry/v2+), pnpm, Composer, PyPI, NuGet, Go, Ruby + committed native binaries.** 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`). **Committed native binaries** (`.dll`/`.exe`/`.so`/`.dylib`) are detected (magic-byte confirmed, so images/assets are never picked up) and **identified by checksum** via deps.dev + CIRCL — to flag tampered/unknown files and libraries that ought to be declared dependencies (disable with `--no-binaries`).
19
19
 
20
20
  ---
21
21
 
@@ -48,8 +48,10 @@ Exactly **one** runtime dependencies must be on PATH (or installed automatically
48
48
  | **0. Warnings** | local heuristics | Missing lockfiles, unresolved Maven versions (BOM-managed), private libs not on Maven Central |
49
49
  | **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 |
50
50
  | **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 |
51
- | **2. CVE in dev deps** | same | Same, but for `test`/`provided` (Maven) and `dev`/`optional`/`peer` (npm) |
52
- | **3. Vendored JS** | [retire.js](https://retirejs.github.io/) | Old jQuery/Bootstrap/Angular/PDF.js copies sitting in `static/` or `webapp/` with no lockfile |
51
+ | **1C. Unmanaged / vendored binaries** | deps.dev + CIRCL (by checksum) | Committed **native binaries** (`.dll`/`.exe`/`.so`/`.dylib`) no package manager governs — identified by hash, flagged **should-be-managed** (exists in a registry), **name≠checksum** (filename disagrees with the hash), **unknown** (no source knows it) or **malicious** (free CIRCL signal) |
52
+ | **1D. Unmanaged / vendored JavaScript** | [retire.js](https://retirejs.github.io/) (`--verbose`) | **Inventory of every standalone JS lib** committed into the tree (jQuery, Bootstrap, PDF.js, …) that no package manager governs — vulnerable *or not*. A cyber-hygiene constat: unknown provenance/integrity/patch story. `--no-vendored-js-inventory` to skip |
53
+ | **2. Vendored JS (vulnerable)** | [retire.js](https://retirejs.github.io/) | The subset of the above with known CVEs/advisories — old jQuery/Bootstrap/Angular/PDF.js copies with no lockfile |
54
+ | **3. CVE in dev deps** | same | Same as chapter 1, but for `test`/`provided` (Maven) and `dev`/`optional`/`peer` (npm) |
53
55
  | **4. EOL frameworks** | endoflife.date | Spring Boot 2.5, Hibernate 4.x, EOL JDKs, AngularJS, Laravel/Symfony, Django, .NET, etc. |
54
56
  | **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` |
55
57
  | **6. Outdated libraries** | Maven Central + npm / Packagist / PyPI / NuGet registries | Available newer versions, with release dates |
@@ -83,9 +85,13 @@ fad-checker --set-nvd-key YOUR_KEY
83
85
  # Read-only full scan (default: all sources on)
84
86
  fad-checker -s ./proj
85
87
 
86
- # Exclude private/internal libs by groupId regex
88
+ # Exclude private/internal libs by groupId/name regex
87
89
  fad-checker -s ./proj -e "^(com\.acme|org\.private)\."
88
90
 
91
+ # Ignore whole sub-paths during the walk (gitignore-style glob, relative to -s)
92
+ fad-checker -s ./proj --exclude-path "packages/legacy/**" --exclude-path "**/fixtures/**"
93
+ fad-checker -s ./proj --no-default-excludes # walk everything (incl. node_modules/.git)
94
+
89
95
  # Also write cleaned POMs (private deps stripped, ready for Snyk)
90
96
  fad-checker -s ./proj -t ../proj-clean -e "^com\.acme\."
91
97
 
@@ -102,6 +108,12 @@ fad-checker -s ./proj --offline
102
108
  fad-checker -s ./proj --ecosystem maven # Maven only
103
109
  fad-checker -s ./proj --ecosystem maven,npm,pypi # several
104
110
  fad-checker -s ./proj --no-nuget --no-composer # or opt out per codec
111
+ fad-checker -s ./proj --no-binaries # skip the native-binary scan
112
+
113
+ # Private registry + reusable defaults (see "Configuration file & environment")
114
+ fad-checker --add-repo npm verdaccio https://npm.acme.com/ --token "$NPM_TOKEN"
115
+ fad-checker --config ./ci/fad-env.json # all options from a JSON file
116
+ fad-checker --source ./proj # --source / --src are aliases
105
117
  ```
106
118
 
107
119
  Run `fad-checker --help` for the full flag list.
@@ -184,7 +196,20 @@ fad-checker --completion zsh > ~/.zsh/completions/_fad-checker
184
196
 
185
197
  ## How it scans without any build tool
186
198
 
187
- This is the surprising bit. The whole point is that you can run `fad-checker` against a *checkout* with no build environment.
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
+ The rest of this section is the detail behind that table.
188
213
 
189
214
  - **Maven** — `pom.xml` files are parsed with xml2js. Property substitution (`${jackson.version}`), parent inheritance, local BOM imports (`<scope>import</scope>`) 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.
190
215
  - **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`.
@@ -194,8 +219,9 @@ This is the surprising bit. The whole point is that you can run `fad-checker` ag
194
219
  - **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.
195
220
  - **Ruby** — `Gemfile.lock` `specs:` give the resolved gem set. OSV "RubyGems" for recall, the RubyGems API for outdated + licenses.
196
221
  - **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.
197
- - **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.
222
+ - **Vendored JavaScript** — `retire.js` shells out (with `--verbose`) and scans `.js` / `.min.js` files by signature. Two outputs: a full **inventory of every identified standalone lib** — jQuery, Bootstrap, Angular, PDF.js copies that no lockfile knows about, *vulnerable or not* (chapter 1D, a cyber-hygiene constat on unmanaged third-party code; `--no-vendored-js-inventory` to skip) — and the **vulnerable subset** with its CVEs/advisories (chapter 2).
198
223
  - **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.)
224
+ - **Committed native binaries** — `.dll` / `.exe` / `.so` / `.dylib` files are found by a magic-byte-confirmed walk (extension **and** PE/ELF/Mach-O signature must agree, so an image renamed `.so` or any asset is rejected), hashed (SHA-1 + SHA-256), then **identified by checksum** online: **deps.dev** query-by-hash returns the exact package coordinate (so the file is byte-identical to a published artifact → *pristine*, and ought to be a declared dependency), and **CIRCL hashlookup** recognises known OS/distro/CDN/NSRL files (→ *known-good*) plus a free `KnownMalicious` flag. Files no source knows are flagged *unknown*; a filename that disagrees with the resolved identity is flagged *name≠checksum*. Reported in their own **Unmanaged / vendored binaries** chapter (1C) and the JSON export. Cached + `--offline`-aware; disable with `--no-binaries`. No malware/AV lane and no binary-metadata parsing — identity is hash-lookup, integrity is hash-comparison.
199
225
  - **CVE data** — three independent sources merged:
200
226
  - **CVEProject** (the canonical `cvelistV5` bundle, filtered to Maven-relevant entries)
201
227
  - **OSV.dev** (Google + GitHub Security Lab, multi-ecosystem)
@@ -222,6 +248,7 @@ All cached data lives in `~/.fad-checker/`:
222
248
  | CISA KEV catalogue | `kev-cache.json` | 24 h |
223
249
  | Go module proxy (latest) | `go-proxy-cache.json` | 24 h |
224
250
  | RubyGems (latest + licenses) | `rubygems-cache.json` | 24 h |
251
+ | Binary identity (deps.dev + CIRCL by hash) | `hash-id-cache.json` | 24 h |
225
252
  | endoflife.date cycles | `eol-cache.json` | 7 d |
226
253
  | Maven Central latest versions | `version-cache.json` | 24 h |
227
254
  | Transitive POMs from Maven Central | `poms-cache/<g>__<a>__<v>.pom` | ∞ (immutable) |
@@ -288,24 +315,68 @@ DB is warmed online (phase 2) and carried by `--export-cache`.
288
315
 
289
316
  ---
290
317
 
291
- ## Custom Maven repositories
318
+ ## Custom repositories & registries
292
319
 
293
- Out 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.
320
+ Out of the box `fad-checker` queries each ecosystem's **public** registry (Maven Central, registry.npmjs.org, PyPI, RubyGems, the Go module proxy). If your project pulls artifacts from a private **Nexus / Artifactory / JBoss** (Maven), **Verdaccio / GitHub Packages** (npm), **devpi / Artifactory** (PyPI), **Gemfury / Geminabox** (Ruby) or a private **GOPROXY / Athens** (Go), register them so transitive resolution, outdated checks, deprecation and license lookups work end-to-end.
321
+
322
+ Custom registries for **`maven`, `npm`, `pypi`, `ruby`, `go`**:
294
323
 
295
324
  ```bash
296
- # Persist a repo (lives in ~/.fad-checker/config.json)
297
- fad-checker --add-repo nexus https://nexus.acme.com/repository/maven-public/
298
- fad-checker --add-repo nexus-priv https://nexus.acme.com/repository/maven-private/ --auth alice:s3cr3t
299
- fad-checker --list-repos
300
- fad-checker --remove-repo nexus-priv
301
-
302
- # One-off (not persisted) — repeatable
303
- fad-checker -s ./proj --repo https://nexus.acme.com/repository/maven-public/
325
+ # Persist a registry (lives in ~/.fad-checker/config.json, keyed by ecosystem)
326
+ fad-checker --add-repo maven nexus https://nexus.acme.com/repository/maven-public/ --auth alice:s3cr3t
327
+ fad-checker --add-repo npm verdaccio https://npm.acme.com/ --token "$NPM_TOKEN"
328
+ fad-checker --add-repo pypi devpi https://pypi.acme.com/root/pypi/+simple/ --auth alice:s3cr3t
329
+ fad-checker --list-repos # grouped by ecosystem
330
+ fad-checker --remove-repo npm verdaccio
331
+
332
+ # One-off (not persisted) — repeatable, always ecosystem-scoped as <eco>=<url>
333
+ fad-checker -s ./proj --repo npm=https://npm.acme.com/ --repo maven=https://nexus.acme.com/repository/maven-public/
304
334
  # Inline auth in the URL also works:
305
- fad-checker -s ./proj --repo https://alice:s3cr3t@nexus.acme.com/repository/maven-public/
335
+ fad-checker -s ./proj --repo maven=https://alice:s3cr3t@nexus.acme.com/repository/maven-public/
306
336
  ```
307
337
 
308
- Repos are tried **in declared order, Maven Central last**. Auth is sent as a `Basic <base64>` header. POMs and `maven-metadata.xml` are cached per coord, so subsequent runs are free even against a private repo.
338
+ Registries are tried **in declared order, the public registry last**. Auth is `--auth user:pass` `Basic <base64>` or `--token TOK` `Bearer TOK` (inline `https://user:pass@host/` also works). Responses are cached per coordinate, so subsequent runs are free even against a private registry.
339
+
340
+ > **PyPI / Ruby caveat:** the custom base must expose the **same JSON API** as the public one (`<base>/<pkg>/json`, `<base>/<gem>.json`). A pure PEP 503 *simple-index* mirror that only lists files won't yield latest/yanked/license metadata — point at the JSON-capable endpoint (Artifactory/devpi/Nexus all have one). **NuGet** and **Composer** private feeds aren't supported yet (their service-index / `packages.json` discovery is a separate follow-up).
341
+
342
+ ---
343
+
344
+ ## Configuration file & environment
345
+
346
+ Don't retype flags every run. `fad-checker` reads defaults from three places, **lowest priority first**, all overridable on the command line:
347
+
348
+ | Layer | Where | Format |
349
+ | --- | --- | --- |
350
+ | **CLI flags** | the command line | flags (always win) |
351
+ | **Config file** | `--config <file.json>`, else `./.fad-env.json` | **JSON** object, keys = option names |
352
+ | **`FAD_CHECKER_ENV`** | environment variable | a **string of CLI flags** (what you'd type) |
353
+ | **Global config** | `~/.fad-checker/config.json` | persisted NVD key + `registries` |
354
+
355
+ Effective precedence: **CLI flag > config file > `FAD_CHECKER_ENV` > global config > built-in defaults.** A file/env value only fills an option you did *not* pass on the CLI; **registries are merged (unioned) across every layer**, never overridden.
356
+
357
+ ```jsonc
358
+ // ./.fad-env.json — JSON, keys mirror the CLI options (camelCase)
359
+ {
360
+ "source": "./my-project", // alias of --src (so is "src")
361
+ "exclude": "^(com\\.acme|client)\\.",
362
+ "excludePath": ["packages/legacy/**", "**/fixtures/**"],
363
+ "failOn": "high",
364
+ "noNuget": true,
365
+ "registries": {
366
+ "npm": [{ "name": "verdaccio", "url": "https://npm.acme.com/", "token": "…" }],
367
+ "maven":[{ "name": "nexus", "url": "https://nexus.acme.com/repository/maven-public/", "auth": "user:pass" }]
368
+ }
369
+ }
370
+ ```
371
+
372
+ ```bash
373
+ fad-checker --config ./ci/fad-env.json # explicit file (beats ./.fad-env.json)
374
+ FAD_CHECKER_ENV='--fail-on high --no-nuget --repo npm=https://npm.acme.com/' fad-checker -s ./proj
375
+ ```
376
+
377
+ The **source directory** accepts three spellings everywhere: `-s`, `--src`, `--source` (and the JSON key `"source"`/`"src"`).
378
+
379
+ > **`-e/--exclude` vs `--exclude-path`:** `--exclude` is a regex on the **coordinate** (groupId/name) — it drops matching *dependencies*. `--exclude-path` is a gitignore-style glob on the **directory path** (relative to `--src`) — it prunes the *walk* so nothing under it is read. They compose. `--exclude-path` is repeatable, unioned across config layers, and `--no-default-excludes` lets you walk the normally-pruned dirs (`node_modules`, `vendor`, `target`, `.git`, …).
309
380
 
310
381
  ---
311
382
 
@@ -328,6 +399,8 @@ Repos are tried **in declared order, Maven Central last**. Auth is sent as a `Ba
328
399
  | [NuGet](https://www.nuget.org/) | Latest stable + per-version `deprecation` | Free public service | `GET api.nuget.org/v3/registration5-gz-semver2/<id>/index.json` |
329
400
  | [Go module proxy](https://proxy.golang.org/) | Latest module version (outdated) | Free public service | `GET proxy.golang.org/<module>/@latest` |
330
401
  | [RubyGems](https://rubygems.org/) | Latest stable + licenses | Free public service | `GET rubygems.org/api/v1/gems/<gem>.json` |
402
+ | [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>` |
403
+ | [CIRCL hashlookup](https://hashlookup.circl.lu/) | Known-good file identity (NSRL/distro/CDN) + KnownMalicious | Free public service | `GET hashlookup.circl.lu/lookup/sha256/<hash>` |
331
404
  | [retire.js](https://retirejs.github.io/retire.js/) | Vendored-JS signature DB + scanner | Apache-2.0 | npm package `retire`, executed locally |
332
405
  | [Snyk](https://snyk.io/) (optional) | Additional CVE source via `snyk test --all-projects --json` | Per Snyk EULA; needs a Snyk account | Local CLI `snyk` |
333
406
  | [MITRE CWE](https://cwe.mitre.org/) | Weakness category links in the report | Free public reference | Linked by URL only, no API call |
@@ -355,7 +428,7 @@ of thing a security consultant or an ANSSI-PASSI engagement needs.
355
428
 
356
429
  | | **fad-checker** | OSV-Scanner | Trivy | Grype + Syft | OWASP DC | Snyk OSS |
357
430
  | --- | --- | --- | --- | --- | --- | --- |
358
- | 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 |
431
+ | 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 |
359
432
  | Reads lockfiles without `install`/build | ✅ | ✅ | ✅ | ✅ | ⚠️ Java needs Maven Central/build | ❌ build required |
360
433
  | Best-effort when **no lockfile** (pinned versions) | ✅ | ❌ | ❌ | ❌ | ⚠️ | ⚠️ |
361
434
  | Vulnerability sources | CVEProject + OSV + NVD + EPSS + KEV + retire.js (+ Snyk), merged | OSV.dev | Aqua DB | Anchore DB | NVD / CPE | Snyk DB |