@dreamhorizonorg/sentinel
Version:
Open-source, zero-dependency tool that blocks compromised packages BEFORE download. Built to counter supply chain and credential theft attacks like Shai-Hulud.
103 lines (86 loc) • 3.12 kB
JavaScript
/**
* OSV (Open Source Vulnerabilities) Provider
* Google's comprehensive vulnerability database
* API: https://osv.dev/docs/
*/
import { VulnerabilityProvider } from './provider.interface.mjs';
import { fetchJsonFromUrl } from '../utils/http.utils.mjs';
import { logVerbose } from '../utils/log.utils.mjs';
import { colors } from '../utils/color.utils.mjs';
import { DEFAULT_TIMEOUT_MS, CVSS_SCORES, DEFAULT_SEVERITY } from '../constants/app.constants.mjs';
import { INFO_MESSAGES } from '../constants/validation.constants.mjs';
export class OSVProvider extends VulnerabilityProvider {
name = 'OSV';
getDefaultConfig() {
return {
...super.getDefaultConfig(),
enabled: true,
apiUrl: 'https://api.osv.dev/v1/query',
timeout: DEFAULT_TIMEOUT_MS
};
}
async check(packageName, version = null, config = {}) {
if (!this.isEnabled(config)) {
return { found: false };
}
const providerConfig = { ...this.getDefaultConfig(), ...config };
try {
// OSV API expects: { "package": { "name": "package-name", "ecosystem": "npm" }, "version": "1.0.0" }
const query = {
package: {
name: packageName,
ecosystem: 'npm'
}
};
if (version) {
query.version = version;
}
const packageDisplay = `${packageName}${version ? '@' + version : ''}`;
logVerbose(colors.dim(INFO_MESSAGES.PROVIDER_CHECKING('OSV', packageName, version)), config.logMode);
const response = await fetchJsonFromUrl(providerConfig.apiUrl, {
method: 'POST',
body: query,
headers: {
'Content-Type': 'application/json'
},
timeout: providerConfig.timeout
});
if (response && response.vulns && response.vulns.length > 0) {
// Get the most severe vulnerability
const vuln = response.vulns[0];
const severity = this.extractSeverity(vuln);
return {
found: true,
severity: severity,
title: vuln.summary ?? vuln.details ?? 'Security vulnerability',
source: 'OSV',
cve: vuln.id,
url: vuln.database_specific?.url ?? `https://osv.dev/vulnerability/${vuln.id}`
};
}
return { found: false };
} catch (error) {
// Fail silently - don't block installation if provider is down
logVerbose(colors.dim(INFO_MESSAGES.PROVIDER_ERROR('OSV', error.message)), config.logMode);
return { found: false };
}
}
/**
* Extract severity from OSV vulnerability
*/
extractSeverity(vuln) {
// OSV uses database_specific.severity or CVSS scores
if (vuln.database_specific?.severity) {
return vuln.database_specific.severity.toLowerCase();
}
// Check CVSS v3 score
if (vuln.severity && vuln.severity.length > 0) {
const cvss = vuln.severity[0].score;
if (cvss >= CVSS_SCORES.CRITICAL) return 'critical';
if (cvss >= CVSS_SCORES.HIGH) return 'high';
if (cvss >= CVSS_SCORES.MEDIUM) return 'medium';
return 'low';
}
return DEFAULT_SEVERITY;
}
}