UNPKG

@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.

86 lines (71 loc) 2.94 kB
/** * Snyk Vulnerability Provider * Snyk's comprehensive vulnerability database * API: https://snyk.io/api * * Note: Snyk API requires authentication (API token) */ import { VulnerabilityProvider } from './provider.interface.mjs'; import { fetchJsonFromUrl } from '../utils/http.utils.mjs'; import { logVerbose, logWarning } from '../utils/log.utils.mjs'; import { colors } from '../utils/color.utils.mjs'; import { DEFAULT_TIMEOUT_MS, DEFAULT_SEVERITY } from '../constants/app.constants.mjs'; import { INFO_MESSAGES } from '../constants/validation.constants.mjs'; export class SnykProvider extends VulnerabilityProvider { name = 'Snyk'; getDefaultConfig() { return { ...super.getDefaultConfig(), enabled: false, // Disabled by default (REQUIRES API token) apiUrl: 'https://api.snyk.io/v1/test/npm', timeout: DEFAULT_TIMEOUT_MS, token: null // REQUIRED: Snyk API token (get one at https://snyk.io) }; } isEnabled(config = {}) { const providerConfig = { ...this.getDefaultConfig(), ...config }; // Snyk REQUIRES API token - cannot work without it return providerConfig.enabled && !!providerConfig.token; } async check(packageName, version = null, config = {}) { if (!this.isEnabled(config)) { return { found: false }; } const providerConfig = { ...this.getDefaultConfig(), ...config }; if (!providerConfig.token) { logWarning(colors.yellow('[Snyk] API token not configured. Skipping.'), config.logMode); return { found: false }; } try { // Snyk API: POST /v1/test/npm/{packageName} const packageSpec = version ? `${packageName}@${version}` : packageName; const apiUrl = `${providerConfig.apiUrl}/${packageSpec}`; logVerbose(colors.dim(INFO_MESSAGES.PROVIDER_CHECKING('Snyk', packageName, version)), config.logMode); const response = await fetchJsonFromUrl(apiUrl, { method: 'POST', headers: { 'Authorization': `token ${providerConfig.token}`, 'Content-Type': 'application/json' }, timeout: providerConfig.timeout }); if (response && response.issues && response.issues.vulnerabilities && response.issues.vulnerabilities.length > 0) { // Get the most severe vulnerability const vuln = response.issues.vulnerabilities[0]; return { found: true, severity: vuln.severity?.toLowerCase() ?? DEFAULT_SEVERITY, title: vuln.title ?? vuln.id, source: 'Snyk', cve: vuln.identifiers?.CVE?.[0], url: vuln.url ?? `https://security.snyk.io/vuln/${vuln.id}` }; } return { found: false }; } catch (error) { // Fail silently - don't block installation if provider is down logVerbose(colors.dim(INFO_MESSAGES.PROVIDER_ERROR('Snyk', error.message)), config.logMode); return { found: false }; } } }