fad-checker 2.3.0 → 2.3.1
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 +5 -2
- package/lib/codecs/gradle.codec.js +1 -1
- package/lib/cve-report.js +1 -1
- package/lib/osv.js +19 -5
- package/lib/sarif-export.js +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/fad-checker)
|
|
4
4
|
[](https://www.npmjs.com/package/fad-checker)
|
|
5
|
-
[](https://github.com/
|
|
5
|
+
[](https://github.com/9pings/fad-checker/blob/main/package.json)
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
|
|
8
8
|
> **F**abulous **A**utonomous **D**ependency **C**hecker<br>
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
|
|
11
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.
|
|
12
12
|
|
|
13
|
-
🌐 **[Project site & docs →](https://
|
|
13
|
+
🌐 **[Project site & docs →](https://9pings.github.io/fad-checker/)**
|
|
14
|
+
|
|
15
|
+
> [!WARNING]
|
|
16
|
+
> **Young project — expect rough edges.** fad-checker is new and under active development, so it may still contain bugs (including false positives and false negatives). Treat its output as a strong first pass, **double-check anything critical**, and please [report issues](https://github.com/9pings/fad-checker/issues) — they get fixed fast.
|
|
14
17
|
|
|
15
18
|
<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>
|
|
16
19
|
|
|
@@ -129,7 +129,7 @@ module.exports = {
|
|
|
129
129
|
const lockGoverned = lockedDirs.has(d) && !inBuildSrc(fp);
|
|
130
130
|
if (lockGoverned) continue; // lockfile already provided resolved deps for this dir
|
|
131
131
|
for (const dep of r.deps) addRec(dep, fp);
|
|
132
|
-
if (!inBuildSrc(fp)) warnings.push({ type: "
|
|
132
|
+
if (!inBuildSrc(fp)) warnings.push({ type: "no-lockfile", manifestPath: fp, message: `no gradle.lockfile next to ${path.relative(dir, fp) || path.basename(fp)} — versions resolved best-effort from the build script + version catalog (dynamic/programmatic deps may be missed). Enable Gradle dependency locking for exact coverage.` });
|
|
133
133
|
for (const u of r.unresolved) warnings.push({ type: "unresolved-versions", manifestPath: fp, message: `could not resolve the version variable for ${u.group}:${u.name} (${u.raw}) — excluded from CVE matching` });
|
|
134
134
|
}
|
|
135
135
|
|
package/lib/cve-report.js
CHANGED
|
@@ -1188,7 +1188,7 @@ function minorSection(title, contentHtml, opts = {}) {
|
|
|
1188
1188
|
}
|
|
1189
1189
|
|
|
1190
1190
|
const WARNING_HEADINGS = {
|
|
1191
|
-
"no-lockfile": { icon: "⚠️", title: "
|
|
1191
|
+
"no-lockfile": { icon: "⚠️", title: "Manifest without a lockfile — best-effort (ranges skipped)" },
|
|
1192
1192
|
"yarn-berry-unsupported": { icon: "⚠️", title: "Yarn 2+/Berry lockfile" },
|
|
1193
1193
|
"unresolved-versions": { icon: "⚠️", title: "Maven deps without a concrete version — silently skipped, run a real Maven/Snyk scan to complete" },
|
|
1194
1194
|
"private-libs": { icon: "🔒", title: "Private / internal libraries — not on Maven Central, not scanned" },
|
package/lib/osv.js
CHANGED
|
@@ -121,18 +121,32 @@ function severityFromOsv(vuln) {
|
|
|
121
121
|
|
|
122
122
|
function scoreFromVuln(vuln) { return cvssInfoFromVuln(vuln).score; }
|
|
123
123
|
|
|
124
|
-
/**
|
|
125
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Pick the fix version to recommend from OSV's affected ranges. A multi-branch advisory
|
|
126
|
+
* (e.g. Tomcat fixed in 9.0.118, 10.1.55 AND 11.0.22) lists one `fixed` per branch — the
|
|
127
|
+
* old code returned the FIRST, which for an 11.0.21 dep meant "upgrade to 9.0.118", i.e. a
|
|
128
|
+
* DOWNGRADE. Instead pick the smallest fix strictly ABOVE the current version: that's the
|
|
129
|
+
* next patched release on the dep's own branch. If none is greater (the branch has no
|
|
130
|
+
* published fix, or the dep is already patched), return null rather than suggest a downgrade.
|
|
131
|
+
*/
|
|
132
|
+
function fixVersionFromOsv(vuln, depKey, depVersion) {
|
|
133
|
+
const { compareMavenVersions } = require("./maven-version");
|
|
134
|
+
const fixes = [];
|
|
126
135
|
for (const a of vuln.affected || []) {
|
|
127
136
|
const name = a.package?.name?.toLowerCase();
|
|
128
137
|
if (name && name !== depKey.toLowerCase()) continue;
|
|
129
138
|
for (const r of a.ranges || []) {
|
|
130
139
|
for (const ev of r.events || []) {
|
|
131
|
-
if (ev.fixed)
|
|
140
|
+
if (ev.fixed) fixes.push(String(ev.fixed));
|
|
132
141
|
}
|
|
133
142
|
}
|
|
134
143
|
}
|
|
135
|
-
return null;
|
|
144
|
+
if (!fixes.length) return null;
|
|
145
|
+
const cmp = (x, y) => { try { return compareMavenVersions(x, y); } catch { return String(x).localeCompare(String(y)); } };
|
|
146
|
+
const sorted = [...fixes].sort(cmp);
|
|
147
|
+
if (!depVersion) return sorted[0]; // no current version to compare against → lowest published fix
|
|
148
|
+
const upgrades = sorted.filter(f => cmp(f, depVersion) > 0);
|
|
149
|
+
return upgrades.length ? upgrades[0] : null;
|
|
136
150
|
}
|
|
137
151
|
|
|
138
152
|
/** Pick the best CVE id from an OSV vuln (prefer CVE-* aliases over GHSA-*). */
|
|
@@ -188,7 +202,7 @@ function vulnToMatch(dep, vuln) {
|
|
|
188
202
|
...(cvss.version ? { cvssVersion: `CVSS:${cvss.version}` } : {}),
|
|
189
203
|
description,
|
|
190
204
|
summary,
|
|
191
|
-
fixVersion: fixVersionFromOsv(vuln, osvPkgName(dep)),
|
|
205
|
+
fixVersion: fixVersionFromOsv(vuln, osvPkgName(dep), dep.version),
|
|
192
206
|
ghsa: (vuln.aliases || []).find(a => a.startsWith("GHSA-")) || (vuln.id?.startsWith("GHSA-") ? vuln.id : null),
|
|
193
207
|
published: vuln.published || null,
|
|
194
208
|
modified: vuln.modified || null,
|
package/lib/sarif-export.js
CHANGED
|
@@ -116,7 +116,7 @@ function buildSarif(matches, opts = {}) {
|
|
|
116
116
|
driver: {
|
|
117
117
|
name: "fad-checker",
|
|
118
118
|
version: String(toolVersion),
|
|
119
|
-
informationUri: "https://github.com/
|
|
119
|
+
informationUri: "https://github.com/9pings/fad-checker",
|
|
120
120
|
rules: [...rulesById.values()],
|
|
121
121
|
},
|
|
122
122
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fad-checker",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "Scan ALL Maven, Gradle, npm, Yarn, Composer, Python, C#/.NET, Go & Ruby dependencies — plus embedded JARs (fat-jars/war/ear) — in a source tree ONE SHOT without mvn/python/etc — CVE (EPSS/KEV-prioritised), EOL, obsolete, outdated & licenses, with SBOM/CSAF/SARIF/JSON exports, CI gating and fix recos",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sca",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"cli"
|
|
46
46
|
],
|
|
47
47
|
"license": "MIT",
|
|
48
|
-
"repository": "https://github.com/
|
|
49
|
-
"homepage": "https://github.com/
|
|
50
|
-
"bugs": "https://github.com/
|
|
48
|
+
"repository": "https://github.com/9pings/fad-checker",
|
|
49
|
+
"homepage": "https://github.com/9pings/fad-checker#readme",
|
|
50
|
+
"bugs": "https://github.com/9pings/fad-checker/issues",
|
|
51
51
|
"author": "pp9Ping <pp9Ping@gmail.com>",
|
|
52
52
|
"maintainers": [
|
|
53
53
|
"pp9Ping <pp9Ping@gmail.com>"
|