renovate 43.109.3 → 43.109.5

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.
@@ -1,4 +1,34 @@
1
+ import { MavenDatasource } from "../../modules/datasource/maven/index.js";
2
+ import { NugetDatasource } from "../../modules/datasource/nuget/index.js";
1
3
  //#region lib/util/vulnerability/utils.ts
4
+ /**
5
+ * Ecosystems/datasources that use Maven-style inclusive ranges for fixed versions: `[version,)`
6
+ */
7
+ const mavenStyleFixedEcosystems = new Set([MavenDatasource.id, NugetDatasource.id]);
8
+ /**
9
+ * Ecosystems/datasources that use Maven-style exclusive ranges for last-affected versions: `(version,)`
10
+ */
11
+ const mavenStyleLastAffectedEcosystems = new Set([MavenDatasource.id]);
12
+ /**
13
+ * Formats a fixed version as an allowed-version constraint appropriate for the ecosystem.
14
+ *
15
+ * @param fixedVersion - The first version that contains the fix
16
+ * @param ecosystem - Ecosystem or datasource name (e.g., 'maven', 'npm', 'nuget'). Checked in a case-insensitive manner.
17
+ */
18
+ function getFixedVersionConstraint(fixedVersion, ecosystem) {
19
+ if (mavenStyleFixedEcosystems.has(ecosystem.toLowerCase())) return `[${fixedVersion},)`;
20
+ return `>= ${fixedVersion}`;
21
+ }
22
+ /**
23
+ * Formats a last-affected version as an allowed-version constraint appropriate for the ecosystem.
24
+ *
25
+ * @param lastAffected - The last version known to be affected
26
+ * @param ecosystem - Ecosystem or datasource name. Checked in a case-insensitive manner.
27
+ */
28
+ function getLastAffectedVersionConstraint(lastAffected, ecosystem) {
29
+ if (mavenStyleLastAffectedEcosystems.has(ecosystem.toLowerCase())) return `(${lastAffected},)`;
30
+ return `> ${lastAffected}`;
31
+ }
2
32
  const severityOrder = {
3
33
  LOW: 1,
4
34
  MEDIUM: 2,
@@ -15,6 +45,6 @@ function getHighestVulnerabilitySeverity(parent, child) {
15
45
  return severityOrder[parentVulSeverity] >= severityOrder[childVulSeverity] ? parentVulSeverity : childVulSeverity;
16
46
  }
17
47
  //#endregion
18
- export { getHighestVulnerabilitySeverity };
48
+ export { getFixedVersionConstraint, getHighestVulnerabilitySeverity, getLastAffectedVersionConstraint };
19
49
 
20
50
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../lib/util/vulnerability/utils.ts"],"sourcesContent":["const severityOrder: Record<string, number> = {\n LOW: 1,\n MEDIUM: 2,\n MODERATE: 2,\n HIGH: 3,\n CRITICAL: 4,\n UNKNOWN: 5,\n};\n\nexport function getHighestVulnerabilitySeverity<\n T extends Record<string, any>,\n TChild extends Record<string, any> | undefined,\n>(parent: T, child: TChild): string {\n const parentVulSeverity = parent.vulnerabilitySeverity?.toUpperCase();\n const childVulSeverity = child?.vulnerabilitySeverity?.toUpperCase();\n\n if (childVulSeverity === undefined) {\n return parentVulSeverity;\n }\n\n if (parentVulSeverity === undefined) {\n return childVulSeverity;\n }\n\n return severityOrder[parentVulSeverity] >= severityOrder[childVulSeverity]\n ? parentVulSeverity\n : childVulSeverity;\n}\n"],"mappings":";AAAA,MAAM,gBAAwC;CAC5C,KAAK;CACL,QAAQ;CACR,UAAU;CACV,MAAM;CACN,UAAU;CACV,SAAS;CACV;AAED,SAAgB,gCAGd,QAAW,OAAuB;CAClC,MAAM,oBAAoB,OAAO,uBAAuB,aAAa;CACrE,MAAM,mBAAmB,OAAO,uBAAuB,aAAa;AAEpE,KAAI,qBAAqB,KAAA,EACvB,QAAO;AAGT,KAAI,sBAAsB,KAAA,EACxB,QAAO;AAGT,QAAO,cAAc,sBAAsB,cAAc,oBACrD,oBACA"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../lib/util/vulnerability/utils.ts"],"sourcesContent":["import { MavenDatasource } from '../../modules/datasource/maven/index.ts';\nimport { NugetDatasource } from '../../modules/datasource/nuget/index.ts';\n\n/**\n * Ecosystems/datasources that use Maven-style inclusive ranges for fixed versions: `[version,)`\n */\nconst mavenStyleFixedEcosystems = new Set([\n MavenDatasource.id,\n NugetDatasource.id,\n]);\n\n/**\n * Ecosystems/datasources that use Maven-style exclusive ranges for last-affected versions: `(version,)`\n */\nconst mavenStyleLastAffectedEcosystems = new Set([MavenDatasource.id]);\n\n/**\n * Formats a fixed version as an allowed-version constraint appropriate for the ecosystem.\n *\n * @param fixedVersion - The first version that contains the fix\n * @param ecosystem - Ecosystem or datasource name (e.g., 'maven', 'npm', 'nuget'). Checked in a case-insensitive manner.\n */\nexport function getFixedVersionConstraint(\n fixedVersion: string,\n ecosystem: string,\n): string {\n if (mavenStyleFixedEcosystems.has(ecosystem.toLowerCase())) {\n return `[${fixedVersion},)`;\n }\n return `>= ${fixedVersion}`;\n}\n\n/**\n * Formats a last-affected version as an allowed-version constraint appropriate for the ecosystem.\n *\n * @param lastAffected - The last version known to be affected\n * @param ecosystem - Ecosystem or datasource name. Checked in a case-insensitive manner.\n */\nexport function getLastAffectedVersionConstraint(\n lastAffected: string,\n ecosystem: string,\n): string {\n if (mavenStyleLastAffectedEcosystems.has(ecosystem.toLowerCase())) {\n return `(${lastAffected},)`;\n }\n return `> ${lastAffected}`;\n}\n\nconst severityOrder: Record<string, number> = {\n LOW: 1,\n MEDIUM: 2,\n MODERATE: 2,\n HIGH: 3,\n CRITICAL: 4,\n UNKNOWN: 5,\n};\n\nexport function getHighestVulnerabilitySeverity<\n T extends Record<string, any>,\n TChild extends Record<string, any> | undefined,\n>(parent: T, child: TChild): string {\n const parentVulSeverity = parent.vulnerabilitySeverity?.toUpperCase();\n const childVulSeverity = child?.vulnerabilitySeverity?.toUpperCase();\n\n if (childVulSeverity === undefined) {\n return parentVulSeverity;\n }\n\n if (parentVulSeverity === undefined) {\n return childVulSeverity;\n }\n\n return severityOrder[parentVulSeverity] >= severityOrder[childVulSeverity]\n ? parentVulSeverity\n : childVulSeverity;\n}\n"],"mappings":";;;;;;AAMA,MAAM,4BAA4B,IAAI,IAAI,CACxC,gBAAgB,IAChB,gBAAgB,GACjB,CAAC;;;;AAKF,MAAM,mCAAmC,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC;;;;;;;AAQtE,SAAgB,0BACd,cACA,WACQ;AACR,KAAI,0BAA0B,IAAI,UAAU,aAAa,CAAC,CACxD,QAAO,IAAI,aAAa;AAE1B,QAAO,MAAM;;;;;;;;AASf,SAAgB,iCACd,cACA,WACQ;AACR,KAAI,iCAAiC,IAAI,UAAU,aAAa,CAAC,CAC/D,QAAO,IAAI,aAAa;AAE1B,QAAO,KAAK;;AAGd,MAAM,gBAAwC;CAC5C,KAAK;CACL,QAAQ;CACR,UAAU;CACV,MAAM;CACN,UAAU;CACV,SAAS;CACV;AAED,SAAgB,gCAGd,QAAW,OAAuB;CAClC,MAAM,oBAAoB,OAAO,uBAAuB,aAAa;CACrE,MAAM,mBAAmB,OAAO,uBAAuB,aAAa;AAEpE,KAAI,qBAAqB,KAAA,EACvB,QAAO;AAGT,KAAI,sBAAsB,KAAA,EACxB,QAAO;AAGT,QAAO,cAAc,sBAAsB,cAAc,oBACrD,oBACA"}
@@ -17,6 +17,7 @@ import { id as id$4 } from "../../../modules/versioning/composer/index.js";
17
17
  import { get } from "../../../modules/versioning/index.js";
