UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

175 lines • 8.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFixedVersionByDatasource = getFixedVersionByDatasource; exports.detectVulnerabilityAlerts = detectVulnerabilityAlerts; const tslib_1 = require("tslib"); const error_messages_1 = require("../../../constants/error-messages"); const logger_1 = require("../../../logger"); const crate_1 = require("../../../modules/datasource/crate"); const go_1 = require("../../../modules/datasource/go"); const maven_1 = require("../../../modules/datasource/maven"); const npm_1 = require("../../../modules/datasource/npm"); const nuget_1 = require("../../../modules/datasource/nuget"); const packagist_1 = require("../../../modules/datasource/packagist"); const pypi_1 = require("../../../modules/datasource/pypi"); const rubygems_1 = require("../../../modules/datasource/rubygems"); const platform_1 = require("../../../modules/platform"); const allVersioning = tslib_1.__importStar(require("../../../modules/versioning")); const composerVersioning = tslib_1.__importStar(require("../../../modules/versioning/composer")); const mavenVersioning = tslib_1.__importStar(require("../../../modules/versioning/maven")); const npmVersioning = tslib_1.__importStar(require("../../../modules/versioning/npm")); const pep440Versioning = tslib_1.__importStar(require("../../../modules/versioning/pep440")); const rubyVersioning = tslib_1.__importStar(require("../../../modules/versioning/ruby")); const semverVersioning = tslib_1.__importStar(require("../../../modules/versioning/semver")); const markdown_1 = require("../../../util/markdown"); function getFixedVersionByDatasource(fixedVersion, datasource) { if (datasource === maven_1.MavenDatasource.id || datasource === nuget_1.NugetDatasource.id) { return `[${fixedVersion},)`; } // crates.io, Go, Hackage, Hex, npm, RubyGems, PyPI return `>= ${fixedVersion}`; } // TODO can return `null` and `undefined` (#22198) async function detectVulnerabilityAlerts(input) { if (!input?.vulnerabilityAlerts) { return input; } if (input.vulnerabilityAlerts.enabled === false) { logger_1.logger.debug('Vulnerability alerts are disabled'); return input; } const alerts = await platform_1.platform.getVulnerabilityAlerts?.(); if (!alerts?.length) { logger_1.logger.debug('No vulnerability alerts found'); if (input.vulnerabilityAlertsOnly) { throw new Error(error_messages_1.NO_VULNERABILITY_ALERTS); } return input; } const config = { ...input }; const versionings = { 'github-tags': semverVersioning.id, go: semverVersioning.id, packagist: composerVersioning.id, maven: mavenVersioning.id, npm: npmVersioning.id, nuget: semverVersioning.id, pypi: pep440Versioning.id, rubygems: rubyVersioning.id, }; const combinedAlerts = {}; for (const alert of alerts) { try { if (alert.dismissed_reason) { continue; } if (!alert.security_vulnerability?.first_patched_version) { logger_1.logger.debug({ alert }, 'Vulnerability alert has no firstPatchedVersion - skipping'); continue; } const datasourceMapping = { composer: packagist_1.PackagistDatasource.id, go: go_1.GoDatasource.id, maven: maven_1.MavenDatasource.id, npm: npm_1.NpmDatasource.id, nuget: nuget_1.NugetDatasource.id, pip: pypi_1.PypiDatasource.id, rubygems: rubygems_1.RubygemsDatasource.id, rust: crate_1.CrateDatasource.id, }; const datasource = datasourceMapping[alert.security_vulnerability.package.ecosystem]; const depName = alert.security_vulnerability.package.name; const fileName = alert.dependency.manifest_path; const fileType = fileName.split('/').pop(); const firstPatchedVersion = alert.security_vulnerability.first_patched_version.identifier; const advisory = alert.security_advisory; combinedAlerts[fileName] ??= {}; combinedAlerts[fileName][datasource] ??= {}; combinedAlerts[fileName][datasource][depName] ??= { advisories: [], }; const alertDetails = combinedAlerts[fileName][datasource][depName]; alertDetails.advisories.push(advisory); const versioningApi = allVersioning.get(versionings[datasource]); if (versioningApi.isVersion(firstPatchedVersion)) { if (!alertDetails.firstPatchedVersion || versioningApi.isGreaterThan(firstPatchedVersion, alertDetails.firstPatchedVersion)) { alertDetails.firstPatchedVersion = firstPatchedVersion; } } else { logger_1.logger.debug('Invalid firstPatchedVersion: ' + firstPatchedVersion); } alertDetails.fileType = fileType; } catch (err) { logger_1.logger.warn({ err }, 'Error parsing vulnerability alert'); } } const alertPackageRules = []; config.remediations = {}; for (const [fileName, files] of Object.entries(combinedAlerts)) { for (const [datasource, dependencies] of Object.entries(files)) { for (const [depName, val] of Object.entries(dependencies)) { let prBodyNotes = []; try { prBodyNotes = ['### GitHub Vulnerability Alerts'].concat(val.advisories.map((advisory) => { const identifiers = advisory.identifiers; const description = advisory.description; let content = '#### '; let heading; if (identifiers.some((id) => id.type === 'CVE')) { heading = identifiers .filter((id) => id.type === 'CVE') .map((id) => id.value) .join(' / '); } else { heading = identifiers.map((id) => id.value).join(' / '); } if (advisory.references?.length) { heading = `[${heading}](${advisory.references[0].url})`; } content += heading; content += '\n\n'; content += (0, markdown_1.sanitizeMarkdown)(description); return content; })); } catch (err) /* istanbul ignore next */ { logger_1.logger.warn({ err }, 'Error generating vulnerability PR notes'); } // TODO: types (#22198) const matchFileNames = datasource === go_1.GoDatasource.id ? [fileName.replace('go.sum', 'go.mod')] : [fileName]; let matchRule = { matchDatasources: [datasource], matchPackageNames: [depName], matchFileNames, }; let matchCurrentVersion = `< ${val.firstPatchedVersion}`; if (datasource === maven_1.MavenDatasource.id || datasource === nuget_1.NugetDatasource.id) { matchCurrentVersion = `(,${val.firstPatchedVersion})`; } // Remediate only direct dependencies matchRule = { ...matchRule, matchCurrentVersion, vulnerabilityFixVersion: val.firstPatchedVersion, prBodyNotes, isVulnerabilityAlert: true, force: { ...config.vulnerabilityAlerts, }, }; alertPackageRules.push(matchRule); } } } logger_1.logger.debug({ alertPackageRules }, 'alert package rules'); config.packageRules = (config.packageRules ?? []).concat(alertPackageRules); return config; } //# sourceMappingURL=vulnerability.js.map