fad-checker 2.2.2 → 2.2.3
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 +34 -3
- package/data/popular-packages.json +39 -0
- package/fad-checker-report/cve-report.doc +10987 -0
- package/fad-checker-report/cve-report.html +11126 -0
- package/fad-checker.js +48 -4
- package/lib/core.js +25 -3
- package/lib/cve-match.js +9 -2
- package/lib/json-export.js +5 -0
- package/lib/malware.js +100 -0
- package/lib/osv-db.js +160 -0
- package/lib/version-overlay.js +8 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
[](https://github.com/n8tz/fad-checker/blob/main/package.json)
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
|
|
8
|
-
> **F**
|
|
8
|
+
> **F**abulous **A**utonomous **D**ependency **C**hecker<br>
|
|
9
|
+
> AKA **F**uckin' **A**utonomous **D**ependency **C**hecker<br>
|
|
9
10
|
|
|
10
11
|
`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
12
|
|
|
@@ -53,6 +54,7 @@ Exactly **one** runtime dependencies must be on PATH (or installed automatically
|
|
|
53
54
|
| **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 |
|
|
54
55
|
| **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 |
|
|
55
56
|
| **3. CVE in dev deps** | same | Same as chapter 1, but for `test`/`provided` (Maven) and `dev`/`optional`/`peer` (npm) |
|
|
57
|
+
| **Supply-chain risk** | OSV `MAL-…` + name heuristic | **Known-malicious** packages (always block the CI gate, any `--fail-on` level) and **suspected typosquats** (`--typosquat`: an npm/PyPI name one edit from a popular package — `lodahs`↔`lodash`) |
|
|
56
58
|
| **4. EOL frameworks** | endoflife.date | Spring Boot 2.5, Hibernate 4.x, EOL JDKs, AngularJS, Laravel/Symfony, Django, .NET, etc. |
|
|
57
59
|
| **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` |
|
|
58
60
|
| **6. Outdated libraries** | Maven Central + npm / Packagist / PyPI / NuGet registries | Available newer versions, with release dates |
|
|
@@ -102,9 +104,17 @@ fad-checker -s ./proj -t ../proj-clean -e "^com\.acme\." --snyk
|
|
|
102
104
|
# Faster: skip Maven Central / no transitive walk
|
|
103
105
|
fad-checker -s ./proj --no-all-libs --no-transitive
|
|
104
106
|
|
|
105
|
-
# Fully offline (uses cached data only)
|
|
107
|
+
# Fully offline (uses cached data only) — zero network, guaranteed (see Air-gapped below)
|
|
106
108
|
fad-checker -s ./proj --offline
|
|
107
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
|
+
|
|
108
118
|
# License + copyleft-policy chapter (off by default)
|
|
109
119
|
fad-checker -s ./proj --licenses
|
|
110
120
|
|
|
@@ -201,6 +211,11 @@ fad-checker --completion zsh > ~/.zsh/completions/_fad-checker
|
|
|
201
211
|
|
|
202
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.
|
|
203
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
|
+
|
|
204
219
|
> Full per-ecosystem and per-stage detail lives in **[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)** and **[`docs/USAGE.md`](docs/USAGE.md)**.
|
|
205
220
|
|
|
206
221
|
---
|
|
@@ -227,6 +242,16 @@ fad-checker --import-cache fad-cache.tar.gz
|
|
|
227
242
|
|
|
228
243
|
## Air-gapped / PASSI audits: anonymized dependency descriptor
|
|
229
244
|
|
|
245
|
+
> **Zero-data-sent guarantee.** Under `--offline`, fad-checker makes **no network calls
|
|
246
|
+
> whatsoever** — it reads only the warmed `~/.fad-checker/` caches and never transmits a
|
|
247
|
+
> dependency, path or finding off the machine. It is regression-tested
|
|
248
|
+
> (`test/offline-guarantee.test.js`, a tripwire fetcher that throws if touched) and
|
|
249
|
+
> auditor-reproducible: `unshare -rn node fad-checker.js -s ./proj --offline …` runs it in a
|
|
250
|
+
> namespace with **no network interface** and yields byte-identical findings. Unlike the
|
|
251
|
+
> 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 (see
|
|
253
|
+
> `docs/USAGE.md` → *Zero-data-sent guarantee*).
|
|
254
|
+
|
|
230
255
|
When the audited system is **offline / confidential** (typical of a PASSI engagement) it
|
|
231
256
|
can't reach OSV / NVD / Maven Central / npm. Split the work across machines while keeping
|
|
232
257
|
**zero environment information** off the secure enclave: an anonymized descriptor carries
|
|
@@ -357,6 +382,7 @@ of thing a security consultant or an ANSSI-PASSI engagement needs.
|
|
|
357
382
|
| CI gating (`--fail-on`) + triage | ✅ severity/KEV + ignore/VEX | ✅ | ✅ | ✅ | ⚠️ | ✅ |
|
|
358
383
|
| Auto-remediation / PRs | ❌ (fix recipes only) | ✅ `fix` | ❌ | ❌ | ❌ | ✅ |
|
|
359
384
|
| Offline | ✅ cache | ✅ local DB | ✅ | ✅ | ✅ feed | ❌ mostly online |
|
|
385
|
+
| Offline Maven **transitive** graph³ | ✅ cached POMs | ❌ disabled offline | ❌ | ❌ | ⚠️ mirror | ❌ |
|
|
360
386
|
| **Scan without exposing the codebase**² | ✅ anonymized descriptor | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
361
387
|
| **Maven private-dep cleanup** (→ Snyk) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
362
388
|
| Output | **HTML + Word `.doc`** + JSON / SARIF / CycloneDX / CSAF | table/JSON/SARIF | table/JSON/SARIF | table/JSON/SARIF | HTML/XML/JSON | JSON / cloud UI |
|
|
@@ -367,7 +393,12 @@ of thing a security consultant or an ANSSI-PASSI engagement needs.
|
|
|
367
393
|
see [Air-gapped / PASSI](#air-gapped--passi-audits-anonymized-dependency-descriptor). OSV-Scanner
|
|
368
394
|
has an offline mode, but it still needs the **source on the scanning machine**.
|
|
369
395
|
|
|
370
|
-
|
|
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
|
|
371
402
|
presentable HTML/Word deliverable, and confidential / air-gapped engagements.
|
|
372
403
|
|
|
373
404
|
**Where it doesn't:** container/OS scanning,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Curated list of widely-used npm + PyPI packages used as TYPOSQUAT TARGETS by lib/malware.js#detectTyposquats. A resolved dep whose name is edit-distance 1 from one of these (but isn't it) is flagged as a suspected typosquat/slopsquat. Not exhaustive — focused on the most-impersonated packages. Add names here to widen proactive coverage.",
|
|
3
|
+
"npm": [
|
|
4
|
+
"react", "react-dom", "lodash", "express", "axios", "chalk", "commander", "request",
|
|
5
|
+
"debug", "async", "moment", "underscore", "jquery", "webpack", "babel-core", "vue",
|
|
6
|
+
"angular", "typescript", "eslint", "prettier", "jest", "mocha", "chai", "bluebird",
|
|
7
|
+
"yargs", "glob", "minimist", "colors", "dotenv", "body-parser", "cors", "mongoose",
|
|
8
|
+
"redux", "next", "gatsby", "rxjs", "classnames", "prop-types", "uuid", "bcrypt",
|
|
9
|
+
"jsonwebtoken", "passport", "nodemon", "node-fetch", "cross-env", "rimraf", "fs-extra",
|
|
10
|
+
"semver", "validator", "winston", "morgan", "helmet", "sequelize", "knex", "mysql",
|
|
11
|
+
"redis", "ioredis", "dayjs", "date-fns", "ramda", "immutable", "styled-components",
|
|
12
|
+
"tailwindcss", "postcss", "autoprefixer", "browserify", "rollup", "parcel", "esbuild",
|
|
13
|
+
"husky", "lint-staged", "concurrently", "nanoid", "form-data", "tslib", "core-js",
|
|
14
|
+
"socket.io", "nodemailer", "puppeteer", "playwright", "cheerio", "inquirer", "ora",
|
|
15
|
+
"execa", "chokidar", "ws", "got", "undici", "zod", "yup", "formik", "react-router",
|
|
16
|
+
"react-router-dom", "react-redux", "vuex", "pinia", "svelte", "preact", "ant-design",
|
|
17
|
+
"bootstrap", "jquery-ui", "three", "d3", "chart.js", "leaflet", "highlight.js",
|
|
18
|
+
"marked", "handlebars", "ejs", "pug", "nunjucks", "graphql", "apollo-server",
|
|
19
|
+
"mongodb", "pg", "typeorm", "prisma", "jsdom", "supertest", "sinon", "nyc", "ava",
|
|
20
|
+
"babel-loader", "ts-loader", "css-loader", "style-loader", "html-webpack-plugin",
|
|
21
|
+
"colord"
|
|
22
|
+
],
|
|
23
|
+
"pypi": [
|
|
24
|
+
"requests", "numpy", "pandas", "flask", "django", "scipy", "matplotlib", "pillow",
|
|
25
|
+
"setuptools", "wheel", "urllib3", "certifi", "pytest", "six", "click", "jinja2",
|
|
26
|
+
"werkzeug", "sqlalchemy", "boto3", "botocore", "pyyaml", "cryptography",
|
|
27
|
+
"beautifulsoup4", "lxml", "scikit-learn", "tensorflow", "keras", "scrapy",
|
|
28
|
+
"celery", "psycopg2", "pymongo", "fastapi", "uvicorn", "pydantic", "aiohttp",
|
|
29
|
+
"httpx", "tqdm", "colorama", "rich", "typer", "python-dateutil", "pytz", "attrs",
|
|
30
|
+
"packaging", "idna", "charset-normalizer", "markupsafe", "openpyxl", "tornado",
|
|
31
|
+
"gunicorn", "redis", "selenium", "paramiko", "fabric", "pyjwt", "passlib", "bcrypt",
|
|
32
|
+
"marshmallow", "flask-sqlalchemy", "flask-cors", "flask-restful", "django-rest-framework",
|
|
33
|
+
"djangorestframework", "gevent", "greenlet", "asgiref", "starlette", "anyio",
|
|
34
|
+
"httpcore", "sniffio", "wrapt", "decorator", "more-itertools", "toml", "tomli",
|
|
35
|
+
"pyparsing", "jsonschema", "protobuf", "grpcio", "boto", "awscli", "google-api-python-client",
|
|
36
|
+
"opencv-python", "imageio", "networkx", "sympy", "statsmodels", "seaborn", "plotly",
|
|
37
|
+
"dash", "streamlit", "jupyter", "ipython", "notebook", "nbconvert", "cython"
|
|
38
|
+
]
|
|
39
|
+
}
|