@vyuhlabs/dxkit 2.3.1 → 2.4.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 +187 -0
- package/README.md +34 -19
- package/dist/analyzers/bom/index.d.ts.map +1 -1
- package/dist/analyzers/bom/index.js +85 -2
- package/dist/analyzers/bom/index.js.map +1 -1
- package/dist/analyzers/bom/pm-signals.d.ts +63 -0
- package/dist/analyzers/bom/pm-signals.d.ts.map +1 -0
- package/dist/analyzers/bom/pm-signals.js +200 -0
- package/dist/analyzers/bom/pm-signals.js.map +1 -0
- package/dist/analyzers/bom/types.d.ts +11 -0
- package/dist/analyzers/bom/types.d.ts.map +1 -1
- package/dist/analyzers/security/gather.d.ts.map +1 -1
- package/dist/analyzers/security/gather.js +15 -0
- package/dist/analyzers/security/gather.js.map +1 -1
- package/dist/analyzers/tools/fingerprint.d.ts +63 -0
- package/dist/analyzers/tools/fingerprint.d.ts.map +1 -0
- package/dist/analyzers/tools/fingerprint.js +82 -0
- package/dist/analyzers/tools/fingerprint.js.map +1 -0
- package/dist/analyzers/tools/osv-scanner-fix.d.ts +63 -0
- package/dist/analyzers/tools/osv-scanner-fix.d.ts.map +1 -0
- package/dist/analyzers/tools/osv-scanner-fix.js +202 -0
- package/dist/analyzers/tools/osv-scanner-fix.js.map +1 -0
- package/dist/analyzers/tools/semver-bump.d.ts +17 -0
- package/dist/analyzers/tools/semver-bump.d.ts.map +1 -0
- package/dist/analyzers/tools/semver-bump.js +30 -0
- package/dist/analyzers/tools/semver-bump.js.map +1 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
- package/dist/analyzers/tools/tool-registry.js +20 -0
- package/dist/analyzers/tools/tool-registry.js.map +1 -1
- package/dist/analyzers/tools/upgrade-plan-resolver.d.ts +64 -0
- package/dist/analyzers/tools/upgrade-plan-resolver.d.ts.map +1 -0
- package/dist/analyzers/tools/upgrade-plan-resolver.js +146 -0
- package/dist/analyzers/tools/upgrade-plan-resolver.js.map +1 -0
- package/dist/analyzers/xlsx/bom.d.ts +29 -18
- package/dist/analyzers/xlsx/bom.d.ts.map +1 -1
- package/dist/analyzers/xlsx/bom.js +386 -71
- package/dist/analyzers/xlsx/bom.js.map +1 -1
- package/dist/languages/capabilities/types.d.ts +46 -2
- package/dist/languages/capabilities/types.d.ts.map +1 -1
- package/dist/languages/csharp.d.ts +33 -0
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +77 -38
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +13 -0
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +17 -1
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +12 -1
- package/dist/languages/typescript.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PM-oriented derived signals for bom renderers (2.3.2).
|
|
4
|
+
*
|
|
5
|
+
* Pure helpers that project raw finding fields into categorical
|
|
6
|
+
* signals a non-technical reviewer can sort/filter/decide on without
|
|
7
|
+
* domain expertise:
|
|
8
|
+
*
|
|
9
|
+
* - `licenseClass(licenseType)` — SPDX-id → permissive / copyleft-
|
|
10
|
+
* weak / copyleft-strong / proprietary / unknown. Lets a PM
|
|
11
|
+
* filter the inventory for "anything I need a lawyer to sign off".
|
|
12
|
+
*
|
|
13
|
+
* - `stalenessTier(releaseDate)` — ISO date → fresh (< 1y) / aging
|
|
14
|
+
* (1–3y) / stale (≥ 3y). Lets a PM see deps that may no longer
|
|
15
|
+
* be maintained without knowing semver or npm-registry API.
|
|
16
|
+
*
|
|
17
|
+
* - `effortEstimate(entry)` — packs the entry's upgrade path into
|
|
18
|
+
* trivial / moderate / major / blocked. Derived from
|
|
19
|
+
* installedVersion → fixedVersion semver delta or "no fix available".
|
|
20
|
+
* Helps scope sprint commitments.
|
|
21
|
+
*
|
|
22
|
+
* These deliberately live OUTSIDE `capabilities/types.ts` so the
|
|
23
|
+
* finding types stay the analyzer contract and these are strictly
|
|
24
|
+
* rendering helpers. If downstream consumers later need them in the
|
|
25
|
+
* JSON output, they can be promoted to type fields in a minor bump.
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.licenseClass = licenseClass;
|
|
29
|
+
exports.stalenessTier = stalenessTier;
|
|
30
|
+
exports.effortEstimate = effortEstimate;
|
|
31
|
+
/** Known-permissive SPDX ids. Matching is forgiving — `MIT`, `MIT license`,
|
|
32
|
+
* `MIT (fork)` all map to the same class. Bench xlsx was full of
|
|
33
|
+
* human-readable suffixes; this logic normalises them away. */
|
|
34
|
+
const PERMISSIVE = new Set([
|
|
35
|
+
'mit',
|
|
36
|
+
'mit-0',
|
|
37
|
+
'apache-2.0',
|
|
38
|
+
'apache 2.0',
|
|
39
|
+
'apache-1.1',
|
|
40
|
+
'bsd',
|
|
41
|
+
'bsd-2-clause',
|
|
42
|
+
'bsd-3-clause',
|
|
43
|
+
'bsd-3-clause-clear',
|
|
44
|
+
'0bsd',
|
|
45
|
+
'isc',
|
|
46
|
+
'zlib',
|
|
47
|
+
'unlicense',
|
|
48
|
+
'cc0-1.0',
|
|
49
|
+
'wtfpl',
|
|
50
|
+
'python-2.0',
|
|
51
|
+
'python',
|
|
52
|
+
'psf-2.0',
|
|
53
|
+
'artistic-2.0',
|
|
54
|
+
'artistic-1.0',
|
|
55
|
+
'boost',
|
|
56
|
+
'bsl-1.0',
|
|
57
|
+
'upl-1.0', // Universal Permissive License
|
|
58
|
+
]);
|
|
59
|
+
const COPYLEFT_STRONG = new Set([
|
|
60
|
+
'gpl-2.0',
|
|
61
|
+
'gpl-3.0',
|
|
62
|
+
'gpl',
|
|
63
|
+
'agpl-3.0',
|
|
64
|
+
'agpl-1.0',
|
|
65
|
+
'agpl',
|
|
66
|
+
'sspl-1.0',
|
|
67
|
+
]);
|
|
68
|
+
const COPYLEFT_WEAK = new Set([
|
|
69
|
+
'lgpl-2.1',
|
|
70
|
+
'lgpl-3.0',
|
|
71
|
+
'lgpl',
|
|
72
|
+
'mpl-1.1',
|
|
73
|
+
'mpl-2.0',
|
|
74
|
+
'epl-1.0',
|
|
75
|
+
'epl-2.0',
|
|
76
|
+
'cddl-1.0',
|
|
77
|
+
'cddl-1.1',
|
|
78
|
+
]);
|
|
79
|
+
const PROPRIETARY_MARKERS = ['UNLICENSED', 'SEE LICENSE IN', 'PROPRIETARY', 'COMMERCIAL'];
|
|
80
|
+
/**
|
|
81
|
+
* Classify a license string from a `LicenseFinding`. Accepts raw SPDX
|
|
82
|
+
* ids, compound expressions (`"MIT OR Apache-2.0"` — classifies by the
|
|
83
|
+
* first recognised token), and human-readable variants. Unrecognised
|
|
84
|
+
* input returns `'unknown'` so the caller can surface the raw string
|
|
85
|
+
* for human review.
|
|
86
|
+
*/
|
|
87
|
+
function licenseClass(licenseType) {
|
|
88
|
+
if (!licenseType || licenseType === 'UNKNOWN' || licenseType.trim().length === 0) {
|
|
89
|
+
return 'unknown';
|
|
90
|
+
}
|
|
91
|
+
const upper = licenseType.toUpperCase();
|
|
92
|
+
for (const marker of PROPRIETARY_MARKERS) {
|
|
93
|
+
if (upper.includes(marker))
|
|
94
|
+
return 'proprietary';
|
|
95
|
+
}
|
|
96
|
+
// Compound expressions: split on OR/AND, classify each, take the
|
|
97
|
+
// strictest class (copyleft > permissive > unknown). Prevents an
|
|
98
|
+
// `MIT OR GPL-3.0` from reading as harmless MIT when the user can
|
|
99
|
+
// also be tied to GPL obligations. Strip surrounding punctuation
|
|
100
|
+
// (parens/brackets) that license-checker sometimes emits on
|
|
101
|
+
// compound expressions like `(Apache-2.0 OR UPL-1.0)`.
|
|
102
|
+
const cleaned = licenseType.replace(/[()[\]{}]/g, ' ').trim();
|
|
103
|
+
const tokens = cleaned
|
|
104
|
+
.split(/\s+(?:OR|AND|\/|\|)\s+|\s+license\s*$/i)
|
|
105
|
+
.map((t) => t
|
|
106
|
+
.trim()
|
|
107
|
+
.toLowerCase()
|
|
108
|
+
.replace(/^apache\s+/, 'apache-')
|
|
109
|
+
.replace(/\s+/g, '-'))
|
|
110
|
+
.filter(Boolean);
|
|
111
|
+
let worst = 'unknown';
|
|
112
|
+
for (const norm of tokens) {
|
|
113
|
+
if (COPYLEFT_STRONG.has(norm))
|
|
114
|
+
return 'copyleft-strong';
|
|
115
|
+
if (COPYLEFT_WEAK.has(norm))
|
|
116
|
+
worst = 'copyleft-weak';
|
|
117
|
+
else if (PERMISSIVE.has(norm) && worst === 'unknown')
|
|
118
|
+
worst = 'permissive';
|
|
119
|
+
}
|
|
120
|
+
return worst;
|
|
121
|
+
}
|
|
122
|
+
const YEAR_MS = 365 * 24 * 60 * 60 * 1000;
|
|
123
|
+
/**
|
|
124
|
+
* Classify package freshness from an ISO-8601 release date. Threshold
|
|
125
|
+
* picked for PM sensibility: "< 1 year" is current, "1–3 years" starts
|
|
126
|
+
* getting stale, "≥ 3 years" warrants a "still maintained?" conversation.
|
|
127
|
+
*
|
|
128
|
+
* `now` is injectable so tests don't drift over time.
|
|
129
|
+
*/
|
|
130
|
+
function stalenessTier(releaseDate, now = new Date()) {
|
|
131
|
+
if (!releaseDate)
|
|
132
|
+
return 'unknown';
|
|
133
|
+
const t = Date.parse(releaseDate);
|
|
134
|
+
if (Number.isNaN(t))
|
|
135
|
+
return 'unknown';
|
|
136
|
+
const ageMs = now.getTime() - t;
|
|
137
|
+
if (ageMs < YEAR_MS)
|
|
138
|
+
return 'fresh';
|
|
139
|
+
if (ageMs < 3 * YEAR_MS)
|
|
140
|
+
return 'aging';
|
|
141
|
+
return 'stale';
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Estimate the effort to remediate a vulnerable package.
|
|
145
|
+
*
|
|
146
|
+
* - `blocked`: no advisory has a `fixedVersion` → requires a drop-in
|
|
147
|
+
* replacement or living-with-it exception.
|
|
148
|
+
* - `trivial`: every advisory's fix is a patch-version bump (same
|
|
149
|
+
* major+minor). Low-risk npm install away.
|
|
150
|
+
* - `moderate`: fix is a minor-version bump (same major). API-additive;
|
|
151
|
+
* contract-stable but light testing warranted.
|
|
152
|
+
* - `major`: fix is a major-version bump. Potential breaking changes;
|
|
153
|
+
* read the changelog before committing.
|
|
154
|
+
*
|
|
155
|
+
* Extracts semver by numeric parse of the first three dotted components
|
|
156
|
+
* (strips a leading `v` Go-style). Non-parseable or multi-vuln mixtures
|
|
157
|
+
* escalate to the highest effort tier seen.
|
|
158
|
+
*/
|
|
159
|
+
function effortEstimate(entry) {
|
|
160
|
+
if (entry.vulns.length === 0)
|
|
161
|
+
return 'trivial'; // unreachable under normal rendering
|
|
162
|
+
const installed = parseSemverTriple(entry.version);
|
|
163
|
+
let worst = 'trivial';
|
|
164
|
+
let anyFixMissing = false;
|
|
165
|
+
for (const v of entry.vulns) {
|
|
166
|
+
if (!v.fixedVersion) {
|
|
167
|
+
anyFixMissing = true;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const fix = parseSemverTriple(v.fixedVersion);
|
|
171
|
+
if (!installed || !fix) {
|
|
172
|
+
worst = worstOf(worst, 'major');
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (fix[0] > installed[0])
|
|
176
|
+
worst = worstOf(worst, 'major');
|
|
177
|
+
else if (fix[1] > installed[1])
|
|
178
|
+
worst = worstOf(worst, 'moderate');
|
|
179
|
+
// patch bumps or lower stay 'trivial'
|
|
180
|
+
}
|
|
181
|
+
if (anyFixMissing)
|
|
182
|
+
return 'blocked';
|
|
183
|
+
return worst;
|
|
184
|
+
}
|
|
185
|
+
function parseSemverTriple(v) {
|
|
186
|
+
const stripped = v.replace(/^v/, '');
|
|
187
|
+
const parts = stripped.split(/[.+-]/).slice(0, 3).map(Number);
|
|
188
|
+
if (parts.length < 3 || parts.some(Number.isNaN))
|
|
189
|
+
return null;
|
|
190
|
+
return parts;
|
|
191
|
+
}
|
|
192
|
+
function worstOf(a, b) {
|
|
193
|
+
const rank = {
|
|
194
|
+
trivial: 0,
|
|
195
|
+
moderate: 1,
|
|
196
|
+
major: 2,
|
|
197
|
+
};
|
|
198
|
+
return rank[a] >= rank[b] ? a : b;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=pm-signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm-signals.js","sourceRoot":"","sources":["../../../src/analyzers/bom/pm-signals.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,6 +115,17 @@ export interface BomReport {
|
|
|
115
115
|
* distinct. When nested scan is disabled or only one root was
|
|
116
116
|
* found, this is `["."]` so consumers can treat it uniformly. */
|
|
117
117
|
projectRoots: string[];
|
|
118
|
+
/** Sorted, deduplicated list of every advisory `fingerprint`
|
|
119
|
+
* covered by this report. Each fingerprint is a stable hash of
|
|
120
|
+
* `(package, installedVersion, id)` stamped by the cross-pack
|
|
121
|
+
* dep-vuln aggregator. Consumers diff two reports by set
|
|
122
|
+
* difference on this list — added fingerprints are new
|
|
123
|
+
* advisories, removed ones are resolved. The per-finding
|
|
124
|
+
* fingerprint also lives on each `BomEntry.vulns[].fingerprint`
|
|
125
|
+
* for attribution; this field is a convenience manifest so
|
|
126
|
+
* external tooling (suppressions, CI gates, upgrade bots) can
|
|
127
|
+
* diff without walking every entry. */
|
|
128
|
+
fingerprints: string[];
|
|
118
129
|
};
|
|
119
130
|
entries: ReadonlyArray<BomEntry>;
|
|
120
131
|
toolsUsed: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/analyzers/bom/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjE,MAAM,WAAW,QAAQ;IAEvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAGhB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,KAAK,EAAE,cAAc,EAAE,CAAC;IAExB;uEACmE;IACnE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAEhC;;;gDAG4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;oEAIgE;IAChE,cAAc,EAAE,OAAO,CAAC;IAExB;;;;;mEAK+D;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;mBAQe;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,WAAW,EAAE,WAAW,CAAC;IACzB;wEACoE;IACpE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,aAAa,EAAE,GAAG,CAAC;IACnB,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB;;qCAE6B;QAC7B,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACxC;;sDAE8C;QAC9C,kBAAkB,EAAE,MAAM,CAAC;QAC3B;oEAC4D;QAC5D,eAAe,EAAE,MAAM,CAAC;QACxB;;;2DAGmD;QACnD,eAAe,EAAE,MAAM,CAAC;QACxB;wDACgD;QAChD,gBAAgB,EAAE,MAAM,CAAC;QACzB;;;;;oEAK4D;QAC5D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QACjD;wEACgE;QAChE,MAAM,EAAE,KAAK,GAAG,WAAW,CAAC;QAC5B;;;mCAG2B;QAC3B,uBAAuB,EAAE,MAAM,CAAC;QAChC;;;0EAGkE;QAClE,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/analyzers/bom/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjE,MAAM,WAAW,QAAQ;IAEvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAGhB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,KAAK,EAAE,cAAc,EAAE,CAAC;IAExB;uEACmE;IACnE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAEhC;;;gDAG4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;oEAIgE;IAChE,cAAc,EAAE,OAAO,CAAC;IAExB;;;;;mEAK+D;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;mBAQe;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,WAAW,EAAE,WAAW,CAAC;IACzB;wEACoE;IACpE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,aAAa,EAAE,GAAG,CAAC;IACnB,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB;;qCAE6B;QAC7B,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACxC;;sDAE8C;QAC9C,kBAAkB,EAAE,MAAM,CAAC;QAC3B;oEAC4D;QAC5D,eAAe,EAAE,MAAM,CAAC;QACxB;;;2DAGmD;QACnD,eAAe,EAAE,MAAM,CAAC;QACxB;wDACgD;QAChD,gBAAgB,EAAE,MAAM,CAAC;QACzB;;;;;oEAK4D;QAC5D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QACjD;wEACgE;QAChE,MAAM,EAAE,KAAK,GAAG,WAAW,CAAC;QAC5B;;;mCAG2B;QAC3B,uBAAuB,EAAE,MAAM,CAAC;QAChC;;;0EAGkE;QAClE,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB;;;;;;;;;gDASwC;QACxC,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../../src/analyzers/security/gather.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../../src/analyzers/security/gather.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAe1D;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACxD,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC,CAeD;AAID,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAuCjE;AAID;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7D,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC,CAeD;AAcD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAuGzE"}
|
|
@@ -15,10 +15,12 @@ exports.gatherDepVulns = gatherDepVulns;
|
|
|
15
15
|
*/
|
|
16
16
|
const runner_1 = require("../tools/runner");
|
|
17
17
|
const epss_1 = require("../tools/epss");
|
|
18
|
+
const fingerprint_1 = require("../tools/fingerprint");
|
|
18
19
|
const kev_1 = require("../tools/kev");
|
|
19
20
|
const osv_1 = require("../tools/osv");
|
|
20
21
|
const reachability_1 = require("../tools/reachability");
|
|
21
22
|
const risk_score_1 = require("../tools/risk-score");
|
|
23
|
+
const upgrade_plan_resolver_1 = require("../tools/upgrade-plan-resolver");
|
|
22
24
|
const exclusions_1 = require("../tools/exclusions");
|
|
23
25
|
const dispatcher_1 = require("../dispatcher");
|
|
24
26
|
const languages_1 = require("../../languages");
|
|
@@ -154,6 +156,11 @@ async function gatherDepVulns(cwd) {
|
|
|
154
156
|
// alias list including the CVE. One OSV roundtrip resolves the
|
|
155
157
|
// whole batch; one EPSS roundtrip scores them all.
|
|
156
158
|
const findings = envelope.findings ?? [];
|
|
159
|
+
// Stamp durable identity on every finding before enrichment. The hash
|
|
160
|
+
// inputs are package/version/id only, so stamping is independent of
|
|
161
|
+
// EPSS/KEV/reachability results — keeps `fingerprint` stable across
|
|
162
|
+
// runs even if enrichment tooling changes underneath.
|
|
163
|
+
(0, fingerprint_1.stampFingerprints)(findings);
|
|
157
164
|
if (findings.length > 0) {
|
|
158
165
|
const cveByFinding = new Map();
|
|
159
166
|
const needsAliasLookup = [];
|
|
@@ -204,6 +211,14 @@ async function gatherDepVulns(cwd) {
|
|
|
204
211
|
(0, reachability_1.markReachable)(findings, reachable);
|
|
205
212
|
}
|
|
206
213
|
}
|
|
214
|
+
// Cross-pack upgrade-plan resolver (Phase 10h.6.4). Runs after
|
|
215
|
+
// per-pack Tier-2 tools have stamped what they can, and before
|
|
216
|
+
// risk scoring so the composite riskScore can factor in the
|
|
217
|
+
// "actionable" bit (future 10h.9.2 CI gate uses it too). Fills
|
|
218
|
+
// gaps by (a) reconciling advisories across plans' `patches[]`
|
|
219
|
+
// lists and (b) parsing the npm-audit transitive-fix free-text
|
|
220
|
+
// template into a structured plan when no tool produced one.
|
|
221
|
+
(0, upgrade_plan_resolver_1.resolveTransitiveUpgradePlans)(findings);
|
|
207
222
|
// Composite riskScore = f(cvss, epss, kev, reachable). Runs last
|
|
208
223
|
// so every signal is populated. Formula is documented in
|
|
209
224
|
// risk-score.ts; skipped for findings without CVSS so we don't
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../src/analyzers/security/gather.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../src/analyzers/security/gather.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advisory fingerprints — durable per-finding identity across runs.
|
|
3
|
+
*
|
|
4
|
+
* The dispatcher's dep-vuln aggregator (src/analyzers/security/gather.ts)
|
|
5
|
+
* stamps every finding with a stable hash of `(package, installedVersion,
|
|
6
|
+
* id)` before scoring + reporting. The same advisory against the same
|
|
7
|
+
* installed version produces the same fingerprint on every run, so
|
|
8
|
+
* consumers (agent-driven upgrade bots, suppressions, CI gates) can diff
|
|
9
|
+
* a current bom against a stored prior to detect:
|
|
10
|
+
*
|
|
11
|
+
* - new advisories (fingerprint present now, absent before)
|
|
12
|
+
* - resolved advisories (fingerprint absent now, present before)
|
|
13
|
+
* - unchanged advisories (fingerprint in both sets)
|
|
14
|
+
*
|
|
15
|
+
* Excluded from the hash:
|
|
16
|
+
* - severity / cvssScore — re-scoring the same advisory against the
|
|
17
|
+
* same install must not mint a new identity
|
|
18
|
+
* - enrichment fields (epssScore, kev, reachable, riskScore) — same
|
|
19
|
+
* reason; these are signals about the advisory, not part of it
|
|
20
|
+
* - producer `tool` — the same advisory hit by two producers (e.g.
|
|
21
|
+
* npm-audit + snyk) should collapse to one identity
|
|
22
|
+
* - `upgradeAdvice` / `upgradePlan` — resolution suggestions change
|
|
23
|
+
* across releases of the fix tooling; identity must outlive them
|
|
24
|
+
*
|
|
25
|
+
* Format: 16-char lowercase hex (first 8 bytes of SHA-1). Short enough
|
|
26
|
+
* to embed inline in reports, long enough to make collisions between
|
|
27
|
+
* non-identical tuples effectively impossible for repo-scale sets.
|
|
28
|
+
*/
|
|
29
|
+
import type { DepVulnFinding } from '../../languages/capabilities/types';
|
|
30
|
+
/**
|
|
31
|
+
* Stable 16-char hex fingerprint for one DepVulnFinding. Input tuple
|
|
32
|
+
* is NUL-separated (not present in any legal package / version / id)
|
|
33
|
+
* so distinct tuples can never collide via concatenation tricks.
|
|
34
|
+
*
|
|
35
|
+
* `installedVersion` is normalized to the empty string when absent so
|
|
36
|
+
* version-less findings (rare — some providers omit it when the lock
|
|
37
|
+
* file is missing) still get a deterministic fingerprint instead of
|
|
38
|
+
* mixing an ambient `undefined` into the hash input.
|
|
39
|
+
*/
|
|
40
|
+
export declare function computeFingerprint(finding: Pick<DepVulnFinding, 'package' | 'installedVersion' | 'id'>): string;
|
|
41
|
+
/**
|
|
42
|
+
* Stamp `fingerprint` on every finding in place. Called once in
|
|
43
|
+
* `gatherDepVulns` after cross-pack merge + enrichment so every
|
|
44
|
+
* downstream consumer (bom, security/detailed, JSON export) sees a
|
|
45
|
+
* fully-stamped finding.
|
|
46
|
+
*
|
|
47
|
+
* Idempotent: re-stamping a finding that already has a fingerprint
|
|
48
|
+
* overwrites it with the same value. Safe to call multiple times,
|
|
49
|
+
* though the gather path only invokes it once.
|
|
50
|
+
*/
|
|
51
|
+
export declare function stampFingerprints(findings: DepVulnFinding[]): void;
|
|
52
|
+
/**
|
|
53
|
+
* Sorted, deduplicated fingerprint list for a set of findings. Used by
|
|
54
|
+
* `analyzeBom` to populate `BomReport.summary.fingerprints` — a single
|
|
55
|
+
* manifest of every advisory identity the report covers, convenient
|
|
56
|
+
* for external diff tooling without walking `entries[].vulns[]`.
|
|
57
|
+
*
|
|
58
|
+
* Silently skips findings missing a fingerprint (should not happen
|
|
59
|
+
* post-gather, but a safety net against a future producer that emits
|
|
60
|
+
* findings outside the `gatherDepVulns` path).
|
|
61
|
+
*/
|
|
62
|
+
export declare function collectFingerprints(findings: ReadonlyArray<DepVulnFinding>): string[];
|
|
63
|
+
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,kBAAkB,GAAG,IAAI,CAAC,GACnE,MAAM,CAGR;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAIlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,MAAM,EAAE,CAMrF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Advisory fingerprints — durable per-finding identity across runs.
|
|
4
|
+
*
|
|
5
|
+
* The dispatcher's dep-vuln aggregator (src/analyzers/security/gather.ts)
|
|
6
|
+
* stamps every finding with a stable hash of `(package, installedVersion,
|
|
7
|
+
* id)` before scoring + reporting. The same advisory against the same
|
|
8
|
+
* installed version produces the same fingerprint on every run, so
|
|
9
|
+
* consumers (agent-driven upgrade bots, suppressions, CI gates) can diff
|
|
10
|
+
* a current bom against a stored prior to detect:
|
|
11
|
+
*
|
|
12
|
+
* - new advisories (fingerprint present now, absent before)
|
|
13
|
+
* - resolved advisories (fingerprint absent now, present before)
|
|
14
|
+
* - unchanged advisories (fingerprint in both sets)
|
|
15
|
+
*
|
|
16
|
+
* Excluded from the hash:
|
|
17
|
+
* - severity / cvssScore — re-scoring the same advisory against the
|
|
18
|
+
* same install must not mint a new identity
|
|
19
|
+
* - enrichment fields (epssScore, kev, reachable, riskScore) — same
|
|
20
|
+
* reason; these are signals about the advisory, not part of it
|
|
21
|
+
* - producer `tool` — the same advisory hit by two producers (e.g.
|
|
22
|
+
* npm-audit + snyk) should collapse to one identity
|
|
23
|
+
* - `upgradeAdvice` / `upgradePlan` — resolution suggestions change
|
|
24
|
+
* across releases of the fix tooling; identity must outlive them
|
|
25
|
+
*
|
|
26
|
+
* Format: 16-char lowercase hex (first 8 bytes of SHA-1). Short enough
|
|
27
|
+
* to embed inline in reports, long enough to make collisions between
|
|
28
|
+
* non-identical tuples effectively impossible for repo-scale sets.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.computeFingerprint = computeFingerprint;
|
|
32
|
+
exports.stampFingerprints = stampFingerprints;
|
|
33
|
+
exports.collectFingerprints = collectFingerprints;
|
|
34
|
+
const crypto_1 = require("crypto");
|
|
35
|
+
/**
|
|
36
|
+
* Stable 16-char hex fingerprint for one DepVulnFinding. Input tuple
|
|
37
|
+
* is NUL-separated (not present in any legal package / version / id)
|
|
38
|
+
* so distinct tuples can never collide via concatenation tricks.
|
|
39
|
+
*
|
|
40
|
+
* `installedVersion` is normalized to the empty string when absent so
|
|
41
|
+
* version-less findings (rare — some providers omit it when the lock
|
|
42
|
+
* file is missing) still get a deterministic fingerprint instead of
|
|
43
|
+
* mixing an ambient `undefined` into the hash input.
|
|
44
|
+
*/
|
|
45
|
+
function computeFingerprint(finding) {
|
|
46
|
+
const input = `${finding.package}\0${finding.installedVersion ?? ''}\0${finding.id}`;
|
|
47
|
+
return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stamp `fingerprint` on every finding in place. Called once in
|
|
51
|
+
* `gatherDepVulns` after cross-pack merge + enrichment so every
|
|
52
|
+
* downstream consumer (bom, security/detailed, JSON export) sees a
|
|
53
|
+
* fully-stamped finding.
|
|
54
|
+
*
|
|
55
|
+
* Idempotent: re-stamping a finding that already has a fingerprint
|
|
56
|
+
* overwrites it with the same value. Safe to call multiple times,
|
|
57
|
+
* though the gather path only invokes it once.
|
|
58
|
+
*/
|
|
59
|
+
function stampFingerprints(findings) {
|
|
60
|
+
for (const f of findings) {
|
|
61
|
+
f.fingerprint = computeFingerprint(f);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Sorted, deduplicated fingerprint list for a set of findings. Used by
|
|
66
|
+
* `analyzeBom` to populate `BomReport.summary.fingerprints` — a single
|
|
67
|
+
* manifest of every advisory identity the report covers, convenient
|
|
68
|
+
* for external diff tooling without walking `entries[].vulns[]`.
|
|
69
|
+
*
|
|
70
|
+
* Silently skips findings missing a fingerprint (should not happen
|
|
71
|
+
* post-gather, but a safety net against a future producer that emits
|
|
72
|
+
* findings outside the `gatherDepVulns` path).
|
|
73
|
+
*/
|
|
74
|
+
function collectFingerprints(findings) {
|
|
75
|
+
const set = new Set();
|
|
76
|
+
for (const f of findings) {
|
|
77
|
+
if (f.fingerprint)
|
|
78
|
+
set.add(f.fingerprint);
|
|
79
|
+
}
|
|
80
|
+
return [...set].sort();
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;AAeH,gDAKC;AAYD,8CAIC;AAYD,kDAMC;AApDD,mCAAoC;AAGpC;;;;;;;;;GASG;AACH,SAAgB,kBAAkB,CAChC,OAAoE;IAEpE,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,gBAAgB,IAAI,EAAE,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC;IACrF,OAAO,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAAC,QAA0B;IAC1D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,CAAC,CAAC,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,QAAuC;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,WAAW;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* osv-scanner fix — Tier-2 upgrade-plan enricher for the TypeScript pack.
|
|
3
|
+
*
|
|
4
|
+
* `npm audit` (Tier-1, typescript pack's primary dep-vuln source) produces
|
|
5
|
+
* per-advisory findings with `fixedVersion` and, for transitive advisories,
|
|
6
|
+
* a free-text `upgradeAdvice` like "Upgrade vitest to 4.1.5 [major]
|
|
7
|
+
* (transitive fix)". That's good for humans reading markdown but leaves
|
|
8
|
+
* autonomous upgrade bots to re-parse the string.
|
|
9
|
+
*
|
|
10
|
+
* `osv-scanner fix --format json --manifest <pkg.json> --lockfile <lock>`
|
|
11
|
+
* produces a structured plan: for each proposed patch, which top-level
|
|
12
|
+
* package to bump (`packageUpdates[]`) and which advisories it would
|
|
13
|
+
* resolve (`fixed[]`). This module wraps that call and stamps the
|
|
14
|
+
* structured result onto each matching `DepVulnFinding.upgradePlan` —
|
|
15
|
+
* the typed sibling to the free-text `upgradeAdvice` that 10h.6.6 added.
|
|
16
|
+
*
|
|
17
|
+
* Degradation: if osv-scanner isn't installed, runs fine but returns
|
|
18
|
+
* zero enrichments. The underlying npm-audit flow populates
|
|
19
|
+
* `upgradeAdvice` either way. Downstream consumers that want the
|
|
20
|
+
* structured form check `upgradePlan` presence.
|
|
21
|
+
*/
|
|
22
|
+
import type { DepVulnFinding, DepVulnUpgradePlan } from '../../languages/capabilities/types';
|
|
23
|
+
/**
|
|
24
|
+
* Run osv-scanner against a TypeScript project and return a map keyed on
|
|
25
|
+
* the `(package, installedVersion, advisoryId)` tuple → upgradePlan. Caller
|
|
26
|
+
* iterates findings and copies the plan onto each match.
|
|
27
|
+
*
|
|
28
|
+
* Returns an empty map when:
|
|
29
|
+
* - osv-scanner binary is not available (tool missing — soft-fail)
|
|
30
|
+
* - package.json or package-lock.json is absent (osv-scanner fix needs both)
|
|
31
|
+
* - osv-scanner exits with parse-breaking output (log and degrade)
|
|
32
|
+
*
|
|
33
|
+
* Never throws. `gatherTsDepVulnsResult` calls this unconditionally and
|
|
34
|
+
* treats the empty map as "no enrichment available".
|
|
35
|
+
*/
|
|
36
|
+
export declare function gatherOsvScannerFixPlans(cwd: string): Promise<Map<string, DepVulnUpgradePlan>>;
|
|
37
|
+
/**
|
|
38
|
+
* Parse raw `osv-scanner fix --format json` stdout into a plan-lookup map.
|
|
39
|
+
*
|
|
40
|
+
* The command prefixes JSON with a warning line when it falls back to
|
|
41
|
+
* `npm install --legacy-peer-deps` (seen on 2026-04-24's dxkit sample
|
|
42
|
+
* capture); skip anything before the first `{`. On parse failure,
|
|
43
|
+
* returns an empty map rather than throwing — enrichment is best-effort.
|
|
44
|
+
*
|
|
45
|
+
* Exported for test coverage.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseOsvScannerFixOutput(raw: string): Map<string, DepVulnUpgradePlan>;
|
|
48
|
+
/**
|
|
49
|
+
* Stamp upgradePlan on every finding with a matching `(package,
|
|
50
|
+
* installedVersion, id)` tuple in the provided plan map. In-place;
|
|
51
|
+
* finds with no matching plan are left unchanged. Idempotent.
|
|
52
|
+
*/
|
|
53
|
+
export declare function enrichWithUpgradePlans(findings: DepVulnFinding[], plans: Map<string, DepVulnUpgradePlan>): number;
|
|
54
|
+
/** Shared key between plan-map construction and finding lookup.
|
|
55
|
+
*
|
|
56
|
+
* GHSA/CVE/SNYK IDs are case-insensitive per their respective specs but
|
|
57
|
+
* producers disagree in practice — npm-audit emits uppercase
|
|
58
|
+
* (`GHSA-W5HQ-...`), osv-scanner emits lowercase (`GHSA-w5hq-...`).
|
|
59
|
+
* Lowercasing the ID component keeps plan lookups hit-or-miss-free when
|
|
60
|
+
* the two merge. Package names in npm are already lowercase; version
|
|
61
|
+
* strings have no case. */
|
|
62
|
+
export declare function planKey(pkg: string, version: string, advisoryId: string): string;
|
|
63
|
+
//# sourceMappingURL=osv-scanner-fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osv-scanner-fix.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/osv-scanner-fix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAqC7F;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CA+B1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAwCrF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,GACrC,MAAM,CAaR;AAED;;;;;;;4BAO4B;AAC5B,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEhF"}
|