18
18
  import { PackagistDatasource } from "../../../modules/datasource/packagist/index.js";
19
19
  import { RubygemsDatasource } from "../../../modules/datasource/rubygems/index.js";
20
+ import "../../../util/vulnerability/utils.js";
20
21
  import { platform } from "../../../modules/platform/index.js";
21
22
  import { sanitizeMarkdown } from "../../../util/markdown.js";
22
23
  //#region lib/workers/repository/init/vulnerability.ts
@@ -1 +1 @@
1
- {"version":3,"file":"vulnerability.js","names":["semverVersioning.id","composerVersioning.id","mavenVersioning.id","pep440Versioning.id","rubyVersioning.id","allVersioning.get"],"sources":["../../../../lib/workers/repository/init/vulnerability.ts"],"sourcesContent":["import type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { NO_VULNERABILITY_ALERTS } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { CrateDatasource } from '../../../modules/datasource/crate/index.ts';\nimport { GithubTagsDatasource } from '../../../modules/datasource/github-tags/index.ts';\nimport { GoDatasource } from '../../../modules/datasource/go/index.ts';\nimport { MavenDatasource } from '../../../modules/datasource/maven/index.ts';\nimport { NpmDatasource } from '../../../modules/datasource/npm/index.ts';\nimport { NugetDatasource } from '../../../modules/datasource/nuget/index.ts';\nimport { PackagistDatasource } from '../../../modules/datasource/packagist/index.ts';\nimport { PypiDatasource } from '../../../modules/datasource/pypi/index.ts';\nimport { RubygemsDatasource } from '../../../modules/datasource/rubygems/index.ts';\nimport type { Ecosystem } from '../../../modules/platform/github/schema.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport * as composerVersioning from '../../../modules/versioning/composer/index.ts';\nimport * as allVersioning from '../../../modules/versioning/index.ts';\nimport * as mavenVersioning from '../../../modules/versioning/maven/index.ts';\nimport * as npmVersioning from '../../../modules/versioning/npm/index.ts';\nimport * as pep440Versioning from '../../../modules/versioning/pep440/index.ts';\nimport * as rubyVersioning from '../../../modules/versioning/ruby/index.ts';\nimport * as semverVersioning from '../../../modules/versioning/semver/index.ts';\nimport type { SecurityAdvisory } from '../../../types/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport { escapeRegExp } from '../../../util/regex.ts';\n\ntype Datasource = string;\ntype DependencyName = string;\ntype FileName = string;\n\ntype CombinedAlert = Record<\n FileName,\n Record<\n Datasource,\n Record<\n DependencyName,\n {\n advisories: SecurityAdvisory[];\n fileType?: string;\n firstPatchedVersion?: string;\n }\n >\n >\n>;\n\nexport function getFixedVersionByDatasource(\n fixedVersion: string,\n datasource: string,\n): string {\n if (datasource === MavenDatasource.id || datasource === NugetDatasource.id) {\n return `[${fixedVersion},)`;\n }\n\n // crates.io, Go, Hackage, Hex, npm, RubyGems, PyPI\n return `>= ${fixedVersion}`;\n}\n\n// TODO can return `null` and `undefined` (#22198)\nexport async function detectVulnerabilityAlerts(\n input: RenovateConfig,\n): Promise<RenovateConfig> {\n if (!input?.vulnerabilityAlerts) {\n return input;\n }\n if (input.vulnerabilityAlerts.enabled === false) {\n logger.debug('Vulnerability alerts are disabled');\n return input;\n }\n const alerts = await platform.getVulnerabilityAlerts?.();\n if (!alerts?.length) {\n logger.debug('No vulnerability alerts found');\n if (input.vulnerabilityAlertsOnly) {\n throw new Error(NO_VULNERABILITY_ALERTS);\n }\n return input;\n }\n const config = { ...input };\n const versionings: Record<string, string> = {\n 'github-tags': semverVersioning.id,\n go: semverVersioning.id,\n packagist: composerVersioning.id,\n maven: mavenVersioning.id,\n npm: npmVersioning.id,\n nuget: semverVersioning.id,\n pypi: pep440Versioning.id,\n rubygems: rubyVersioning.id,\n };\n const combinedAlerts: CombinedAlert = {};\n for (const alert of alerts) {\n try {\n if (alert.dismissed_reason) {\n continue;\n }\n if (!alert.security_vulnerability?.first_patched_version) {\n logger.debug(\n { alert },\n 'Vulnerability alert has no firstPatchedVersion - skipping',\n );\n continue;\n }\n const datasourceMapping: Record<Ecosystem, string> = {\n actions: GithubTagsDatasource.id,\n composer: PackagistDatasource.id,\n go: GoDatasource.id,\n maven: MavenDatasource.id,\n npm: NpmDatasource.id,\n nuget: NugetDatasource.id,\n pip: PypiDatasource.id,\n rubygems: RubygemsDatasource.id,\n rust: CrateDatasource.id,\n };\n const datasource =\n datasourceMapping[alert.security_vulnerability.package.ecosystem];\n const depName = alert.security_vulnerability.package.name;\n const fileName = alert.dependency.manifest_path;\n const fileType = fileName.split('/').pop();\n const firstPatchedVersion =\n alert.security_vulnerability.first_patched_version.identifier;\n const advisory = alert.security_advisory;\n\n combinedAlerts[fileName] ??= {};\n combinedAlerts[fileName][datasource] ??= {};\n combinedAlerts[fileName][datasource][depName] ??= {\n advisories: [],\n };\n const alertDetails = combinedAlerts[fileName][datasource][depName];\n alertDetails.advisories.push(advisory);\n const versioningApi = allVersioning.get(versionings[datasource]);\n if (versioningApi.isVersion(firstPatchedVersion)) {\n if (\n !alertDetails.firstPatchedVersion ||\n versioningApi.isGreaterThan(\n firstPatchedVersion,\n alertDetails.firstPatchedVersion,\n )\n ) {\n alertDetails.firstPatchedVersion = firstPatchedVersion;\n }\n } else {\n logger.debug('Invalid firstPatchedVersion: ' + firstPatchedVersion);\n }\n alertDetails.fileType = fileType;\n } catch (err) {\n logger.warn({ err }, 'Error parsing vulnerability alert');\n }\n }\n const alertPackageRules: PackageRule[] = [];\n config.remediations = {} as never;\n for (const [fileName, files] of Object.entries(combinedAlerts)) {\n for (const [datasource, dependencies] of Object.entries(files)) {\n for (const [depName, val] of Object.entries(dependencies)) {\n if (!val.firstPatchedVersion) {\n continue;\n }\n\n let prBodyNotes: string[] = [];\n try {\n prBodyNotes = ['### GitHub Vulnerability Alerts'].concat(\n val.advisories.map((advisory) => {\n const identifiers = advisory.identifiers;\n const description = advisory.description;\n let content = '#### ';\n let heading: string;\n if (identifiers.some((id) => id.type === 'CVE')) {\n heading = identifiers\n .filter((id) => id.type === 'CVE')\n .map((id) => id.value)\n .join(' / ');\n } else {\n heading = identifiers.map((id) => id.value).join(' / ');\n }\n if (advisory.references?.length) {\n heading = `[${heading}](${advisory.references[0].url})`;\n }\n content += heading;\n content += '\\n\\n';\n\n content += sanitizeMarkdown(description);\n return content;\n }),\n );\n } catch (err) /* istanbul ignore next */ {\n logger.warn({ err }, 'Error generating vulnerability PR notes');\n }\n // TODO: types (#22198)\n const matchFileNames =\n datasource === GoDatasource.id\n ? [fileName.replace('go.sum', 'go.mod')]\n : [fileName];\n let matchRule: PackageRule = {\n matchDatasources: [datasource],\n matchPackageNames: [depName],\n matchFileNames,\n };\n\n let matchCurrentVersion = `< ${val.firstPatchedVersion}`;\n if (\n datasource === MavenDatasource.id ||\n datasource === NugetDatasource.id\n ) {\n matchCurrentVersion = `(,${val.firstPatchedVersion})`;\n } else if (datasource === GithubTagsDatasource.id) {\n matchCurrentVersion = `!/^${escapeRegExp(val.firstPatchedVersion)}$/`;\n }\n\n // Remediate only direct dependencies\n matchRule = {\n ...matchRule,\n matchCurrentVersion,\n vulnerabilityFixVersion: val.firstPatchedVersion,\n prBodyNotes,\n isVulnerabilityAlert: true,\n force: {\n ...config.vulnerabilityAlerts,\n },\n };\n alertPackageRules.push(matchRule);\n }\n }\n }\n logger.debug({ alertPackageRules }, 'alert package rules');\n config.packageRules = (config.packageRules ?? []).concat(alertPackageRules);\n return config;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"vulnerability.js","names":["semverVersioning.id","composerVersioning.id","mavenVersioning.id","pep440Versioning.id","rubyVersioning.id","allVersioning.get"],"sources":["../../../../lib/workers/repository/init/vulnerability.ts"],"sourcesContent":["import type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { NO_VULNERABILITY_ALERTS } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { CrateDatasource } from '../../../modules/datasource/crate/index.ts';\nimport { GithubTagsDatasource } from '../../../modules/datasource/github-tags/index.ts';\nimport { GoDatasource } from '../../../modules/datasource/go/index.ts';\nimport { MavenDatasource } from '../../../modules/datasource/maven/index.ts';\nimport { NpmDatasource } from '../../../modules/datasource/npm/index.ts';\nimport { NugetDatasource } from '../../../modules/datasource/nuget/index.ts';\nimport { PackagistDatasource } from '../../../modules/datasource/packagist/index.ts';\nimport { PypiDatasource } from '../../../modules/datasource/pypi/index.ts';\nimport { RubygemsDatasource } from '../../../modules/datasource/rubygems/index.ts';\nimport type { Ecosystem } from '../../../modules/platform/github/schema.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport * as composerVersioning from '../../../modules/versioning/composer/index.ts';\nimport * as allVersioning from '../../../modules/versioning/index.ts';\nimport * as mavenVersioning from '../../../modules/versioning/maven/index.ts';\nimport * as npmVersioning from '../../../modules/versioning/npm/index.ts';\nimport * as pep440Versioning from '../../../modules/versioning/pep440/index.ts';\nimport * as rubyVersioning from '../../../modules/versioning/ruby/index.ts';\nimport * as semverVersioning from '../../../modules/versioning/semver/index.ts';\nimport type { SecurityAdvisory } from '../../../types/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport { escapeRegExp } from '../../../util/regex.ts';\nimport { getFixedVersionConstraint } from '../../../util/vulnerability/utils.ts';\n\ntype Datasource = string;\ntype DependencyName = string;\ntype FileName = string;\n\ntype CombinedAlert = Record<\n FileName,\n Record<\n Datasource,\n Record<\n DependencyName,\n {\n advisories: SecurityAdvisory[];\n fileType?: string;\n firstPatchedVersion?: string;\n }\n >\n >\n>;\n\nexport function getFixedVersionByDatasource(\n fixedVersion: string,\n datasource: string,\n): string {\n return getFixedVersionConstraint(fixedVersion, datasource);\n}\n\n// TODO can return `null` and `undefined` (#22198)\nexport async function detectVulnerabilityAlerts(\n input: RenovateConfig,\n): Promise<RenovateConfig> {\n if (!input?.vulnerabilityAlerts) {\n return input;\n }\n if (input.vulnerabilityAlerts.enabled === false) {\n logger.debug('Vulnerability alerts are disabled');\n return input;\n }\n const alerts = await platform.getVulnerabilityAlerts?.();\n if (!alerts?.length) {\n logger.debug('No vulnerability alerts found');\n if (input.vulnerabilityAlertsOnly) {\n throw new Error(NO_VULNERABILITY_ALERTS);\n }\n return input;\n }\n const config = { ...input };\n const versionings: Record<string, string> = {\n 'github-tags': semverVersioning.id,\n go: semverVersioning.id,\n packagist: composerVersioning.id,\n maven: mavenVersioning.id,\n npm: npmVersioning.id,\n nuget: semverVersioning.id,\n pypi: pep440Versioning.id,\n rubygems: rubyVersioning.id,\n };\n const combinedAlerts: CombinedAlert = {};\n for (const alert of alerts) {\n try {\n if (alert.dismissed_reason) {\n continue;\n }\n if (!alert.security_vulnerability?.first_patched_version) {\n logger.debug(\n { alert },\n 'Vulnerability alert has no firstPatchedVersion - skipping',\n );\n continue;\n }\n const datasourceMapping: Record<Ecosystem, string> = {\n actions: GithubTagsDatasource.id,\n composer: PackagistDatasource.id,\n go: GoDatasource.id,\n maven: MavenDatasource.id,\n npm: NpmDatasource.id,\n nuget: NugetDatasource.id,\n pip: PypiDatasource.id,\n rubygems: RubygemsDatasource.id,\n rust: CrateDatasource.id,\n };\n const datasource =\n datasourceMapping[alert.security_vulnerability.package.ecosystem];\n const depName = alert.security_vulnerability.package.name;\n const fileName = alert.dependency.manifest_path;\n const fileType = fileName.split('/').pop();\n const firstPatchedVersion =\n alert.security_vulnerability.first_patched_version.identifier;\n const advisory = alert.security_advisory;\n\n combinedAlerts[fileName] ??= {};\n combinedAlerts[fileName][datasource] ??= {};\n combinedAlerts[fileName][datasource][depName] ??= {\n advisories: [],\n };\n const alertDetails = combinedAlerts[fileName][datasource][depName];\n alertDetails.advisories.push(advisory);\n const versioningApi = allVersioning.get(versionings[datasource]);\n if (versioningApi.isVersion(firstPatchedVersion)) {\n if (\n !alertDetails.firstPatchedVersion ||\n versioningApi.isGreaterThan(\n firstPatchedVersion,\n alertDetails.firstPatchedVersion,\n )\n ) {\n alertDetails.firstPatchedVersion = firstPatchedVersion;\n }\n } else {\n logger.debug('Invalid firstPatchedVersion: ' + firstPatchedVersion);\n }\n alertDetails.fileType = fileType;\n } catch (err) {\n logger.warn({ err }, 'Error parsing vulnerability alert');\n }\n }\n const alertPackageRules: PackageRule[] = [];\n config.remediations = {} as never;\n for (const [fileName, files] of Object.entries(combinedAlerts)) {\n for (const [datasource, dependencies] of Object.entries(files)) {\n for (const [depName, val] of Object.entries(dependencies)) {\n if (!val.firstPatchedVersion) {\n continue;\n }\n\n let prBodyNotes: string[] = [];\n try {\n prBodyNotes = ['### GitHub Vulnerability Alerts'].concat(\n val.advisories.map((advisory) => {\n const identifiers = advisory.identifiers;\n const description = advisory.description;\n let content = '#### ';\n let heading: string;\n if (identifiers.some((id) => id.type === 'CVE')) {\n heading = identifiers\n .filter((id) => id.type === 'CVE')\n .map((id) => id.value)\n .join(' / ');\n } else {\n heading = identifiers.map((id) => id.value).join(' / ');\n }\n if (advisory.references?.length) {\n heading = `[${heading}](${advisory.references[0].url})`;\n }\n content += heading;\n content += '\\n\\n';\n\n content += sanitizeMarkdown(description);\n return content;\n }),\n );\n } catch (err) /* istanbul ignore next */ {\n logger.warn({ err }, 'Error generating vulnerability PR notes');\n }\n // TODO: types (#22198)\n const matchFileNames =\n datasource === GoDatasource.id\n ? [fileName.replace('go.sum', 'go.mod')]\n : [fileName];\n let matchRule: PackageRule = {\n matchDatasources: [datasource],\n matchPackageNames: [depName],\n matchFileNames,\n };\n\n let matchCurrentVersion = `< ${val.firstPatchedVersion}`;\n if (\n datasource === MavenDatasource.id ||\n datasource === NugetDatasource.id\n ) {\n matchCurrentVersion = `(,${val.firstPatchedVersion})`;\n } else if (datasource === GithubTagsDatasource.id) {\n matchCurrentVersion = `!/^${escapeRegExp(val.firstPatchedVersion)}$/`;\n }\n\n // Remediate only direct dependencies\n matchRule = {\n ...matchRule,\n matchCurrentVersion,\n vulnerabilityFixVersion: val.firstPatchedVersion,\n prBodyNotes,\n isVulnerabilityAlert: true,\n force: {\n ...config.vulnerabilityAlerts,\n },\n };\n alertPackageRules.push(matchRule);\n }\n }\n }\n logger.debug({ alertPackageRules }, 'alert package rules');\n config.packageRules = (config.packageRules ?? []).concat(alertPackageRules);\n return config;\n}\n"],"mappings":"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"}
@@ -5,6 +5,7 @@ import { instrument } from "../../../instrumentation/index.js";
5
5
  import { all } from "../../../util/promises.js";
6
6
  import { get } from "../../../modules/versioning/index.js";
7
7
  import { getDefaultVersioning } from "../../../modules/datasource/common.js";
8
+ import { getFixedVersionConstraint, getLastAffectedVersionConstraint } from "../../../util/vulnerability/utils.js";
8
9
  import { mergeChildConfig } from "../../../config/utils.js";
9
10
  import { getManagerConfig } from "../../../config/index.js";
10
11
  import { sanitizeMarkdown } from "../../../util/markdown.js";
@@ -196,12 +197,10 @@ var Vulnerabilities = class Vulnerabilities {
196
197
  return null;
197
198
  }
198
199
  getFixedVersionByEcosystem(fixedVersion, ecosystem) {
199
- if (ecosystem === "Maven" || ecosystem === "NuGet") return `[${fixedVersion},)`;
200
- return `>= ${fixedVersion}`;
200
+ return getFixedVersionConstraint(fixedVersion, ecosystem);
201
201
  }
202
202
  getLastAffectedByEcosystem(lastAffected, ecosystem) {
203
- if (ecosystem === "Maven") return `(${lastAffected},)`;
204
- return `> ${lastAffected}`;
203
+ return getLastAffectedVersionConstraint(lastAffected, ecosystem);
205
204
  }
206
205
  isVersionGt(version, other, versioningApi) {
207
206
  return versioningApi.isVersion(version) && versioningApi.isVersion(other) && versioningApi.isGreaterThan(version, other);
@@ -1 +1 @@
1
- {"version":3,"file":"vulnerabilities.js","names":["p.all","getVersioning"],"sources":["../../../../lib/workers/repository/process/vulnerabilities.ts"],"sourcesContent":["// TODO #22198\nimport type { Ecosystem, Osv } from '@renovatebot/osv-offline';\nimport { OsvOffline } from '@renovatebot/osv-offline';\nimport {\n isEmptyArray,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { CvssVector } from 'ae-cvss-calculator';\nimport * as _aeCvss from 'ae-cvss-calculator';\nimport { z } from 'zod/v3';\nimport { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';\nimport type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultVersioning } from '../../../modules/datasource/common.ts';\nimport type {\n PackageDependency,\n PackageFile,\n} from '../../../modules/manager/types.ts';\nimport type { VersioningApi } from '../../../modules/versioning/index.ts';\nimport { get as getVersioning } from '../../../modules/versioning/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { titleCase } from '../../../util/string.ts';\nimport type {\n DependencyVulnerabilities,\n SeverityDetails,\n Vulnerability,\n} from './types.ts';\n\nconst { fromVector } = (_aeCvss as unknown as { default: typeof _aeCvss })\n .default;\n\nexport class Vulnerabilities {\n private static osvOffline: Promise<OsvOffline> | undefined;\n\n private osvOffline: OsvOffline;\n\n private static readonly datasourceEcosystemMap: Record<\n string,\n Ecosystem | undefined\n > = {\n crate: 'crates.io',\n go: 'Go',\n hackage: 'Hackage',\n hex: 'Hex',\n maven: 'Maven',\n npm: 'npm',\n nuget: 'NuGet',\n packagist: 'Packagist',\n pypi: 'PyPI',\n rubygems: 'RubyGems',\n };\n\n private constructor(osvOffline: OsvOffline) {\n this.osvOffline = osvOffline;\n }\n\n private static initialize(): Promise<OsvOffline> {\n // no async here, so osv promise will only be created once\n Vulnerabilities.osvOffline ??= OsvOffline.create();\n return Vulnerabilities.osvOffline;\n }\n\n static async create(): Promise<Vulnerabilities> {\n // intialize osv only once\n const osvOffline = await Vulnerabilities.initialize();\n\n const instance = new Vulnerabilities(osvOffline);\n return instance;\n }\n\n async appendVulnerabilityPackageRules(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<void> {\n const dependencyVulnerabilities = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n\n config.packageRules ??= [];\n for (const {\n vulnerabilities,\n versioningApi,\n } of dependencyVulnerabilities) {\n const groupPackageRules: PackageRule[] = [];\n for (const vulnerability of vulnerabilities) {\n const rule = this.vulnerabilityToPackageRules(vulnerability);\n if (isNullOrUndefined(rule)) {\n continue;\n }\n groupPackageRules.push(rule);\n }\n this.sortByFixedVersion(groupPackageRules, versioningApi);\n\n config.packageRules.push(...groupPackageRules);\n }\n }\n\n async fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<Vulnerability[]> {\n const groups = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n return groups.flatMap((group) => group.vulnerabilities);\n }\n\n private async fetchDependencyVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<DependencyVulnerabilities[]> {\n const managers = Object.keys(packageFiles);\n const allManagerJobs = managers.map((manager) =>\n this.fetchManagerVulnerabilities(config, packageFiles, manager),\n );\n return (await Promise.all(allManagerJobs)).flat();\n }\n\n private async fetchManagerVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n manager: string,\n ): Promise<DependencyVulnerabilities[]> {\n const managerConfig = getManagerConfig(config, manager);\n const queue = packageFiles[manager].map(\n (pFile) => (): Promise<DependencyVulnerabilities[]> =>\n this.fetchManagerPackageFileVulnerabilities(managerConfig, pFile),\n );\n logger.trace(\n { manager, queueLength: queue.length },\n 'fetchManagerVulnerabilities starting',\n );\n const result = (await p.all(queue)).flat();\n logger.trace({ manager }, 'fetchManagerVulnerabilities finished');\n return result;\n }\n\n private async fetchManagerPackageFileVulnerabilities(\n managerConfig: RenovateConfig,\n pFile: PackageFile,\n ): Promise<DependencyVulnerabilities[]> {\n const { packageFile } = pFile;\n const packageFileConfig = mergeChildConfig(managerConfig, pFile);\n const { manager } = packageFileConfig;\n const queue = pFile.deps.map(\n (dep) => (): Promise<DependencyVulnerabilities | null> =>\n this.fetchDependencyVulnerability(packageFileConfig, dep),\n );\n logger.trace(\n { manager, packageFile, queueLength: queue.length },\n 'fetchManagerPackageFileVulnerabilities starting with concurrency',\n );\n\n const result = await p.all(queue);\n logger.trace(\n { packageFile },\n 'fetchManagerPackageFileVulnerabilities finished',\n );\n\n return result.filter(isTruthy);\n }\n\n private async fetchDependencyVulnerability(\n packageFileConfig: RenovateConfig & PackageFile,\n dep: PackageDependency,\n ): Promise<DependencyVulnerabilities | null> {\n const ecosystem = Vulnerabilities.datasourceEcosystemMap[dep.datasource!];\n if (!ecosystem) {\n logger.trace(`Cannot map datasource ${dep.datasource!} to OSV ecosystem`);\n return null;\n }\n\n let packageName = dep.packageName ?? dep.depName!;\n if (ecosystem === 'PyPI') {\n // https://peps.python.org/pep-0503/#normalized-names\n packageName = packageName.toLowerCase().replace(regEx(/[_.-]+/g), '-');\n }\n\n try {\n const osvVulnerabilities = await instrument(\n 'get OSV vulnerabilities',\n () => this.osvOffline.getVulnerabilities(ecosystem, packageName),\n {\n attributes: {\n packageName,\n ecosystem,\n },\n },\n );\n if (\n isNullOrUndefined(osvVulnerabilities) ||\n isEmptyArray(osvVulnerabilities)\n ) {\n logger.trace(\n `No vulnerabilities found in OSV database for ${packageName}`,\n );\n return null;\n }\n\n const depVersion =\n dep.lockedVersion ?? dep.currentVersion ?? dep.currentValue!;\n\n const versioning = dep.versioning ?? getDefaultVersioning(dep.datasource);\n const versioningApi = getVersioning(versioning);\n\n if (!versioningApi.isVersion(depVersion)) {\n logger.debug(\n `Skipping vulnerability lookup for package ${packageName} due to unsupported version ${depVersion}`,\n );\n return null;\n }\n\n const vulnerabilities: Vulnerability[] = [];\n for (const osvVulnerability of osvVulnerabilities) {\n if (osvVulnerability.withdrawn) {\n logger.trace(\n `Skipping withdrawn vulnerability ${osvVulnerability.id}`,\n );\n continue;\n }\n\n for (const affected of osvVulnerability.affected ?? []) {\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n packageName,\n depVersion,\n affected,\n versioningApi,\n );\n if (!isVulnerable) {\n continue;\n }\n\n logger.debug(\n `Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`,\n );\n const fixedVersion = this.getFixedVersion(\n ecosystem,\n depVersion,\n affected,\n versioningApi,\n );\n\n vulnerabilities.push({\n packageName,\n vulnerability: osvVulnerability,\n affected,\n depVersion,\n fixedVersion,\n datasource: dep.datasource!,\n packageFileConfig,\n });\n }\n }\n\n return { vulnerabilities, versioningApi };\n } catch (err) {\n logger.warn(\n { err, packageName },\n 'Error fetching vulnerability information for package',\n );\n return null;\n }\n }\n\n private sortByFixedVersion(\n packageRules: PackageRule[],\n versioningApi: VersioningApi,\n ): void {\n const versionsCleaned: Record<string, string> = {};\n for (const rule of packageRules) {\n const version = rule.allowedVersions!;\n versionsCleaned[version] = version.replace(regEx(/[(),=> ]+/g), '');\n }\n packageRules.sort((a, b) =>\n versioningApi.sortVersions(\n versionsCleaned[a.allowedVersions!],\n versionsCleaned[b.allowedVersions!],\n ),\n );\n }\n\n // https://ossf.github.io/osv-schema/#affectedrangesevents-fields\n private sortEvents(\n events: Osv.Event[],\n versioningApi: VersioningApi,\n ): Osv.Event[] {\n const sortedCopy: Osv.Event[] = [];\n let zeroEvent: Osv.Event | null = null;\n\n for (const event of events) {\n if (event.introduced === '0') {\n zeroEvent = event;\n } else if (versioningApi.isVersion(Object.values(event)[0])) {\n sortedCopy.push(event);\n } else {\n logger.debug({ event }, 'Skipping OSV event with invalid version');\n }\n }\n\n sortedCopy.sort((a, b) =>\n // no pre-processing, as there are only very few values to sort\n versioningApi.sortVersions(Object.values(a)[0], Object.values(b)[0]),\n );\n\n if (zeroEvent) {\n sortedCopy.unshift(zeroEvent);\n }\n\n return sortedCopy;\n }\n\n private isPackageAffected(\n ecosystem: Ecosystem,\n packageName: string,\n affected: Osv.Affected,\n ): boolean {\n return (\n affected.package?.name === packageName &&\n affected.package?.ecosystem === ecosystem\n );\n }\n\n private includedInVersions(\n depVersion: string,\n affected: Osv.Affected,\n ): boolean {\n return !!affected.versions?.includes(depVersion);\n }\n\n private includedInRanges(\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n let vulnerable = false;\n for (const event of this.sortEvents(range.events, versioningApi)) {\n if (\n isNonEmptyString(event.introduced) &&\n (event.introduced === '0' ||\n this.isVersionGtOrEq(depVersion, event.introduced, versioningApi))\n ) {\n vulnerable = true;\n } else if (\n isNonEmptyString(event.fixed) &&\n this.isVersionGtOrEq(depVersion, event.fixed, versioningApi)\n ) {\n vulnerable = false;\n } else if (\n isNonEmptyString(event.last_affected) &&\n this.isVersionGt(depVersion, event.last_affected, versioningApi)\n ) {\n vulnerable = false;\n }\n }\n\n if (vulnerable) {\n return true;\n }\n }\n\n return false;\n }\n\n // https://ossf.github.io/osv-schema/#evaluation\n private isPackageVulnerable(\n ecosystem: Ecosystem,\n packageName: string,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n this.isPackageAffected(ecosystem, packageName, affected) &&\n (this.includedInVersions(depVersion, affected) ||\n this.includedInRanges(depVersion, affected, versioningApi))\n );\n }\n\n private getFixedVersion(\n ecosystem: Ecosystem,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): string | null {\n const fixedVersions: string[] = [];\n const lastAffectedVersions: string[] = [];\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n for (const event of range.events) {\n if (\n isNonEmptyString(event.fixed) &&\n versioningApi.isVersion(event.fixed)\n ) {\n fixedVersions.push(event.fixed);\n } else if (\n isNonEmptyString(event.last_affected) &&\n versioningApi.isVersion(event.last_affected)\n ) {\n lastAffectedVersions.push(event.last_affected);\n }\n }\n }\n\n fixedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const fixedVersion = fixedVersions.find((version) =>\n this.isVersionGt(version, depVersion, versioningApi),\n );\n if (fixedVersion) {\n return this.getFixedVersionByEcosystem(fixedVersion, ecosystem);\n }\n\n lastAffectedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const lastAffected = lastAffectedVersions.find((version) =>\n this.isVersionGtOrEq(version, depVersion, versioningApi),\n );\n if (lastAffected) {\n return this.getLastAffectedByEcosystem(lastAffected, ecosystem);\n }\n\n return null;\n }\n\n private getFixedVersionByEcosystem(\n fixedVersion: string,\n ecosystem: Ecosystem,\n ): string {\n if (ecosystem === 'Maven' || ecosystem === 'NuGet') {\n return `[${fixedVersion},)`;\n }\n\n // crates.io, Go, Hex, npm, RubyGems, PyPI\n return `>= ${fixedVersion}`;\n }\n\n private getLastAffectedByEcosystem(\n lastAffected: string,\n ecosystem: Ecosystem,\n ): string {\n if (ecosystem === 'Maven') {\n return `(${lastAffected},)`;\n }\n\n // crates.io, Go, Hex, npm, RubyGems, PyPI\n return `> ${lastAffected}`;\n }\n\n private isVersionGt(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n versioningApi.isGreaterThan(version, other)\n );\n }\n\n private isVersionGtOrEq(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n (versioningApi.equals(version, other) ||\n versioningApi.isGreaterThan(version, other))\n );\n }\n\n private vulnerabilityToPackageRules(vul: Vulnerability): PackageRule | null {\n const {\n vulnerability,\n affected,\n packageName,\n depVersion,\n fixedVersion,\n datasource,\n packageFileConfig,\n } = vul;\n if (isNullOrUndefined(fixedVersion)) {\n logger.debug(\n `No fixed version available for vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n return null;\n }\n\n logger.debug(\n `Setting allowed version ${fixedVersion} to fix vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n return {\n matchDatasources: [datasource],\n matchPackageNames: [packageName],\n matchCurrentVersion: depVersion,\n allowedVersions: fixedVersion,\n isVulnerabilityAlert: true,\n vulnerabilitySeverity: severityDetails.severityLevel,\n prBodyNotes: this.generatePrBodyNotes(vulnerability, affected),\n force: {\n ...packageFileConfig.vulnerabilityAlerts,\n },\n };\n }\n\n static evaluateCvssVector(vector: string): [string, string] {\n const CvssJsonSchema = z.object({\n baseScore: z.number().default(0.0),\n baseSeverity: z.string().toUpperCase().default('UNKNOWN'),\n });\n\n try {\n const parsedCvssScore: CvssVector<any> | null = fromVector(vector);\n const res = CvssJsonSchema.parse(parsedCvssScore?.createJsonSchema());\n\n return [res.baseScore.toFixed(1), res.baseSeverity];\n } catch {\n logger.debug(`Error processing CVSS vector ${vector}`);\n }\n\n return ['', ''];\n }\n\n private generatePrBodyNotes(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): string[] {\n let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();\n aliases = aliases.map((id) => {\n if (id.startsWith('CVE-')) {\n return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;\n } else if (id.startsWith('GHSA-')) {\n return `[${id}](https://github.com/advisories/${id})`;\n } else if (id.startsWith('GO-')) {\n return `[${id}](https://pkg.go.dev/vuln/${id})`;\n } else if (id.startsWith('RUSTSEC-')) {\n return `[${id}](https://rustsec.org/advisories/${id}.html)`;\n }\n\n return id;\n });\n\n let content = '\\n\\n---\\n\\n### ';\n content += vulnerability.summary ? `${vulnerability.summary}\\n` : '';\n content += `${aliases.join(' / ')}\\n`;\n content += `\\n<details>\\n<summary>More information</summary>\\n`;\n\n const details = vulnerability.details?.replace(\n regEx(/^#{1,4} /gm),\n '##### ',\n );\n content += `#### Details\\n${details ?? 'No details.'}\\n`;\n\n content += '#### Severity\\n';\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n if (severityDetails.cvssVector) {\n content += `- CVSS Score: ${severityDetails.score}\\n`;\n content += `- Vector String: \\`${severityDetails.cvssVector}\\`\\n`;\n } else {\n content += `${titleCase(severityDetails.severityLevel)}\\n`;\n }\n\n content += `\\n#### References\\n${\n vulnerability.references\n ?.map((ref) => {\n return `- [${ref.url}](${ref.url})`;\n })\n .join('\\n') ?? 'No references.'\n }`;\n\n let attribution = '';\n if (vulnerability.id.startsWith('GHSA-')) {\n attribution = ` and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md))`;\n } else if (vulnerability.id.startsWith('GO-')) {\n attribution = ` and the [Go Vulnerability Database](https://github.com/golang/vulndb) ([CC-BY 4.0](https://github.com/golang/vulndb#license))`;\n } else if (vulnerability.id.startsWith('PYSEC-')) {\n attribution = ` and the [PyPI Advisory Database](https://github.com/pypa/advisory-database) ([CC-BY 4.0](https://github.com/pypa/advisory-database/blob/main/LICENSE))`;\n } else if (vulnerability.id.startsWith('RUSTSEC-')) {\n attribution = ` and the [Rust Advisory Database](https://github.com/RustSec/advisory-db) ([CC0 1.0](https://github.com/rustsec/advisory-db/blob/main/LICENSE.txt))`;\n }\n content += `\\n\\nThis data is provided by [OSV](https://osv.dev/vulnerability/${vulnerability.id})${attribution}.\\n`;\n content += `</details>`;\n\n return [sanitizeMarkdown(content)];\n }\n\n private extractSeverityDetails(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): SeverityDetails {\n let severityLevel = 'UNKNOWN';\n let score = 'Unknown';\n\n const cvssVector =\n vulnerability.severity?.find((e) => e.type === 'CVSS_V4')?.score ??\n vulnerability.severity?.find((e) => e.type === 'CVSS_V3')?.score ??\n (affected.database_specific?.cvss as string); // RUSTSEC\n\n if (cvssVector) {\n const [baseScore, severity] =\n Vulnerabilities.evaluateCvssVector(cvssVector);\n severityLevel = severity ? severity.toUpperCase() : 'UNKNOWN';\n score = baseScore\n ? `${baseScore} / 10 (${titleCase(severityLevel)})`\n : 'Unknown';\n } else if (\n vulnerability.id.startsWith('GHSA-') &&\n vulnerability.database_specific?.severity\n ) {\n const severity = vulnerability.database_specific.severity as string;\n severityLevel = severity.toUpperCase();\n }\n\n return {\n cvssVector,\n score,\n severityLevel,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"vulnerabilities.js","names":["p.all","getVersioning"],"sources":["../../../../lib/workers/repository/process/vulnerabilities.ts"],"sourcesContent":["// TODO #22198\nimport type { Ecosystem, Osv } from '@renovatebot/osv-offline';\nimport { OsvOffline } from '@renovatebot/osv-offline';\nimport {\n isEmptyArray,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { CvssVector } from 'ae-cvss-calculator';\nimport * as _aeCvss from 'ae-cvss-calculator';\nimport { z } from 'zod/v3';\nimport { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';\nimport type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultVersioning } from '../../../modules/datasource/common.ts';\nimport type {\n PackageDependency,\n PackageFile,\n} from '../../../modules/manager/types.ts';\nimport type { VersioningApi } from '../../../modules/versioning/index.ts';\nimport { get as getVersioning } from '../../../modules/versioning/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { titleCase } from '../../../util/string.ts';\nimport {\n getFixedVersionConstraint,\n getLastAffectedVersionConstraint,\n} from '../../../util/vulnerability/utils.ts';\nimport type {\n DependencyVulnerabilities,\n SeverityDetails,\n Vulnerability,\n} from './types.ts';\n\nconst { fromVector } = (_aeCvss as unknown as { default: typeof _aeCvss })\n .default;\n\nexport class Vulnerabilities {\n private static osvOffline: Promise<OsvOffline> | undefined;\n\n private osvOffline: OsvOffline;\n\n private static readonly datasourceEcosystemMap: Record<\n string,\n Ecosystem | undefined\n > = {\n crate: 'crates.io',\n go: 'Go',\n hackage: 'Hackage',\n hex: 'Hex',\n maven: 'Maven',\n npm: 'npm',\n nuget: 'NuGet',\n packagist: 'Packagist',\n pypi: 'PyPI',\n rubygems: 'RubyGems',\n };\n\n private constructor(osvOffline: OsvOffline) {\n this.osvOffline = osvOffline;\n }\n\n private static initialize(): Promise<OsvOffline> {\n // no async here, so osv promise will only be created once\n Vulnerabilities.osvOffline ??= OsvOffline.create();\n return Vulnerabilities.osvOffline;\n }\n\n static async create(): Promise<Vulnerabilities> {\n // intialize osv only once\n const osvOffline = await Vulnerabilities.initialize();\n\n const instance = new Vulnerabilities(osvOffline);\n return instance;\n }\n\n async appendVulnerabilityPackageRules(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<void> {\n const dependencyVulnerabilities = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n\n config.packageRules ??= [];\n for (const {\n vulnerabilities,\n versioningApi,\n } of dependencyVulnerabilities) {\n const groupPackageRules: PackageRule[] = [];\n for (const vulnerability of vulnerabilities) {\n const rule = this.vulnerabilityToPackageRules(vulnerability);\n if (isNullOrUndefined(rule)) {\n continue;\n }\n groupPackageRules.push(rule);\n }\n this.sortByFixedVersion(groupPackageRules, versioningApi);\n\n config.packageRules.push(...groupPackageRules);\n }\n }\n\n async fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<Vulnerability[]> {\n const groups = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n return groups.flatMap((group) => group.vulnerabilities);\n }\n\n private async fetchDependencyVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<DependencyVulnerabilities[]> {\n const managers = Object.keys(packageFiles);\n const allManagerJobs = managers.map((manager) =>\n this.fetchManagerVulnerabilities(config, packageFiles, manager),\n );\n return (await Promise.all(allManagerJobs)).flat();\n }\n\n private async fetchManagerVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n manager: string,\n ): Promise<DependencyVulnerabilities[]> {\n const managerConfig = getManagerConfig(config, manager);\n const queue = packageFiles[manager].map(\n (pFile) => (): Promise<DependencyVulnerabilities[]> =>\n this.fetchManagerPackageFileVulnerabilities(managerConfig, pFile),\n );\n logger.trace(\n { manager, queueLength: queue.length },\n 'fetchManagerVulnerabilities starting',\n );\n const result = (await p.all(queue)).flat();\n logger.trace({ manager }, 'fetchManagerVulnerabilities finished');\n return result;\n }\n\n private async fetchManagerPackageFileVulnerabilities(\n managerConfig: RenovateConfig,\n pFile: PackageFile,\n ): Promise<DependencyVulnerabilities[]> {\n const { packageFile } = pFile;\n const packageFileConfig = mergeChildConfig(managerConfig, pFile);\n const { manager } = packageFileConfig;\n const queue = pFile.deps.map(\n (dep) => (): Promise<DependencyVulnerabilities | null> =>\n this.fetchDependencyVulnerability(packageFileConfig, dep),\n );\n logger.trace(\n { manager, packageFile, queueLength: queue.length },\n 'fetchManagerPackageFileVulnerabilities starting with concurrency',\n );\n\n const result = await p.all(queue);\n logger.trace(\n { packageFile },\n 'fetchManagerPackageFileVulnerabilities finished',\n );\n\n return result.filter(isTruthy);\n }\n\n private async fetchDependencyVulnerability(\n packageFileConfig: RenovateConfig & PackageFile,\n dep: PackageDependency,\n ): Promise<DependencyVulnerabilities | null> {\n const ecosystem = Vulnerabilities.datasourceEcosystemMap[dep.datasource!];\n if (!ecosystem) {\n logger.trace(`Cannot map datasource ${dep.datasource!} to OSV ecosystem`);\n return null;\n }\n\n let packageName = dep.packageName ?? dep.depName!;\n if (ecosystem === 'PyPI') {\n // https://peps.python.org/pep-0503/#normalized-names\n packageName = packageName.toLowerCase().replace(regEx(/[_.-]+/g), '-');\n }\n\n try {\n const osvVulnerabilities = await instrument(\n 'get OSV vulnerabilities',\n () => this.osvOffline.getVulnerabilities(ecosystem, packageName),\n {\n attributes: {\n packageName,\n ecosystem,\n },\n },\n );\n if (\n isNullOrUndefined(osvVulnerabilities) ||\n isEmptyArray(osvVulnerabilities)\n ) {\n logger.trace(\n `No vulnerabilities found in OSV database for ${packageName}`,\n );\n return null;\n }\n\n const depVersion =\n dep.lockedVersion ?? dep.currentVersion ?? dep.currentValue!;\n\n const versioning = dep.versioning ?? getDefaultVersioning(dep.datasource);\n const versioningApi = getVersioning(versioning);\n\n if (!versioningApi.isVersion(depVersion)) {\n logger.debug(\n `Skipping vulnerability lookup for package ${packageName} due to unsupported version ${depVersion}`,\n );\n return null;\n }\n\n const vulnerabilities: Vulnerability[] = [];\n for (const osvVulnerability of osvVulnerabilities) {\n if (osvVulnerability.withdrawn) {\n logger.trace(\n `Skipping withdrawn vulnerability ${osvVulnerability.id}`,\n );\n continue;\n }\n\n for (const affected of osvVulnerability.affected ?? []) {\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n packageName,\n depVersion,\n affected,\n versioningApi,\n );\n if (!isVulnerable) {\n continue;\n }\n\n logger.debug(\n `Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`,\n );\n const fixedVersion = this.getFixedVersion(\n ecosystem,\n depVersion,\n affected,\n versioningApi,\n );\n\n vulnerabilities.push({\n packageName,\n vulnerability: osvVulnerability,\n affected,\n depVersion,\n fixedVersion,\n datasource: dep.datasource!,\n packageFileConfig,\n });\n }\n }\n\n return { vulnerabilities, versioningApi };\n } catch (err) {\n logger.warn(\n { err, packageName },\n 'Error fetching vulnerability information for package',\n );\n return null;\n }\n }\n\n private sortByFixedVersion(\n packageRules: PackageRule[],\n versioningApi: VersioningApi,\n ): void {\n const versionsCleaned: Record<string, string> = {};\n for (const rule of packageRules) {\n const version = rule.allowedVersions!;\n versionsCleaned[version] = version.replace(regEx(/[(),=> ]+/g), '');\n }\n packageRules.sort((a, b) =>\n versioningApi.sortVersions(\n versionsCleaned[a.allowedVersions!],\n versionsCleaned[b.allowedVersions!],\n ),\n );\n }\n\n // https://ossf.github.io/osv-schema/#affectedrangesevents-fields\n private sortEvents(\n events: Osv.Event[],\n versioningApi: VersioningApi,\n ): Osv.Event[] {\n const sortedCopy: Osv.Event[] = [];\n let zeroEvent: Osv.Event | null = null;\n\n for (const event of events) {\n if (event.introduced === '0') {\n zeroEvent = event;\n } else if (versioningApi.isVersion(Object.values(event)[0])) {\n sortedCopy.push(event);\n } else {\n logger.debug({ event }, 'Skipping OSV event with invalid version');\n }\n }\n\n sortedCopy.sort((a, b) =>\n // no pre-processing, as there are only very few values to sort\n versioningApi.sortVersions(Object.values(a)[0], Object.values(b)[0]),\n );\n\n if (zeroEvent) {\n sortedCopy.unshift(zeroEvent);\n }\n\n return sortedCopy;\n }\n\n private isPackageAffected(\n ecosystem: Ecosystem,\n packageName: string,\n affected: Osv.Affected,\n ): boolean {\n return (\n affected.package?.name === packageName &&\n affected.package?.ecosystem === ecosystem\n );\n }\n\n private includedInVersions(\n depVersion: string,\n affected: Osv.Affected,\n ): boolean {\n return !!affected.versions?.includes(depVersion);\n }\n\n private includedInRanges(\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n let vulnerable = false;\n for (const event of this.sortEvents(range.events, versioningApi)) {\n if (\n isNonEmptyString(event.introduced) &&\n (event.introduced === '0' ||\n this.isVersionGtOrEq(depVersion, event.introduced, versioningApi))\n ) {\n vulnerable = true;\n } else if (\n isNonEmptyString(event.fixed) &&\n this.isVersionGtOrEq(depVersion, event.fixed, versioningApi)\n ) {\n vulnerable = false;\n } else if (\n isNonEmptyString(event.last_affected) &&\n this.isVersionGt(depVersion, event.last_affected, versioningApi)\n ) {\n vulnerable = false;\n }\n }\n\n if (vulnerable) {\n return true;\n }\n }\n\n return false;\n }\n\n // https://ossf.github.io/osv-schema/#evaluation\n private isPackageVulnerable(\n ecosystem: Ecosystem,\n packageName: string,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n this.isPackageAffected(ecosystem, packageName, affected) &&\n (this.includedInVersions(depVersion, affected) ||\n this.includedInRanges(depVersion, affected, versioningApi))\n );\n }\n\n private getFixedVersion(\n ecosystem: Ecosystem,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): string | null {\n const fixedVersions: string[] = [];\n const lastAffectedVersions: string[] = [];\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n for (const event of range.events) {\n if (\n isNonEmptyString(event.fixed) &&\n versioningApi.isVersion(event.fixed)\n ) {\n fixedVersions.push(event.fixed);\n } else if (\n isNonEmptyString(event.last_affected) &&\n versioningApi.isVersion(event.last_affected)\n ) {\n lastAffectedVersions.push(event.last_affected);\n }\n }\n }\n\n fixedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const fixedVersion = fixedVersions.find((version) =>\n this.isVersionGt(version, depVersion, versioningApi),\n );\n if (fixedVersion) {\n return this.getFixedVersionByEcosystem(fixedVersion, ecosystem);\n }\n\n lastAffectedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const lastAffected = lastAffectedVersions.find((version) =>\n this.isVersionGtOrEq(version, depVersion, versioningApi),\n );\n if (lastAffected) {\n return this.getLastAffectedByEcosystem(lastAffected, ecosystem);\n }\n\n return null;\n }\n\n private getFixedVersionByEcosystem(\n fixedVersion: string,\n ecosystem: Ecosystem,\n ): string {\n return getFixedVersionConstraint(fixedVersion, ecosystem);\n }\n\n private getLastAffectedByEcosystem(\n lastAffected: string,\n ecosystem: Ecosystem,\n ): string {\n return getLastAffectedVersionConstraint(lastAffected, ecosystem);\n }\n\n private isVersionGt(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n versioningApi.isGreaterThan(version, other)\n );\n }\n\n private isVersionGtOrEq(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n (versioningApi.equals(version, other) ||\n versioningApi.isGreaterThan(version, other))\n );\n }\n\n private vulnerabilityToPackageRules(vul: Vulnerability): PackageRule | null {\n const {\n vulnerability,\n affected,\n packageName,\n depVersion,\n fixedVersion,\n datasource,\n packageFileConfig,\n } = vul;\n if (isNullOrUndefined(fixedVersion)) {\n logger.debug(\n `No fixed version available for vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n return null;\n }\n\n logger.debug(\n `Setting allowed version ${fixedVersion} to fix vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n return {\n matchDatasources: [datasource],\n matchPackageNames: [packageName],\n matchCurrentVersion: depVersion,\n allowedVersions: fixedVersion,\n isVulnerabilityAlert: true,\n vulnerabilitySeverity: severityDetails.severityLevel,\n prBodyNotes: this.generatePrBodyNotes(vulnerability, affected),\n force: {\n ...packageFileConfig.vulnerabilityAlerts,\n },\n };\n }\n\n static evaluateCvssVector(vector: string): [string, string] {\n const CvssJsonSchema = z.object({\n baseScore: z.number().default(0.0),\n baseSeverity: z.string().toUpperCase().default('UNKNOWN'),\n });\n\n try {\n const parsedCvssScore: CvssVector<any> | null = fromVector(vector);\n const res = CvssJsonSchema.parse(parsedCvssScore?.createJsonSchema());\n\n return [res.baseScore.toFixed(1), res.baseSeverity];\n } catch {\n logger.debug(`Error processing CVSS vector ${vector}`);\n }\n\n return ['', ''];\n }\n\n private generatePrBodyNotes(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): string[] {\n let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();\n aliases = aliases.map((id) => {\n if (id.startsWith('CVE-')) {\n return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;\n } else if (id.startsWith('GHSA-')) {\n return `[${id}](https://github.com/advisories/${id})`;\n } else if (id.startsWith('GO-')) {\n return `[${id}](https://pkg.go.dev/vuln/${id})`;\n } else if (id.startsWith('RUSTSEC-')) {\n return `[${id}](https://rustsec.org/advisories/${id}.html)`;\n }\n\n return id;\n });\n\n let content = '\\n\\n---\\n\\n### ';\n content += vulnerability.summary ? `${vulnerability.summary}\\n` : '';\n content += `${aliases.join(' / ')}\\n`;\n content += `\\n<details>\\n<summary>More information</summary>\\n`;\n\n const details = vulnerability.details?.replace(\n regEx(/^#{1,4} /gm),\n '##### ',\n );\n content += `#### Details\\n${details ?? 'No details.'}\\n`;\n\n content += '#### Severity\\n';\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n if (severityDetails.cvssVector) {\n content += `- CVSS Score: ${severityDetails.score}\\n`;\n content += `- Vector String: \\`${severityDetails.cvssVector}\\`\\n`;\n } else {\n content += `${titleCase(severityDetails.severityLevel)}\\n`;\n }\n\n content += `\\n#### References\\n${\n vulnerability.references\n ?.map((ref) => {\n return `- [${ref.url}](${ref.url})`;\n })\n .join('\\n') ?? 'No references.'\n }`;\n\n let attribution = '';\n if (vulnerability.id.startsWith('GHSA-')) {\n attribution = ` and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md))`;\n } else if (vulnerability.id.startsWith('GO-')) {\n attribution = ` and the [Go Vulnerability Database](https://github.com/golang/vulndb) ([CC-BY 4.0](https://github.com/golang/vulndb#license))`;\n } else if (vulnerability.id.startsWith('PYSEC-')) {\n attribution = ` and the [PyPI Advisory Database](https://github.com/pypa/advisory-database) ([CC-BY 4.0](https://github.com/pypa/advisory-database/blob/main/LICENSE))`;\n } else if (vulnerability.id.startsWith('RUSTSEC-')) {\n attribution = ` and the [Rust Advisory Database](https://github.com/RustSec/advisory-db) ([CC0 1.0](https://github.com/rustsec/advisory-db/blob/main/LICENSE.txt))`;\n }\n content += `\\n\\nThis data is provided by [OSV](https://osv.dev/vulnerability/${vulnerability.id})${attribution}.\\n`;\n content += `</details>`;\n\n return [sanitizeMarkdown(content)];\n }\n\n private extractSeverityDetails(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): SeverityDetails {\n let severityLevel = 'UNKNOWN';\n let score = 'Unknown';\n\n const cvssVector =\n vulnerability.severity?.find((e) => e.type === 'CVSS_V4')?.score ??\n vulnerability.severity?.find((e) => e.type === 'CVSS_V3')?.score ??\n (affected.database_specific?.cvss as string); // RUSTSEC\n\n if (cvssVector) {\n const [baseScore, severity] =\n Vulnerabilities.evaluateCvssVector(cvssVector);\n severityLevel = severity ? severity.toUpperCase() : 'UNKNOWN';\n score = baseScore\n ? `${baseScore} / 10 (${titleCase(severityLevel)})`\n : 'Unknown';\n } else if (\n vulnerability.id.startsWith('GHSA-') &&\n vulnerability.database_specific?.severity\n ) {\n const severity = vulnerability.database_specific.severity as string;\n severityLevel = severity.toUpperCase();\n }\n\n return {\n cvssVector,\n score,\n severityLevel,\n };\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "43.109.3",
4
+ "version": "43.109.5",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -121,7 +121,7 @@
121
121
  "@redis/client": "5.11.0",
122
122
  "@renovatebot/detect-tools": "3.0.0",
123
123
  "@renovatebot/good-enough-parser": "2.0.0",
124
- "@renovatebot/osv-offline": "2.4.0",
124
+ "@renovatebot/osv-offline": "2.4.1",
125
125
  "@renovatebot/pep440": "4.2.2",
126
126
  "@renovatebot/pgp": "1.3.4",
127
127
  "@renovatebot/ruby-semver": "4.1.2",
@@ -157,7 +157,7 @@
157
157
  "git-url-parse": "16.1.0",
158
158
  "github-url-from-git": "1.5.0",
159
159
  "glob": "13.0.6",
160
- "global-agent": "4.1.3",
160
+ "global-agent": "3.0.0",
161
161
  "google-auth-library": "10.6.2",
162
162
  "got": "14.6.6",
163
163
  "graph-data-structure": "4.5.0",
@@ -236,6 +236,7 @@
236
236
  "@types/estree": "1.0.8",
237
237
  "@types/fs-extra": "11.0.4",
238
238
  "@types/github-url-from-git": "1.5.3",
239
+ "@types/global-agent": "3.0.0",
239
240
  "@types/ini": "4.1.1",
240
241
  "@types/js-yaml": "4.0.9",
241
242
  "@types/json-dup-key-validator": "1.0.2",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 43.109.3 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 43.109.5 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "43.109.3",
5
+ "x-renovate-version": "43.109.5",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "properties": {