@lateos/npm-scan 0.3.2 → 0.3.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/backend/db.js +4 -0
- package/backend/report.js +5 -4
- package/backend/sbom.js +2 -2
- package/cli/cli.js +6 -3
- package/package.json +1 -1
package/backend/db.js
CHANGED
|
@@ -33,6 +33,10 @@ export function getFindings(scanId) {
|
|
|
33
33
|
return db.prepare('SELECT * FROM findings WHERE scan_id = ?').all(scanId);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export function getScan(scanId) {
|
|
37
|
+
return db.prepare('SELECT * FROM scans WHERE id = ?').get(scanId);
|
|
38
|
+
}
|
|
39
|
+
|
|
36
40
|
export function close() {
|
|
37
41
|
db.close();
|
|
38
42
|
}
|
package/backend/report.js
CHANGED
|
@@ -6,7 +6,7 @@ export function generateHTML(scans) {
|
|
|
6
6
|
const worstLabel = ['', 'info', 'low', 'medium', 'high', 'critical'][worst] || 'clean';
|
|
7
7
|
const color = { critical: '#d73a49', high: '#cb2431', medium: '#f66a0a', low: '#dbab09', clean: '#28a745' }[worstLabel] || '#28a745';
|
|
8
8
|
const findingRows = findings.map(f =>
|
|
9
|
-
`<tr><td>${f.id}</td><td style="color:${color}">${f.severity}</td><td>${f.title || ''}</td><td>${(f.evidence || '').slice(0, 80)}</td></tr>`
|
|
9
|
+
`<tr><td>${f.atk_id || f.id}</td><td style="color:${color}">${f.severity}</td><td>${f.description || f.title || ''}</td><td>${(f.evidence || '').slice(0, 80)}</td></tr>`
|
|
10
10
|
).join('');
|
|
11
11
|
return { name: s.package_name, worstLabel, color, count: findings.length, findingRows };
|
|
12
12
|
});
|
|
@@ -65,7 +65,7 @@ th { background: #161b22; font-weight: 600; }
|
|
|
65
65
|
<h2>NIST SP 800-161 Compliance Summary</h2>
|
|
66
66
|
${nistMap}
|
|
67
67
|
|
|
68
|
-
<p class="meta">npm-scan
|
|
68
|
+
<p class="meta">npm-scan v${process.env.npm_package_version || '0.3.2'} | Apache-2.0 + Commons Clause | NIST SP 800-161 mapped</p>
|
|
69
69
|
</body>
|
|
70
70
|
</html>`;
|
|
71
71
|
}
|
|
@@ -74,8 +74,9 @@ function getAtkFindings(scans) {
|
|
|
74
74
|
const map = {};
|
|
75
75
|
for (const s of scans) {
|
|
76
76
|
for (const f of (s.findings || [])) {
|
|
77
|
-
|
|
78
|
-
map[
|
|
77
|
+
const key = f.atk_id || f.id;
|
|
78
|
+
if (!map[key]) map[key] = [];
|
|
79
|
+
map[key].push(f);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
return map;
|
package/backend/sbom.js
CHANGED
|
@@ -15,7 +15,7 @@ function generateCycloneDX(pkgJson, findings) {
|
|
|
15
15
|
version: pkgJson.version || 'unknown',
|
|
16
16
|
purl: `pkg:npm/${pkgJson.name || 'unknown'}@${pkgJson.version || 'unknown'}`
|
|
17
17
|
},
|
|
18
|
-
tools: [{ name: 'npm-scan', version: '0.2
|
|
18
|
+
tools: [{ name: 'npm-scan', version: '0.3.2' }]
|
|
19
19
|
},
|
|
20
20
|
vulnerabilities: findings.map(f => {
|
|
21
21
|
const atkId = f.atk_id || f.id;
|
|
@@ -60,7 +60,7 @@ function generateSPDX(pkgJson, findings) {
|
|
|
60
60
|
annotationDate: new Date().toISOString(),
|
|
61
61
|
annotationType: 'OTHER',
|
|
62
62
|
annotator: 'Tool: npm-scan',
|
|
63
|
-
comment: `[${f.id}] ${f.severity.toUpperCase()}: ${f.
|
|
63
|
+
comment: `[${f.atk_id || f.id}] ${f.severity.toUpperCase()}: ${f.description || f.title || ''}`
|
|
64
64
|
}))
|
|
65
65
|
};
|
|
66
66
|
return JSON.stringify(spdx, null, 2);
|
package/cli/cli.js
CHANGED
|
@@ -50,17 +50,20 @@ program
|
|
|
50
50
|
.option('--html', 'HTML report')
|
|
51
51
|
.option('--nist', 'NIST 800-161 compliance report')
|
|
52
52
|
.action(async (options) => {
|
|
53
|
-
const { getRecentScans, getFindings,
|
|
53
|
+
const { getRecentScans, getFindings, getScan } = await import('../backend/db.js');
|
|
54
54
|
if (options.id) {
|
|
55
55
|
const findings = getFindings(options.id);
|
|
56
|
-
const
|
|
56
|
+
const scanInfo = getScan(options.id);
|
|
57
|
+
const pkgName = scanInfo?.package_name || 'scan-' + options.id;
|
|
58
|
+
const pkgVer = scanInfo?.version || 'unknown';
|
|
59
|
+
const pkg = { name: pkgName, version: pkgVer };
|
|
57
60
|
if (options.sbom) {
|
|
58
61
|
const { generateSBOM } = await import('../backend/sbom.js');
|
|
59
62
|
const sbom = generateSBOM(pkg, findings, options.sbom === true ? 'json' : options.sbom);
|
|
60
63
|
console.log(sbom);
|
|
61
64
|
} else if (options.html || options.nist) {
|
|
62
65
|
const { generateHTML } = await import('../backend/report.js');
|
|
63
|
-
const scan = findings.length ? { package_name:
|
|
66
|
+
const scan = findings.length ? { package_name: pkgName, version: pkgVer, findings } : null;
|
|
64
67
|
const html = generateHTML(scan ? [scan] : []);
|
|
65
68
|
console.log(html);
|
|
66
69
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lateos/npm-scan",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Powerful npm supply chain security scanner - detects malicious packages (Shai-Hulud style), behavioral analysis, SBOM, and compliance reporting.",
|
|
5
5
|
"main": "backend/index.js",
|
|
6
6
|
"bin": {
|