@vyuhlabs/dxkit 2.2.0 → 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/CHANGELOG.md +160 -0
- package/README.md +40 -29
- package/dist/analyzers/bom/discovery.d.ts +38 -0
- package/dist/analyzers/bom/discovery.d.ts.map +1 -0
- package/dist/analyzers/bom/discovery.js +166 -0
- package/dist/analyzers/bom/discovery.js.map +1 -0
- package/dist/analyzers/bom/gather.d.ts +28 -0
- package/dist/analyzers/bom/gather.d.ts.map +1 -1
- package/dist/analyzers/bom/gather.js +98 -0
- package/dist/analyzers/bom/gather.js.map +1 -1
- package/dist/analyzers/bom/index.d.ts +49 -2
- package/dist/analyzers/bom/index.d.ts.map +1 -1
- package/dist/analyzers/bom/index.js +188 -12
- package/dist/analyzers/bom/index.js.map +1 -1
- package/dist/analyzers/bom/types.d.ts +33 -1
- package/dist/analyzers/bom/types.d.ts.map +1 -1
- package/dist/analyzers/licenses/index.d.ts +1 -1
- package/dist/analyzers/licenses/index.d.ts.map +1 -1
- package/dist/analyzers/licenses/index.js +22 -7
- package/dist/analyzers/licenses/index.js.map +1 -1
- package/dist/analyzers/security/detailed.d.ts.map +1 -1
- package/dist/analyzers/security/detailed.js +21 -8
- package/dist/analyzers/security/detailed.js.map +1 -1
- package/dist/analyzers/security/gather.d.ts.map +1 -1
- package/dist/analyzers/security/gather.js +76 -1
- package/dist/analyzers/security/gather.js.map +1 -1
- package/dist/analyzers/security/index.d.ts.map +1 -1
- package/dist/analyzers/security/index.js +20 -7
- package/dist/analyzers/security/index.js.map +1 -1
- package/dist/analyzers/tools/epss.d.ts +55 -0
- package/dist/analyzers/tools/epss.d.ts.map +1 -0
- package/dist/analyzers/tools/epss.js +133 -0
- package/dist/analyzers/tools/epss.js.map +1 -0
- package/dist/analyzers/tools/graphify.d.ts.map +1 -1
- package/dist/analyzers/tools/graphify.js +17 -7
- package/dist/analyzers/tools/graphify.js.map +1 -1
- package/dist/analyzers/tools/kev.d.ts +52 -0
- package/dist/analyzers/tools/kev.d.ts.map +1 -0
- package/dist/analyzers/tools/kev.js +95 -0
- package/dist/analyzers/tools/kev.js.map +1 -0
- package/dist/analyzers/tools/npm-registry.d.ts +43 -0
- package/dist/analyzers/tools/npm-registry.d.ts.map +1 -0
- package/dist/analyzers/tools/npm-registry.js +107 -0
- package/dist/analyzers/tools/npm-registry.js.map +1 -0
- package/dist/analyzers/tools/osv.d.ts +12 -0
- package/dist/analyzers/tools/osv.d.ts.map +1 -1
- package/dist/analyzers/tools/osv.js +45 -2
- package/dist/analyzers/tools/osv.js.map +1 -1
- package/dist/analyzers/tools/reachability.d.ts +60 -0
- package/dist/analyzers/tools/reachability.d.ts.map +1 -0
- package/dist/analyzers/tools/reachability.js +104 -0
- package/dist/analyzers/tools/reachability.js.map +1 -0
- package/dist/analyzers/tools/risk-score.d.ts +69 -0
- package/dist/analyzers/tools/risk-score.d.ts.map +1 -0
- package/dist/analyzers/tools/risk-score.js +86 -0
- package/dist/analyzers/tools/risk-score.js.map +1 -0
- package/dist/analyzers/tools/tool-registry.d.ts +10 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
- package/dist/analyzers/tools/tool-registry.js +35 -20
- package/dist/analyzers/tools/tool-registry.js.map +1 -1
- package/dist/analyzers/xlsx/bom.d.ts.map +1 -1
- package/dist/analyzers/xlsx/bom.js +1 -2
- package/dist/analyzers/xlsx/bom.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +41 -10
- package/dist/cli.js.map +1 -1
- package/dist/languages/capabilities/types.d.ts +6 -0
- package/dist/languages/capabilities/types.d.ts.map +1 -1
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +8 -0
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +24 -7
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +8 -0
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +9 -0
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +23 -1
- package/dist/languages/typescript.js.map +1 -1
- package/package.json +4 -3
- package/templates/.claude/agents-available/dashboard-builder.md +7 -7
- package/templates/.claude/agents-available/dev-report.md +4 -4
- package/templates/.claude/agents-available/health-auditor.md +1 -1
- package/templates/.claude/agents-available/strategic-planner.md +7 -7
- package/templates/.claude/agents-available/vulnerability-scanner.md +3 -3
- package/templates/.claude/commands/dashboard.md +1 -1
- package/templates/.claude/commands/deps.md +1 -1
- package/templates/.claude/commands/dev-report.md +2 -2
- package/templates/.claude/commands/docs.md +1 -1
- package/templates/.claude/commands/export-pdf.md +3 -3
- package/templates/.claude/commands/health.md +3 -3
- package/templates/.claude/commands/plan.md +1 -1
- package/templates/.claude/commands/quality.md.template +2 -2
- package/templates/.claude/commands/stealth-mode.md +1 -1
- package/templates/.claude/commands/test-gaps.md +2 -2
- package/templates/.claude/commands/vulnerabilities.md +3 -3
- package/dist/agents/extract.d.ts +0 -25
- package/dist/agents/extract.d.ts.map +0 -1
- package/dist/agents/extract.js +0 -186
- package/dist/agents/extract.js.map +0 -1
- package/dist/agents/schemas.d.ts +0 -106
- package/dist/agents/schemas.d.ts.map +0 -1
- package/dist/agents/schemas.js +0 -86
- package/dist/agents/schemas.js.map +0 -1
- package/dist/agents/session.d.ts +0 -28
- package/dist/agents/session.d.ts.map +0 -1
- package/dist/agents/session.js +0 -223
- package/dist/agents/session.js.map +0 -1
- package/dist/analyzers/index.d.ts +0 -3
- package/dist/analyzers/index.d.ts.map +0 -1
- package/dist/analyzers/index.js +0 -6
- package/dist/analyzers/index.js.map +0 -1
- package/dist/analyzers/security/report.d.ts +0 -6
- package/dist/analyzers/security/report.d.ts.map +0 -1
- package/dist/analyzers/security/report.js +0 -118
- package/dist/analyzers/security/report.js.map +0 -1
- package/dist/analyzers/tools/dotnet.d.ts +0 -8
- package/dist/analyzers/tools/dotnet.d.ts.map +0 -1
- package/dist/analyzers/tools/dotnet.js +0 -81
- package/dist/analyzers/tools/dotnet.js.map +0 -1
- package/dist/analyzers/tools/gather-cache.d.ts +0 -16
- package/dist/analyzers/tools/gather-cache.d.ts.map +0 -1
- package/dist/analyzers/tools/gather-cache.js +0 -126
- package/dist/analyzers/tools/gather-cache.js.map +0 -1
- package/dist/analyzers/tools/go.d.ts +0 -8
- package/dist/analyzers/tools/go.d.ts.map +0 -1
- package/dist/analyzers/tools/go.js +0 -84
- package/dist/analyzers/tools/go.js.map +0 -1
- package/dist/analyzers/tools/node.d.ts +0 -8
- package/dist/analyzers/tools/node.d.ts.map +0 -1
- package/dist/analyzers/tools/node.js +0 -160
- package/dist/analyzers/tools/node.js.map +0 -1
- package/dist/analyzers/tools/python.d.ts +0 -8
- package/dist/analyzers/tools/python.d.ts.map +0 -1
- package/dist/analyzers/tools/python.js +0 -81
- package/dist/analyzers/tools/python.js.map +0 -1
- package/dist/analyzers/tools/rust.d.ts +0 -8
- package/dist/analyzers/tools/rust.d.ts.map +0 -1
- package/dist/analyzers/tools/rust.js +0 -86
- package/dist/analyzers/tools/rust.js.map +0 -1
- package/templates/.ai/templates/session-checkpoint-template.md +0 -97
|
@@ -46,11 +46,15 @@ exports.gatherGraphifyResult = gatherGraphifyResult;
|
|
|
46
46
|
* `tools/parallel.ts`. Memoized per-cwd so both callers share one
|
|
47
47
|
* invocation per analyzer run.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
* cleanup
|
|
51
|
-
*
|
|
49
|
+
* D013 (10f.2) — `/tmp/graphify-venv` was prone to systemd-tmpfiles
|
|
50
|
+
* cleanup and first-install races. The venv now lives at
|
|
51
|
+
* `~/.cache/dxkit/tools-venv` via `tool-registry.ts:TOOLS_VENV`;
|
|
52
|
+
* this file's per-run tempfile also migrated to `fs.mkdtempSync` so
|
|
53
|
+
* two concurrent dxkit processes never collide on a script name.
|
|
52
54
|
*/
|
|
53
55
|
const fs = __importStar(require("fs"));
|
|
56
|
+
const os = __importStar(require("os"));
|
|
57
|
+
const path = __importStar(require("path"));
|
|
54
58
|
const runner_1 = require("./runner");
|
|
55
59
|
const tool_registry_1 = require("./tool-registry");
|
|
56
60
|
const exclusions_1 = require("./exclusions");
|
|
@@ -200,12 +204,18 @@ function computeGraphifyOutcome(cwd) {
|
|
|
200
204
|
const pythonCmd = findPython(cwd);
|
|
201
205
|
if (!pythonCmd)
|
|
202
206
|
return { kind: 'unavailable', reason: 'not installed' };
|
|
203
|
-
|
|
207
|
+
// Per-run tempdir via mkdtempSync — unique random suffix eliminates
|
|
208
|
+
// the `Date.now()` collision risk when two dxkit processes fire
|
|
209
|
+
// within the same millisecond. The whole dir is rm'd on exit so we
|
|
210
|
+
// don't litter /tmp across runs.
|
|
211
|
+
const scriptDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dxkit-graphify-'));
|
|
212
|
+
const scriptPath = path.join(scriptDir, 'run.py');
|
|
204
213
|
fs.writeFileSync(scriptPath, buildGraphifyScript(cwd));
|
|
205
|
-
// Redirect stderr to suppress progress output, run from
|
|
206
|
-
|
|
214
|
+
// Redirect stderr to suppress progress output, run from the tempdir
|
|
215
|
+
// so the script doesn't drop cache files inside the analyzed repo.
|
|
216
|
+
const output = (0, runner_1.run)(`cd '${scriptDir}' && ${pythonCmd} '${scriptPath}' '${cwd}' 2>/dev/null`, cwd, 120000);
|
|
207
217
|
try {
|
|
208
|
-
fs.
|
|
218
|
+
fs.rmSync(scriptDir, { recursive: true, force: true });
|
|
209
219
|
}
|
|
210
220
|
catch {
|
|
211
221
|
/* ignore */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CISA Known Exploited Vulnerabilities (KEV) enrichment.
|
|
3
|
+
*
|
|
4
|
+
* CISA publishes a catalog of CVEs the US-federal-agency ISAC has
|
|
5
|
+
* confirmed are being actively exploited in the wild (different from
|
|
6
|
+
* EPSS's *probability of* exploitation). A KEV hit is the strongest
|
|
7
|
+
* "fix this now" signal we can attach to a finding.
|
|
8
|
+
*
|
|
9
|
+
* Feed: `https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json`
|
|
10
|
+
*
|
|
11
|
+
* Shape (we only read `vulnerabilities[].cveID`):
|
|
12
|
+
* {
|
|
13
|
+
* "catalogVersion": "...",
|
|
14
|
+
* "dateReleased": "...",
|
|
15
|
+
* "count": 1200-ish,
|
|
16
|
+
* "vulnerabilities": [
|
|
17
|
+
* { "cveID": "CVE-2021-44228", "vendorProject": "Apache", ... }
|
|
18
|
+
* ]
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* Unlike EPSS (per-CVE lookup), KEV is a bulk download + local
|
|
22
|
+
* lookup — one HTTP call per session, search is a `Set.has`.
|
|
23
|
+
*
|
|
24
|
+
* Design mirrors `osv.ts` / `epss.ts`:
|
|
25
|
+
* - Session-scoped cache so the catalog is fetched at most once
|
|
26
|
+
* per process (it's ~1300 entries, ~200KB).
|
|
27
|
+
* - AbortSignal.timeout prevents stalls.
|
|
28
|
+
* - Fetcher injectable for tests.
|
|
29
|
+
* - Graceful degradation: if the catalog is unreachable, every
|
|
30
|
+
* finding's `kev` stays unset (treated as "no data", not
|
|
31
|
+
* "confirmed not KEV").
|
|
32
|
+
*/
|
|
33
|
+
/** Shape of the fetcher — swapped in tests to avoid real network. */
|
|
34
|
+
export type KevFetcher = () => Promise<Set<string> | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Fetch (or return cached) KEV catalog as a Set of CVE IDs. Returns
|
|
37
|
+
* an empty set on network failure so callers can treat "KEV lookup
|
|
38
|
+
* succeeded but CVE X is not listed" and "KEV fetch failed" the
|
|
39
|
+
* same way — both collapse to "no KEV flag on this finding". The
|
|
40
|
+
* distinction is preserved in logs via DXKIT_DEBUG_KEV.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getKevCatalog(fetcher?: KevFetcher): Promise<Set<string>>;
|
|
43
|
+
/**
|
|
44
|
+
* Enrich `cves` with KEV membership. Returns the subset of input
|
|
45
|
+
* CVE IDs that appear in the catalog. Empty result is safe —
|
|
46
|
+
* callers interpret absence from the result set as "not KEV"
|
|
47
|
+
* (true negative; caller should set `kev: false`).
|
|
48
|
+
*/
|
|
49
|
+
export declare function enrichKev(cves: ReadonlyArray<string>, fetcher?: KevFetcher): Promise<Set<string>>;
|
|
50
|
+
/** Test-only — reset the process cache between tests. */
|
|
51
|
+
export declare function __clearKevCache(): void;
|
|
52
|
+
//# sourceMappingURL=kev.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kev.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/kev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AA+B3D;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,UAA4B,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAK/F;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,OAAO,GAAE,UAA4B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAOtB;AAED,yDAAyD;AACzD,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CISA Known Exploited Vulnerabilities (KEV) enrichment.
|
|
4
|
+
*
|
|
5
|
+
* CISA publishes a catalog of CVEs the US-federal-agency ISAC has
|
|
6
|
+
* confirmed are being actively exploited in the wild (different from
|
|
7
|
+
* EPSS's *probability of* exploitation). A KEV hit is the strongest
|
|
8
|
+
* "fix this now" signal we can attach to a finding.
|
|
9
|
+
*
|
|
10
|
+
* Feed: `https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json`
|
|
11
|
+
*
|
|
12
|
+
* Shape (we only read `vulnerabilities[].cveID`):
|
|
13
|
+
* {
|
|
14
|
+
* "catalogVersion": "...",
|
|
15
|
+
* "dateReleased": "...",
|
|
16
|
+
* "count": 1200-ish,
|
|
17
|
+
* "vulnerabilities": [
|
|
18
|
+
* { "cveID": "CVE-2021-44228", "vendorProject": "Apache", ... }
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* Unlike EPSS (per-CVE lookup), KEV is a bulk download + local
|
|
23
|
+
* lookup — one HTTP call per session, search is a `Set.has`.
|
|
24
|
+
*
|
|
25
|
+
* Design mirrors `osv.ts` / `epss.ts`:
|
|
26
|
+
* - Session-scoped cache so the catalog is fetched at most once
|
|
27
|
+
* per process (it's ~1300 entries, ~200KB).
|
|
28
|
+
* - AbortSignal.timeout prevents stalls.
|
|
29
|
+
* - Fetcher injectable for tests.
|
|
30
|
+
* - Graceful degradation: if the catalog is unreachable, every
|
|
31
|
+
* finding's `kev` stays unset (treated as "no data", not
|
|
32
|
+
* "confirmed not KEV").
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.getKevCatalog = getKevCatalog;
|
|
36
|
+
exports.enrichKev = enrichKev;
|
|
37
|
+
exports.__clearKevCache = __clearKevCache;
|
|
38
|
+
/** Cached CVE set for the process lifetime. `null` means "tried and failed". */
|
|
39
|
+
let cachedCatalog = undefined;
|
|
40
|
+
/** Per-request timeout. The CISA feed is usually fast but can stall under load. */
|
|
41
|
+
const KEV_REQUEST_TIMEOUT_MS = 10000;
|
|
42
|
+
/** Production fetcher: downloads the CISA catalog and builds a CVE set. */
|
|
43
|
+
const DEFAULT_FETCHER = async () => {
|
|
44
|
+
try {
|
|
45
|
+
const res = await fetch('https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json', { signal: AbortSignal.timeout(KEV_REQUEST_TIMEOUT_MS) });
|
|
46
|
+
if (!res.ok)
|
|
47
|
+
return null;
|
|
48
|
+
const body = (await res.json());
|
|
49
|
+
const set = new Set();
|
|
50
|
+
for (const row of body.vulnerabilities ?? []) {
|
|
51
|
+
if (row.cveID)
|
|
52
|
+
set.add(row.cveID);
|
|
53
|
+
}
|
|
54
|
+
return set;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (process.env.DXKIT_DEBUG_KEV) {
|
|
58
|
+
process.stderr.write(`[dxkit-kev] catalog fetch failed: ${err.message}\n`); // slop-ok
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Fetch (or return cached) KEV catalog as a Set of CVE IDs. Returns
|
|
65
|
+
* an empty set on network failure so callers can treat "KEV lookup
|
|
66
|
+
* succeeded but CVE X is not listed" and "KEV fetch failed" the
|
|
67
|
+
* same way — both collapse to "no KEV flag on this finding". The
|
|
68
|
+
* distinction is preserved in logs via DXKIT_DEBUG_KEV.
|
|
69
|
+
*/
|
|
70
|
+
async function getKevCatalog(fetcher = DEFAULT_FETCHER) {
|
|
71
|
+
if (cachedCatalog === undefined) {
|
|
72
|
+
cachedCatalog = await fetcher();
|
|
73
|
+
}
|
|
74
|
+
return cachedCatalog ?? new Set();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Enrich `cves` with KEV membership. Returns the subset of input
|
|
78
|
+
* CVE IDs that appear in the catalog. Empty result is safe —
|
|
79
|
+
* callers interpret absence from the result set as "not KEV"
|
|
80
|
+
* (true negative; caller should set `kev: false`).
|
|
81
|
+
*/
|
|
82
|
+
async function enrichKev(cves, fetcher = DEFAULT_FETCHER) {
|
|
83
|
+
const catalog = await getKevCatalog(fetcher);
|
|
84
|
+
const hits = new Set();
|
|
85
|
+
for (const cve of cves) {
|
|
86
|
+
if (catalog.has(cve))
|
|
87
|
+
hits.add(cve);
|
|
88
|
+
}
|
|
89
|
+
return hits;
|
|
90
|
+
}
|
|
91
|
+
/** Test-only — reset the process cache between tests. */
|
|
92
|
+
function __clearKevCache() {
|
|
93
|
+
cachedCatalog = undefined;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=kev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kev.js","sourceRoot":"","sources":["../../../src/analyzers/tools/kev.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;AA4CH,sCAKC;AAQD,8BAUC;AAGD,0CAEC;AAtED,gFAAgF;AAChF,IAAI,aAAa,GAAmC,SAAS,CAAC;AAK9D,mFAAmF;AACnF,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAMrC,2EAA2E;AAC3E,MAAM,eAAe,GAAe,KAAK,IAAI,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,qFAAqF,EACrF,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CACxD,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAe,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;YAC7C,IAAI,GAAG,CAAC,KAAK;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;YAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAsC,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU;QACnG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;GAMG;AACI,KAAK,UAAU,aAAa,CAAC,UAAsB,eAAe;IACvE,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,aAAa,GAAG,MAAM,OAAO,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,aAAa,IAAI,IAAI,GAAG,EAAE,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,SAAS,CAC7B,IAA2B,EAC3B,UAAsB,eAAe;IAErC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yDAAyD;AACzD,SAAgB,eAAe;IAC7B,aAAa,GAAG,SAAS,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm registry per-package metadata fetch.
|
|
3
|
+
*
|
|
4
|
+
* Populates `LicenseFinding.releaseDate` (xlsx col 10 — Component
|
|
5
|
+
* Release Date, D006) by querying
|
|
6
|
+
* `GET https://registry.npmjs.org/<pkg>`
|
|
7
|
+
* and reading the `time[<version>]` ISO-8601 string for the exact
|
|
8
|
+
* installed version. Falls back to `time.modified` when the exact
|
|
9
|
+
* version isn't listed (extremely rare; usually means the installed
|
|
10
|
+
* version is a legacy tag the registry re-hoisted).
|
|
11
|
+
*
|
|
12
|
+
* Design mirrors `osv.ts` / `epss.ts`:
|
|
13
|
+
* - Session-scoped cache keyed on package name (one HTTP call per
|
|
14
|
+
* package regardless of how many versions are installed).
|
|
15
|
+
* - AbortSignal.timeout keeps the analyzer from hanging.
|
|
16
|
+
* - Fetcher injectable for tests.
|
|
17
|
+
* - Graceful degradation — every IO failure maps to "no date",
|
|
18
|
+
* and `releaseDate` stays unset on the finding.
|
|
19
|
+
*
|
|
20
|
+
* Concurrency: `enrichReleaseDates` runs per-package fetches with a
|
|
21
|
+
* bounded pool so a 1700-package bom doesn't fire 1700 simultaneous
|
|
22
|
+
* sockets. Default pool size is tuned for the npm CDN's behavior.
|
|
23
|
+
*/
|
|
24
|
+
/** Shape of the fetcher — swapped in tests to avoid real network. */
|
|
25
|
+
export type NpmRegistryFetcher = (pkg: string) => Promise<Map<string, string> | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Fetch release dates for a set of `(package, version)` pairs from
|
|
28
|
+
* the npm registry. Returns a map keyed by `package@version` →
|
|
29
|
+
* ISO-8601 date string. Missing entries (unknown package, version
|
|
30
|
+
* not in registry's `time`, network failure) are absent from the
|
|
31
|
+
* map — callers treat absence as "date unknown" and leave
|
|
32
|
+
* `releaseDate` unset on the LicenseFinding.
|
|
33
|
+
*
|
|
34
|
+
* Caches per-package responses so multiple versions of the same
|
|
35
|
+
* package cost one HTTP call.
|
|
36
|
+
*/
|
|
37
|
+
export declare function enrichReleaseDates(pairs: ReadonlyArray<{
|
|
38
|
+
package: string;
|
|
39
|
+
version: string;
|
|
40
|
+
}>, fetcher?: NpmRegistryFetcher, concurrency?: number): Promise<Map<string, string>>;
|
|
41
|
+
/** Test-only — reset the process cache between tests. */
|
|
42
|
+
export declare function __clearNpmRegistryCache(): void;
|
|
43
|
+
//# sourceMappingURL=npm-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-registry.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/npm-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,qEAAqE;AACrE,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AAkCtF;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1D,OAAO,GAAE,kBAAoC,EAC7C,WAAW,GAAE,MAAwB,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA+B9B;AAED,yDAAyD;AACzD,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* npm registry per-package metadata fetch.
|
|
4
|
+
*
|
|
5
|
+
* Populates `LicenseFinding.releaseDate` (xlsx col 10 — Component
|
|
6
|
+
* Release Date, D006) by querying
|
|
7
|
+
* `GET https://registry.npmjs.org/<pkg>`
|
|
8
|
+
* and reading the `time[<version>]` ISO-8601 string for the exact
|
|
9
|
+
* installed version. Falls back to `time.modified` when the exact
|
|
10
|
+
* version isn't listed (extremely rare; usually means the installed
|
|
11
|
+
* version is a legacy tag the registry re-hoisted).
|
|
12
|
+
*
|
|
13
|
+
* Design mirrors `osv.ts` / `epss.ts`:
|
|
14
|
+
* - Session-scoped cache keyed on package name (one HTTP call per
|
|
15
|
+
* package regardless of how many versions are installed).
|
|
16
|
+
* - AbortSignal.timeout keeps the analyzer from hanging.
|
|
17
|
+
* - Fetcher injectable for tests.
|
|
18
|
+
* - Graceful degradation — every IO failure maps to "no date",
|
|
19
|
+
* and `releaseDate` stays unset on the finding.
|
|
20
|
+
*
|
|
21
|
+
* Concurrency: `enrichReleaseDates` runs per-package fetches with a
|
|
22
|
+
* bounded pool so a 1700-package bom doesn't fire 1700 simultaneous
|
|
23
|
+
* sockets. Default pool size is tuned for the npm CDN's behavior.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.enrichReleaseDates = enrichReleaseDates;
|
|
27
|
+
exports.__clearNpmRegistryCache = __clearNpmRegistryCache;
|
|
28
|
+
/** Session cache. Key: package name, value: map of version → ISO date, or null on lookup failure. */
|
|
29
|
+
const cache = new Map();
|
|
30
|
+
/** Per-request timeout. npm CDN is usually fast but some long-tail packages stall. */
|
|
31
|
+
const NPM_REQUEST_TIMEOUT_MS = 10000;
|
|
32
|
+
/** Max concurrent fetches. npm allows generous parallelism but we keep it polite. */
|
|
33
|
+
const NPM_CONCURRENCY = 20;
|
|
34
|
+
/** Production fetcher: issues one GET per package, parses `time` map. */
|
|
35
|
+
const DEFAULT_FETCHER = async (pkg) => {
|
|
36
|
+
try {
|
|
37
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(pkg).replace('%40', '@')}`;
|
|
38
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(NPM_REQUEST_TIMEOUT_MS) });
|
|
39
|
+
if (!res.ok)
|
|
40
|
+
return null;
|
|
41
|
+
const body = (await res.json());
|
|
42
|
+
const time = body.time;
|
|
43
|
+
if (!time)
|
|
44
|
+
return null;
|
|
45
|
+
const out = new Map();
|
|
46
|
+
for (const [key, value] of Object.entries(time)) {
|
|
47
|
+
if (typeof value === 'string')
|
|
48
|
+
out.set(key, value);
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
if (process.env.DXKIT_DEBUG_NPM_REGISTRY) {
|
|
54
|
+
process.stderr.write(`[dxkit-npm-registry] ${pkg}: ${err.message}\n`); // slop-ok
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Fetch release dates for a set of `(package, version)` pairs from
|
|
61
|
+
* the npm registry. Returns a map keyed by `package@version` →
|
|
62
|
+
* ISO-8601 date string. Missing entries (unknown package, version
|
|
63
|
+
* not in registry's `time`, network failure) are absent from the
|
|
64
|
+
* map — callers treat absence as "date unknown" and leave
|
|
65
|
+
* `releaseDate` unset on the LicenseFinding.
|
|
66
|
+
*
|
|
67
|
+
* Caches per-package responses so multiple versions of the same
|
|
68
|
+
* package cost one HTTP call.
|
|
69
|
+
*/
|
|
70
|
+
async function enrichReleaseDates(pairs, fetcher = DEFAULT_FETCHER, concurrency = NPM_CONCURRENCY) {
|
|
71
|
+
const result = new Map();
|
|
72
|
+
const uniquePackages = new Set();
|
|
73
|
+
for (const p of pairs)
|
|
74
|
+
uniquePackages.add(p.package);
|
|
75
|
+
const toFetch = [];
|
|
76
|
+
for (const pkg of uniquePackages) {
|
|
77
|
+
if (!cache.has(pkg))
|
|
78
|
+
toFetch.push(pkg);
|
|
79
|
+
}
|
|
80
|
+
// Bounded-concurrency pool. Each worker pulls the next package
|
|
81
|
+
// from a shared index until the list is drained.
|
|
82
|
+
let idx = 0;
|
|
83
|
+
const workers = Array.from({ length: Math.min(concurrency, toFetch.length) }, async () => {
|
|
84
|
+
while (idx < toFetch.length) {
|
|
85
|
+
const i = idx++;
|
|
86
|
+
const pkg = toFetch[i];
|
|
87
|
+
cache.set(pkg, await fetcher(pkg));
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
await Promise.all(workers);
|
|
91
|
+
for (const { package: pkg, version } of pairs) {
|
|
92
|
+
const times = cache.get(pkg);
|
|
93
|
+
if (!times)
|
|
94
|
+
continue;
|
|
95
|
+
const exact = times.get(version);
|
|
96
|
+
const fallback = times.get('modified');
|
|
97
|
+
const iso = exact ?? fallback;
|
|
98
|
+
if (iso)
|
|
99
|
+
result.set(`${pkg}@${version}`, iso);
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
/** Test-only — reset the process cache between tests. */
|
|
104
|
+
function __clearNpmRegistryCache() {
|
|
105
|
+
cache.clear();
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=npm-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-registry.js","sourceRoot":"","sources":["../../../src/analyzers/tools/npm-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -90,6 +90,18 @@ export declare function resolveCvssScores(inputs: Array<{
|
|
|
90
90
|
embeddedCvss: number | null;
|
|
91
91
|
aliases: string[];
|
|
92
92
|
}>, fetcher?: OsvFetcher): Promise<Map<string, number | null>>;
|
|
93
|
+
/**
|
|
94
|
+
* Look up the `aliases` list for each ID against OSV.dev. GHSA/RUSTSEC/
|
|
95
|
+
* GO-YYYY-NNNN primaries frequently have a CVE in their aliases that
|
|
96
|
+
* the producing tool (npm-audit, cargo-audit, govulncheck) didn't
|
|
97
|
+
* surface — we pull them here so downstream enrichers (EPSS) can
|
|
98
|
+
* query against CVE IDs even when the primary isn't one.
|
|
99
|
+
*
|
|
100
|
+
* Falls back to an empty list for IDs the fetcher can't resolve.
|
|
101
|
+
* Session-cached via the same map as `enrichOsv` so a find-severity
|
|
102
|
+
* pass and a find-aliases pass cost at most one roundtrip per ID.
|
|
103
|
+
*/
|
|
104
|
+
export declare function resolveAliases(ids: ReadonlyArray<string>, fetcher?: OsvFetcher): Promise<Map<string, string[]>>;
|
|
93
105
|
/** Test-only — reset the process cache between tests. */
|
|
94
106
|
export declare function __clearOsvCache(): void;
|
|
95
107
|
//# sourceMappingURL=osv.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osv.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/osv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE1E,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,iBAAiB,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACnD,CAAC,CAAC;IAGH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED;iEACiE;AACjE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAKD,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAMnD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2ClE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAuBhE;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAW3D;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"osv.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/osv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE1E,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,iBAAiB,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACnD,CAAC,CAAC;IAGH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED;iEACiE;AACjE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAKD,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAMnD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2ClE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAuBhE;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAW3D;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAsCjE;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,GAAE,UAA4B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CA6BjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EACpF,OAAO,GAAE,UAA4B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CA6CrC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,EAC1B,OAAO,GAAE,UAA4B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAiBhC;AAED,yDAAyD;AACzD,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|
|
@@ -18,6 +18,7 @@ exports.extractOsvCvssScore = extractOsvCvssScore;
|
|
|
18
18
|
exports.classifyOsvSeverity = classifyOsvSeverity;
|
|
19
19
|
exports.enrichOsv = enrichOsv;
|
|
20
20
|
exports.resolveCvssScores = resolveCvssScores;
|
|
21
|
+
exports.resolveAliases = resolveAliases;
|
|
21
22
|
exports.__clearOsvCache = __clearOsvCache;
|
|
22
23
|
const cvss_v4_1 = require("./cvss-v4");
|
|
23
24
|
/** Process-scoped cache so repeated lookups in a session don't re-query. */
|
|
@@ -143,9 +144,23 @@ function classifyOsvSeverity(vuln) {
|
|
|
143
144
|
* under full-analyzer load. Unreachable hosts still fail fast via AbortSignal.
|
|
144
145
|
*/
|
|
145
146
|
const OSV_REQUEST_TIMEOUT_MS = 10000;
|
|
147
|
+
/**
|
|
148
|
+
* OSV.dev is case-sensitive on GHSA IDs — `GHSA-7h2j-956f-4vf2` resolves,
|
|
149
|
+
* `GHSA-7H2J-956F-4VF2` returns "Bug not found". npm-audit emits
|
|
150
|
+
* uppercase, so any analyzer passing npm-audit IDs straight through
|
|
151
|
+
* would get zero results. Normalize the alphabetic portion before the
|
|
152
|
+
* HTTP call; CVE / PYSEC / GO / RUSTSEC aren't affected (either all-
|
|
153
|
+
* numeric or already canonically uppercased).
|
|
154
|
+
*/
|
|
155
|
+
function normalizeIdForOsv(id) {
|
|
156
|
+
if (id.startsWith('GHSA-'))
|
|
157
|
+
return 'GHSA-' + id.slice(5).toLowerCase();
|
|
158
|
+
return id;
|
|
159
|
+
}
|
|
146
160
|
const DEFAULT_FETCHER = async (id) => {
|
|
147
161
|
try {
|
|
148
|
-
const
|
|
162
|
+
const normalized = normalizeIdForOsv(id);
|
|
163
|
+
const res = await fetch(`https://api.osv.dev/v1/vulns/${encodeURIComponent(normalized)}`, {
|
|
149
164
|
signal: AbortSignal.timeout(OSV_REQUEST_TIMEOUT_MS),
|
|
150
165
|
});
|
|
151
166
|
if (!res.ok)
|
|
@@ -154,7 +169,7 @@ const DEFAULT_FETCHER = async (id) => {
|
|
|
154
169
|
}
|
|
155
170
|
catch (err) {
|
|
156
171
|
if (process.env.DXKIT_DEBUG_OSV) {
|
|
157
|
-
process.stderr.write(`[dxkit-osv] ${id}: ${err.message}\n`);
|
|
172
|
+
process.stderr.write(`[dxkit-osv] ${id}: ${err.message}\n`); // slop-ok
|
|
158
173
|
}
|
|
159
174
|
return null;
|
|
160
175
|
}
|
|
@@ -263,6 +278,34 @@ async function resolveCvssScores(inputs, fetcher = DEFAULT_FETCHER) {
|
|
|
263
278
|
}
|
|
264
279
|
return result;
|
|
265
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Look up the `aliases` list for each ID against OSV.dev. GHSA/RUSTSEC/
|
|
283
|
+
* GO-YYYY-NNNN primaries frequently have a CVE in their aliases that
|
|
284
|
+
* the producing tool (npm-audit, cargo-audit, govulncheck) didn't
|
|
285
|
+
* surface — we pull them here so downstream enrichers (EPSS) can
|
|
286
|
+
* query against CVE IDs even when the primary isn't one.
|
|
287
|
+
*
|
|
288
|
+
* Falls back to an empty list for IDs the fetcher can't resolve.
|
|
289
|
+
* Session-cached via the same map as `enrichOsv` so a find-severity
|
|
290
|
+
* pass and a find-aliases pass cost at most one roundtrip per ID.
|
|
291
|
+
*/
|
|
292
|
+
async function resolveAliases(ids, fetcher = DEFAULT_FETCHER) {
|
|
293
|
+
const result = new Map();
|
|
294
|
+
const uniqueIds = [...new Set(ids)];
|
|
295
|
+
if (uniqueIds.length === 0)
|
|
296
|
+
return result;
|
|
297
|
+
const settled = await Promise.allSettled(uniqueIds.map(async (id) => {
|
|
298
|
+
const vuln = await fetcher(id);
|
|
299
|
+
return [id, vuln?.aliases ?? []];
|
|
300
|
+
}));
|
|
301
|
+
for (const p of settled) {
|
|
302
|
+
if (p.status === 'fulfilled') {
|
|
303
|
+
const [id, aliases] = p.value;
|
|
304
|
+
result.set(id, aliases);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
266
309
|
/** Test-only — reset the process cache between tests. */
|
|
267
310
|
function __clearOsvCache() {
|
|
268
311
|
cache.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osv.js","sourceRoot":"","sources":["../../../src/analyzers/tools/osv.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AAgCH,kCAMC;AAOD,oDA2CC;AASD,kDAuBC;AAGD,kDAWC;
|
|
1
|
+
{"version":3,"file":"osv.js","sourceRoot":"","sources":["../../../src/analyzers/tools/osv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reachability analysis for dependency vulnerabilities.
|
|
3
|
+
*
|
|
4
|
+
* Answers the triage question "does *my* code actually touch this
|
|
5
|
+
* vulnerable package, anywhere?". A critical CVE in `axios` is
|
|
6
|
+
* meaningful if `import from 'axios'` exists somewhere in my source;
|
|
7
|
+
* it's usually inert noise if axios is a transitive dev-dep nothing
|
|
8
|
+
* actually loads.
|
|
9
|
+
*
|
|
10
|
+
* Input is the aggregated `ImportsResult` (language packs already
|
|
11
|
+
* extract per-file specifiers; the dispatcher unions them). Output is
|
|
12
|
+
* a boolean per `DepVulnFinding.reachable`.
|
|
13
|
+
*
|
|
14
|
+
* Matching is *coarse* — name-level, not call-graph level. Importing
|
|
15
|
+
* `lodash` flags every lodash finding as reachable even if the call
|
|
16
|
+
* sites only touch safe paths. A precise per-advisory reachability
|
|
17
|
+
* check (Snyk-style AST walking into the package itself) belongs in
|
|
18
|
+
* 10h.8 (optional snyk overlay); this module is the OSS-only
|
|
19
|
+
* predecessor the rest of dxkit ships with.
|
|
20
|
+
*
|
|
21
|
+
* Pure functions so renders can be tested without filesystem.
|
|
22
|
+
*/
|
|
23
|
+
import type { DepVulnFinding, ImportsResult } from '../../languages/capabilities/types';
|
|
24
|
+
/**
|
|
25
|
+
* Project an import specifier to the external package name it
|
|
26
|
+
* references, or null for relative / absolute / protocol specifiers.
|
|
27
|
+
*
|
|
28
|
+
* Handles three ecosystems consistently:
|
|
29
|
+
*
|
|
30
|
+
* - npm scoped: `@scope/name` or `@scope/name/subpath` → `@scope/name`
|
|
31
|
+
* - npm bare: `lodash` or `lodash/get` → `lodash`
|
|
32
|
+
* - Python: `foo.bar.baz` (from ImportsResult's raw specifier
|
|
33
|
+
* form) → `foo` (top-level module is the package name)
|
|
34
|
+
* - Go: `github.com/user/repo/subpkg` → `github.com/user/repo`
|
|
35
|
+
* (3-slash module-path convention; detected by the
|
|
36
|
+
* dotted first segment)
|
|
37
|
+
* - Rust / C#: not reliably mapped (crate paths / namespaces
|
|
38
|
+
* don't equal package names). Rust's `use serde`
|
|
39
|
+
* does resolve though, since `serde` is both crate
|
|
40
|
+
* and extracted specifier.
|
|
41
|
+
*
|
|
42
|
+
* Pure; exported for unit tests.
|
|
43
|
+
*/
|
|
44
|
+
export declare function specifierToPackage(spec: string): string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Build a set of external package names referenced from anywhere in
|
|
47
|
+
* the repo's source. Empty set is safe — means "no imports parsed",
|
|
48
|
+
* which callers treat as "reachability unknown" (leave findings'
|
|
49
|
+
* `reachable` unset rather than mass-false).
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildReachablePackageSet(imports: ImportsResult): Set<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Annotate every finding's `reachable` field. `true` when the finding's
|
|
54
|
+
* `package` is in the reachable set; `false` otherwise. Unsetting is
|
|
55
|
+
* intentionally avoided — we always classify once the set is built,
|
|
56
|
+
* because an empty set (no imports parsed) skips this helper entirely
|
|
57
|
+
* at the call site in `gatherDepVulns`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function markReachable(findings: DepVulnFinding[], reachable: ReadonlySet<string>): void;
|
|
60
|
+
//# sourceMappingURL=reachability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reachability.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/reachability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAExF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0B9D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,CAS5E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAI9F"}
|