From 0034661058817dabaee7c2a92233a681c5ec7df0 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 15 Sep 2024 06:38:19 +0200 Subject: [PATCH 01/11] refactor: use vulnerabilityFixVersion for github alerts --- lib/config/validation.ts | 1 + .../__snapshots__/vulnerability.spec.ts.snap | 6 +- lib/workers/repository/init/vulnerability.ts | 6 +- .../repository/process/lookup/index.spec.ts | 67 +++++++++++++++++++ .../repository/process/lookup/index.ts | 34 ++++++++++ .../repository/process/lookup/types.ts | 2 + 6 files changed, 108 insertions(+), 8 deletions(-) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 620cbe190d5242..fdcf487a20a52f 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -64,6 +64,7 @@ const ignoredNodes = [ 'vulnerabilityAlertsOnly', 'vulnerabilityAlert', 'isVulnerabilityAlert', + 'vulnerabilityFixVersion', // not intended to be used by end users but may be by Mend apps 'copyLocalLibs', // deprecated - functionality is now enabled by default 'prBody', // deprecated 'minimumConfidence', // undocumented feature flag diff --git a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap index ae46fd5e4c4f06..d42cf0cd1f76ab 100644 --- a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap @@ -3,7 +3,6 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() returns go alerts 1`] = ` [ { - "allowedVersions": "1.8.3", "force": { "branchTopic": "{{{datasource}}}-{{{depNameSanitized}}}-vulnerability", "commitMessageSuffix": "[SECURITY]", @@ -30,6 +29,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur go", ], + "vulnerabilityFixVersion": "1.8.3", }, ] `; @@ -37,7 +37,6 @@ go", exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() returns maven alerts 1`] = ` [ { - "allowedVersions": "2.7.9.4", "force": { "branchTopic": "{{{datasource}}}-{{{depNameSanitized}}}-vulnerability", "commitMessageSuffix": "[SECURITY]", @@ -64,6 +63,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur An issue was discovered in FasterXML jackson-databind prior to 2.7.9.4, 2.8.11.2, and 2.9.6. When Default Typing is enabled (either globally or for a specific property), the service has the Jodd-db jar (for database access for the Jodd framework) in the classpath, and an attacker can provide an LDAP service to access, it is possible to make the service execute a malicious payload.", ], + "vulnerabilityFixVersion": "2.7.9.4", }, ] `; @@ -71,7 +71,6 @@ An issue was discovered in FasterXML jackson-databind prior to 2.7.9.4, 2.8.11.2 exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() returns pip alerts 1`] = ` [ { - "allowedVersions": "==2.2.1.0", "force": { "branchTopic": "{{{datasource}}}-{{{depNameSanitized}}}-vulnerability", "commitMessageSuffix": "[SECURITY]", @@ -113,6 +112,7 @@ Ansible before version 2.2.0 fails to properly sanitize fact variables sent from Ansible before versions 2.1.4, 2.2.1 is vulnerable to an improper input validation in Ansible's handling of data sent from client systems. An attacker with control over a client system being managed by Ansible and the ability to send facts back to the Ansible server could use this flaw to execute arbitrary code on the Ansible server using the Ansible server privileges.", ], + "vulnerabilityFixVersion": "2.2.1.0", }, ] `; diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts index dbf8b04c6a7689..13f796020c9fe6 100644 --- a/lib/workers/repository/init/vulnerability.ts +++ b/lib/workers/repository/init/vulnerability.ts @@ -174,10 +174,6 @@ export async function detectVulnerabilityAlerts( logger.warn({ err }, 'Error generating vulnerability PR notes'); } // TODO: types (#22198) - const allowedVersions = - datasource === PypiDatasource.id - ? `==${val.firstPatchedVersion!}` - : val.firstPatchedVersion; const matchFileNames = datasource === GoDatasource.id ? [fileName.replace('go.sum', 'go.mod')] @@ -191,7 +187,7 @@ export async function detectVulnerabilityAlerts( // Remediate only direct dependencies matchRule = { ...matchRule, - allowedVersions, + vulnerabilityFixVersion: val.firstPatchedVersion, prBodyNotes, isVulnerabilityAlert: true, force: { diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 3c67849975f522..56d4b740c693c3 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -818,6 +818,73 @@ describe('workers/repository/process/lookup/index', () => { ]); }); + it('uses vulnerabilityFixVersion', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '1.1.0'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 1, + newPatch: 0, + newValue: '1.1.0', + newVersion: '1.1.0', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + + it('ignores vulnerabilityFixVersion if not a version', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '1.1'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 0, + newPatch: 1, + newValue: '1.0.1', + newVersion: '1.0.1', + releaseTimestamp: expect.any(String), + updateType: 'patch', + }, + ]); + }); + + it('returns no results if vulnerabilityFixVersion is too high', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '5.1.0'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toBeEmptyArray(); + }); + it('supports minor and major upgrades for ranged versions', async () => { config.currentValue = '~0.4.0'; config.rangeStrategy = 'pin'; diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts index c4167937ac1fd1..9b4ecc3a24a81d 100644 --- a/lib/workers/repository/process/lookup/index.ts +++ b/lib/workers/repository/process/lookup/index.ts @@ -372,6 +372,40 @@ export async function lookupUpdates( ); let shrinkedViaVulnerability = false; if (config.isVulnerabilityAlert) { + if (config.vulnerabilityFixVersion) { + res.vulnerabilityFixVersion = config.vulnerabilityFixVersion; + if (versioning.isVersion(config.vulnerabilityFixVersion)) { + // Filter out versions if the vulnerabilityFixVersion is higher + const fixedFilteredReleases = filteredReleases.filter( + (r) => + !versioning.isGreaterThan( + config.vulnerabilityFixVersion!, + r.version, + ), + ); + // Warn if this filtering results caused zero releases + if (fixedFilteredReleases.length === 0 && filteredReleases.length) { + logger.warn( + { + releases: filteredReleases, + vulnerabilityFixVersion: config.vulnerabilityFixVersion, + packageName: config.packageName, + }, + 'No releases satisfy vulnerabilityFixVersion', + ); + } + // Use the additionally filtered releases + filteredReleases = fixedFilteredReleases; + } else { + logger.warn( + { + vulnerabilityFixVersion: config.vulnerabilityFixVersion, + packageName: config.packageName, + }, + 'vulnerabilityFixVersion is not a version', + ); + } + } filteredReleases = filteredReleases.slice(0, 1); shrinkedViaVulnerability = true; logger.debug( diff --git a/lib/workers/repository/process/lookup/types.ts b/lib/workers/repository/process/lookup/types.ts index ed944ea253d5e9..aaec2a405d532e 100644 --- a/lib/workers/repository/process/lookup/types.ts +++ b/lib/workers/repository/process/lookup/types.ts @@ -49,6 +49,7 @@ export interface LookupUpdateConfig replacementNameTemplate?: string; replacementVersion?: string; extractVersion?: string; + vulnerabilityFixVersion?: string; } export interface UpdateResult { @@ -68,4 +69,5 @@ export interface UpdateResult { warnings: ValidationMessage[]; versioning?: string; currentVersionTimestamp?: string; + vulnerabilityFixVersion?: string; } From 81540e4189a7910b331b5dbf96daa38a666180f2 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 15 Sep 2024 07:13:42 +0200 Subject: [PATCH 02/11] feat: vulnerabilityFixStrategy --- docs/usage/configuration-options.md | 15 +++++ lib/config/options/index.ts | 10 ++++ lib/config/types.ts | 7 ++- .../__snapshots__/vulnerability.spec.ts.snap | 3 + .../repository/process/lookup/index.spec.ts | 55 ++++++++++++++++++- .../repository/process/lookup/index.ts | 20 +++++-- .../repository/process/lookup/types.ts | 2 + 7 files changed, 102 insertions(+), 10 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 6b85afa5b1131f..dc10180b133e20 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -4062,3 +4062,18 @@ To disable the vulnerability alerts feature, set `enabled=false` in a `vulnerabi !!! note If you want to raise only vulnerability fix PRs, you may use the `security:only-security-updates` preset. + +### vulnerabilityFixStrategy + +When a vulnerability fix is available, Renovate will default to picking the lowest fixed version (`vulnerabilityFixStrategy=lowest`). +For example, if the current version is `1.0.0`, and a vulnerability is fixed in `1.1.0`, while the latest version is `1.2.0`, then Renovate will propose an update to `1.1.0` as the vulnerability fix. + +If `vulnerabilityFixStrategy=highest` is configured then Renovate will use its normal strategy for picking upgrades, e.g. in the above example it will propose an update to `1.2.0` to fix the vulnerability. + +```json title="Setting vulnerabilityFixStrategy to highest" +{ + "vulnerabilityAlerts": { + "vulnerabilityFixStrategy": "highest" + } +} +``` diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index aa3751a231d670..38b31a45c5b3b1 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1968,12 +1968,22 @@ const options: RenovateOptions[] = [ commitMessageSuffix: '[SECURITY]', branchTopic: `{{{datasource}}}-{{{depNameSanitized}}}-vulnerability`, prCreation: 'immediate', + vulnerabilityFixStrategy: 'lowest', }, mergeable: true, cli: false, env: false, supportedPlatforms: ['github'], }, + { + name: 'vulnerabilityFixStrategy', + description: + 'Strategy to use when fixing vulnerabilities. `lowest` will use the lowest fixed version, `highest` will use the highest fixed version.', + type: 'string', + allowedValues: ['lowest', 'highest'], + default: 'lowest', + parents: ['vulnerabilityAlerts'], + }, { name: 'osvVulnerabilityAlerts', description: 'Use vulnerability alerts from `osv.dev`.', diff --git a/lib/config/types.ts b/lib/config/types.ts index fc26ae82b380de..6fccc8f885eb32 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -391,12 +391,13 @@ export interface ValidationMessage { } export type AllowedParents = - | 'customManagers' | 'customDatasources' + | 'customManagers' | 'hostRules' - | 'postUpgradeTasks' + | 'logLevelRemap' | 'packageRules' - | 'logLevelRemap'; + | 'postUpgradeTasks' + | 'vulnerabilityAlerts'; export interface RenovateOptionBase { /** * If true, the option can only be configured by people with access to the Renovate instance. diff --git a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap index d42cf0cd1f76ab..1d7868498bb0b0 100644 --- a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap @@ -12,6 +12,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "prCreation": "immediate", "rangeStrategy": "update-lockfile", "schedule": [], + "vulnerabilityFixStrategy": "lowest", }, "isVulnerabilityAlert": true, "matchDatasources": [ @@ -46,6 +47,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "prCreation": "immediate", "rangeStrategy": "update-lockfile", "schedule": [], + "vulnerabilityFixStrategy": "lowest", }, "isVulnerabilityAlert": true, "matchDatasources": [ @@ -80,6 +82,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "prCreation": "immediate", "rangeStrategy": "update-lockfile", "schedule": [], + "vulnerabilityFixStrategy": "lowest", }, "isVulnerabilityAlert": true, "matchDatasources": [ diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 56d4b740c693c3..11841cec4b9914 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -793,7 +793,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses minimum version for vulnerabilityAlerts', async () => { + it('uses lowest version by default for vulnerabilityAlerts', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.packageName = 'q'; @@ -818,6 +818,32 @@ describe('workers/repository/process/lookup/index', () => { ]); }); + it('uses highest version for vulnerabilityAlerts when vulnerabilityFixStrategy=highest', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixStrategy = 'highest'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 4, + newPatch: 1, + newValue: '1.4.1', + newVersion: '1.4.1', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + it('uses vulnerabilityFixVersion', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; @@ -844,6 +870,33 @@ describe('workers/repository/process/lookup/index', () => { ]); }); + it('takes highest verion when using vulnerabilityFixStrategy=highest with vulnerabilityFixVersion', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '1.1.0'; + config.vulnerabilityFixStrategy = 'highest'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 4, + newPatch: 1, + newValue: '1.4.1', + newVersion: '1.4.1', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + it('ignores vulnerabilityFixVersion if not a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts index 9b4ecc3a24a81d..f567e4ed5b78af 100644 --- a/lib/workers/repository/process/lookup/index.ts +++ b/lib/workers/repository/process/lookup/index.ts @@ -373,6 +373,7 @@ export async function lookupUpdates( let shrinkedViaVulnerability = false; if (config.isVulnerabilityAlert) { if (config.vulnerabilityFixVersion) { + res.vulnerabilityFixStrategy = config.vulnerabilityFixStrategy; res.vulnerabilityFixVersion = config.vulnerabilityFixVersion; if (versioning.isVersion(config.vulnerabilityFixVersion)) { // Filter out versions if the vulnerabilityFixVersion is higher @@ -406,12 +407,19 @@ export async function lookupUpdates( ); } } - filteredReleases = filteredReleases.slice(0, 1); - shrinkedViaVulnerability = true; - logger.debug( - { filteredReleases }, - 'Vulnerability alert found: limiting results to a single release', - ); + if (config.vulnerabilityFixStrategy === 'highest') { + // Don't shrink the list of releases - let Renovate use its normal logic + logger.once.debug( + `Using vulnerabilityFixStrategy=highest for ${config.packageName}`, + ); + } else { + // Shrink the list of releases to the lowest fixed version + logger.once.debug( + `Using vulnerabilityFixStrategy=lowest for ${config.packageName}`, + ); + filteredReleases = filteredReleases.slice(0, 1); + shrinkedViaVulnerability = true; + } } const buckets: Record = {}; for (const release of filteredReleases) { diff --git a/lib/workers/repository/process/lookup/types.ts b/lib/workers/repository/process/lookup/types.ts index aaec2a405d532e..03ad7f94942f39 100644 --- a/lib/workers/repository/process/lookup/types.ts +++ b/lib/workers/repository/process/lookup/types.ts @@ -50,6 +50,7 @@ export interface LookupUpdateConfig replacementVersion?: string; extractVersion?: string; vulnerabilityFixVersion?: string; + vulnerabilityFixStrategy?: string; } export interface UpdateResult { @@ -70,4 +71,5 @@ export interface UpdateResult { versioning?: string; currentVersionTimestamp?: string; vulnerabilityFixVersion?: string; + vulnerabilityFixStrategy?: string; } From 0ba1edaebd85e36a0a328d5cb48e0d77ec18a4ba Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 16 Sep 2024 06:06:02 +0200 Subject: [PATCH 03/11] handle vulnerabilityFixVersion as version or range --- .../repository/process/lookup/index.spec.ts | 56 ++++++++++++++++++- .../repository/process/lookup/index.ts | 25 ++++++--- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 56d4b740c693c3..b129d8a4b89c29 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -818,7 +818,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses vulnerabilityFixVersion', async () => { + it('uses vulnerabilityFixVersion when a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.vulnerabilityFixVersion = '1.1.0'; @@ -844,10 +844,62 @@ describe('workers/repository/process/lookup/index', () => { ]); }); + it('takes a later release when vulnerabilityFixVersion does not exist', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '1.0.2'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 1, + newPatch: 0, + newValue: '1.1.0', + newVersion: '1.1.0', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + + it('uses vulnerabilityFixVersion when a range', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '>= 1.1.0'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 1, + newPatch: 0, + newValue: '1.1.0', + newVersion: '1.1.0', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + it('ignores vulnerabilityFixVersion if not a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFixVersion = '1.1'; + config.vulnerabilityFixVersion = 'abc'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts index 9b4ecc3a24a81d..69cdc2016c552b 100644 --- a/lib/workers/repository/process/lookup/index.ts +++ b/lib/workers/repository/process/lookup/index.ts @@ -374,15 +374,24 @@ export async function lookupUpdates( if (config.isVulnerabilityAlert) { if (config.vulnerabilityFixVersion) { res.vulnerabilityFixVersion = config.vulnerabilityFixVersion; - if (versioning.isVersion(config.vulnerabilityFixVersion)) { + if (versioning.isValid(config.vulnerabilityFixVersion)) { // Filter out versions if the vulnerabilityFixVersion is higher - const fixedFilteredReleases = filteredReleases.filter( - (r) => - !versioning.isGreaterThan( - config.vulnerabilityFixVersion!, - r.version, - ), - ); + const fixedFilteredReleases = versioning.isVersion( + config.vulnerabilityFixVersion, + ) + ? filteredReleases.filter( + (r) => + !versioning.isGreaterThan( + config.vulnerabilityFixVersion!, + r.version, + ), + ) + : filteredReleases.filter((r) => + versioning.matches( + r.version, + config.vulnerabilityFixVersion!, + ), + ); // Warn if this filtering results caused zero releases if (fixedFilteredReleases.length === 0 && filteredReleases.length) { logger.warn( From a24fd2a2263ab5046195db47cc9da3fc21385c8d Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 16 Sep 2024 06:19:29 +0200 Subject: [PATCH 04/11] Apply suggestions from code review Co-authored-by: Johannes Feichtner <343448+Churro@users.noreply.github.com> --- lib/config/options/index.ts | 2 +- lib/workers/repository/process/lookup/index.spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 38b31a45c5b3b1..4834cee9797f78 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1978,7 +1978,7 @@ const options: RenovateOptions[] = [ { name: 'vulnerabilityFixStrategy', description: - 'Strategy to use when fixing vulnerabilities. `lowest` will use the lowest fixed version, `highest` will use the highest fixed version.', + 'Strategy to use when fixing vulnerabilities. `lowest` will propose the earliest version with a fix, `highest` will always pick the latest version.', type: 'string', allowedValues: ['lowest', 'highest'], default: 'lowest', diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 11841cec4b9914..746f8a4aab1b5d 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -818,7 +818,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses highest version for vulnerabilityAlerts when vulnerabilityFixStrategy=highest', async () => { + it('uses highest available version for vulnerabilityAlerts when vulnerabilityFixStrategy=highest', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.vulnerabilityFixStrategy = 'highest'; @@ -870,7 +870,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('takes highest verion when using vulnerabilityFixStrategy=highest with vulnerabilityFixVersion', async () => { + it('takes highest available version when using vulnerabilityFixStrategy=highest with vulnerabilityFixVersion', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.vulnerabilityFixVersion = '1.1.0'; From 2c29b5409ccb14ad40fa997ef853483067417a32 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 16 Sep 2024 06:42:44 +0200 Subject: [PATCH 05/11] fix tests --- .../repository/process/lookup/index.spec.ts | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 22a9fb587543d6..323c47bee56a61 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -844,7 +844,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses vulnerabilityFixVersion', async () => { + it('uses vulnerabilityFixVersion when a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.vulnerabilityFixVersion = '1.1.0'; @@ -870,6 +870,58 @@ describe('workers/repository/process/lookup/index', () => { ]); }); + it('takes next version when vulnerabilityFixVersion is missing', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '1.0.2'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 1, + newPatch: 0, + newValue: '1.1.0', + newVersion: '1.1.0', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + + it('uses vulnerabilityFixVersion when a range', async () => { + config.currentValue = '1.0.0'; + config.isVulnerabilityAlert = true; + config.vulnerabilityFixVersion = '>= 1.1.0'; + config.packageName = 'q'; + config.datasource = NpmDatasource.id; + httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); + + const { updates } = await Result.wrap( + lookup.lookupUpdates(config), + ).unwrapOrThrow(); + + expect(updates).toEqual([ + { + bucket: 'non-major', + newMajor: 1, + newMinor: 1, + newPatch: 0, + newValue: '1.1.0', + newVersion: '1.1.0', + releaseTimestamp: expect.any(String), + updateType: 'minor', + }, + ]); + }); + it('takes highest available version when using vulnerabilityFixStrategy=highest with vulnerabilityFixVersion', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; From bd1ac7199f0e1579f101e8fa99f2da1439fa94a0 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 16 Sep 2024 08:17:07 +0200 Subject: [PATCH 06/11] rename vulnerabilityFixVersion -> vulnerabilityFix --- lib/config/validation.ts | 2 +- .../__snapshots__/vulnerability.spec.ts.snap | 6 ++--- lib/workers/repository/init/vulnerability.ts | 2 +- .../repository/process/lookup/index.spec.ts | 20 +++++++-------- .../repository/process/lookup/index.ts | 25 ++++++++----------- .../repository/process/lookup/types.ts | 4 +-- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index fdcf487a20a52f..015806bcee561e 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -64,7 +64,7 @@ const ignoredNodes = [ 'vulnerabilityAlertsOnly', 'vulnerabilityAlert', 'isVulnerabilityAlert', - 'vulnerabilityFixVersion', // not intended to be used by end users but may be by Mend apps + 'vulnerabilityFix', // not intended to be used by end users but may be by Mend apps 'copyLocalLibs', // deprecated - functionality is now enabled by default 'prBody', // deprecated 'minimumConfidence', // undocumented feature flag diff --git a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap index d42cf0cd1f76ab..6a26f542b7c776 100644 --- a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap @@ -29,7 +29,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur go", ], - "vulnerabilityFixVersion": "1.8.3", + "vulnerabilityFix": "1.8.3", }, ] `; @@ -63,7 +63,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur An issue was discovered in FasterXML jackson-databind prior to 2.7.9.4, 2.8.11.2, and 2.9.6. When Default Typing is enabled (either globally or for a specific property), the service has the Jodd-db jar (for database access for the Jodd framework) in the classpath, and an attacker can provide an LDAP service to access, it is possible to make the service execute a malicious payload.", ], - "vulnerabilityFixVersion": "2.7.9.4", + "vulnerabilityFix": "2.7.9.4", }, ] `; @@ -112,7 +112,7 @@ Ansible before version 2.2.0 fails to properly sanitize fact variables sent from Ansible before versions 2.1.4, 2.2.1 is vulnerable to an improper input validation in Ansible's handling of data sent from client systems. An attacker with control over a client system being managed by Ansible and the ability to send facts back to the Ansible server could use this flaw to execute arbitrary code on the Ansible server using the Ansible server privileges.", ], - "vulnerabilityFixVersion": "2.2.1.0", + "vulnerabilityFix": "2.2.1.0", }, ] `; diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts index 13f796020c9fe6..581adf874041e5 100644 --- a/lib/workers/repository/init/vulnerability.ts +++ b/lib/workers/repository/init/vulnerability.ts @@ -187,7 +187,7 @@ export async function detectVulnerabilityAlerts( // Remediate only direct dependencies matchRule = { ...matchRule, - vulnerabilityFixVersion: val.firstPatchedVersion, + vulnerabilityFix: val.firstPatchedVersion, prBodyNotes, isVulnerabilityAlert: true, force: { diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index b129d8a4b89c29..7d8eea9a249e55 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -818,10 +818,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses vulnerabilityFixVersion when a version', async () => { + it('uses vulnerabilityFix when a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFixVersion = '1.1.0'; + config.vulnerabilityFix = '1.1.0'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -844,10 +844,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('takes a later release when vulnerabilityFixVersion does not exist', async () => { + it('takes a later release when vulnerabilityFix does not exist', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFixVersion = '1.0.2'; + config.vulnerabilityFix = '1.0.2'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -870,10 +870,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses vulnerabilityFixVersion when a range', async () => { + it('uses vulnerabilityFix when a range', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFixVersion = '>= 1.1.0'; + config.vulnerabilityFix = '>= 1.1.0'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -896,10 +896,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('ignores vulnerabilityFixVersion if not a version', async () => { + it('ignores vulnerabilityFix if not a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFixVersion = 'abc'; + config.vulnerabilityFix = 'abc'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -922,10 +922,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('returns no results if vulnerabilityFixVersion is too high', async () => { + it('returns no results if vulnerabilityFix is too high', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFixVersion = '5.1.0'; + config.vulnerabilityFix = '5.1.0'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts index 69cdc2016c552b..ffeec0853a8413 100644 --- a/lib/workers/repository/process/lookup/index.ts +++ b/lib/workers/repository/process/lookup/index.ts @@ -372,35 +372,32 @@ export async function lookupUpdates( ); let shrinkedViaVulnerability = false; if (config.isVulnerabilityAlert) { - if (config.vulnerabilityFixVersion) { - res.vulnerabilityFixVersion = config.vulnerabilityFixVersion; - if (versioning.isValid(config.vulnerabilityFixVersion)) { - // Filter out versions if the vulnerabilityFixVersion is higher + if (config.vulnerabilityFix) { + res.vulnerabilityFix = config.vulnerabilityFix; + if (versioning.isValid(config.vulnerabilityFix)) { + // Filter out versions if the vulnerabilityFix is higher const fixedFilteredReleases = versioning.isVersion( - config.vulnerabilityFixVersion, + config.vulnerabilityFix, ) ? filteredReleases.filter( (r) => !versioning.isGreaterThan( - config.vulnerabilityFixVersion!, + config.vulnerabilityFix!, r.version, ), ) : filteredReleases.filter((r) => - versioning.matches( - r.version, - config.vulnerabilityFixVersion!, - ), + versioning.matches(r.version, config.vulnerabilityFix!), ); // Warn if this filtering results caused zero releases if (fixedFilteredReleases.length === 0 && filteredReleases.length) { logger.warn( { releases: filteredReleases, - vulnerabilityFixVersion: config.vulnerabilityFixVersion, + vulnerabilityFix: config.vulnerabilityFix, packageName: config.packageName, }, - 'No releases satisfy vulnerabilityFixVersion', + 'No releases satisfy vulnerabilityFix', ); } // Use the additionally filtered releases @@ -408,10 +405,10 @@ export async function lookupUpdates( } else { logger.warn( { - vulnerabilityFixVersion: config.vulnerabilityFixVersion, + vulnerabilityFix: config.vulnerabilityFix, packageName: config.packageName, }, - 'vulnerabilityFixVersion is not a version', + 'vulnerabilityFix is not valid', ); } } diff --git a/lib/workers/repository/process/lookup/types.ts b/lib/workers/repository/process/lookup/types.ts index aaec2a405d532e..32de0dd3560b24 100644 --- a/lib/workers/repository/process/lookup/types.ts +++ b/lib/workers/repository/process/lookup/types.ts @@ -49,7 +49,7 @@ export interface LookupUpdateConfig replacementNameTemplate?: string; replacementVersion?: string; extractVersion?: string; - vulnerabilityFixVersion?: string; + vulnerabilityFix?: string; } export interface UpdateResult { @@ -69,5 +69,5 @@ export interface UpdateResult { warnings: ValidationMessage[]; versioning?: string; currentVersionTimestamp?: string; - vulnerabilityFixVersion?: string; + vulnerabilityFix?: string; } From 6ab5539eba9711c81f33e4935d866481d6fd2a60 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 17 Sep 2024 06:59:30 +0200 Subject: [PATCH 07/11] Rename back --- lib/config/validation.ts | 2 +- .../__snapshots__/vulnerability.spec.ts.snap | 6 ++--- lib/workers/repository/init/vulnerability.ts | 2 +- .../repository/process/lookup/index.spec.ts | 20 +++++++-------- .../repository/process/lookup/index.ts | 25 +++++++++++-------- .../repository/process/lookup/types.ts | 4 +-- 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 015806bcee561e..fdcf487a20a52f 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -64,7 +64,7 @@ const ignoredNodes = [ 'vulnerabilityAlertsOnly', 'vulnerabilityAlert', 'isVulnerabilityAlert', - 'vulnerabilityFix', // not intended to be used by end users but may be by Mend apps + 'vulnerabilityFixVersion', // not intended to be used by end users but may be by Mend apps 'copyLocalLibs', // deprecated - functionality is now enabled by default 'prBody', // deprecated 'minimumConfidence', // undocumented feature flag diff --git a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap index 6a26f542b7c776..d42cf0cd1f76ab 100644 --- a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap @@ -29,7 +29,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur go", ], - "vulnerabilityFix": "1.8.3", + "vulnerabilityFixVersion": "1.8.3", }, ] `; @@ -63,7 +63,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur An issue was discovered in FasterXML jackson-databind prior to 2.7.9.4, 2.8.11.2, and 2.9.6. When Default Typing is enabled (either globally or for a specific property), the service has the Jodd-db jar (for database access for the Jodd framework) in the classpath, and an attacker can provide an LDAP service to access, it is possible to make the service execute a malicious payload.", ], - "vulnerabilityFix": "2.7.9.4", + "vulnerabilityFixVersion": "2.7.9.4", }, ] `; @@ -112,7 +112,7 @@ Ansible before version 2.2.0 fails to properly sanitize fact variables sent from Ansible before versions 2.1.4, 2.2.1 is vulnerable to an improper input validation in Ansible's handling of data sent from client systems. An attacker with control over a client system being managed by Ansible and the ability to send facts back to the Ansible server could use this flaw to execute arbitrary code on the Ansible server using the Ansible server privileges.", ], - "vulnerabilityFix": "2.2.1.0", + "vulnerabilityFixVersion": "2.2.1.0", }, ] `; diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts index 581adf874041e5..13f796020c9fe6 100644 --- a/lib/workers/repository/init/vulnerability.ts +++ b/lib/workers/repository/init/vulnerability.ts @@ -187,7 +187,7 @@ export async function detectVulnerabilityAlerts( // Remediate only direct dependencies matchRule = { ...matchRule, - vulnerabilityFix: val.firstPatchedVersion, + vulnerabilityFixVersion: val.firstPatchedVersion, prBodyNotes, isVulnerabilityAlert: true, force: { diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 7d8eea9a249e55..b129d8a4b89c29 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -818,10 +818,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses vulnerabilityFix when a version', async () => { + it('uses vulnerabilityFixVersion when a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFix = '1.1.0'; + config.vulnerabilityFixVersion = '1.1.0'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -844,10 +844,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('takes a later release when vulnerabilityFix does not exist', async () => { + it('takes a later release when vulnerabilityFixVersion does not exist', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFix = '1.0.2'; + config.vulnerabilityFixVersion = '1.0.2'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -870,10 +870,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses vulnerabilityFix when a range', async () => { + it('uses vulnerabilityFixVersion when a range', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFix = '>= 1.1.0'; + config.vulnerabilityFixVersion = '>= 1.1.0'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -896,10 +896,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('ignores vulnerabilityFix if not a version', async () => { + it('ignores vulnerabilityFixVersion if not a version', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFix = 'abc'; + config.vulnerabilityFixVersion = 'abc'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); @@ -922,10 +922,10 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('returns no results if vulnerabilityFix is too high', async () => { + it('returns no results if vulnerabilityFixVersion is too high', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; - config.vulnerabilityFix = '5.1.0'; + config.vulnerabilityFixVersion = '5.1.0'; config.packageName = 'q'; config.datasource = NpmDatasource.id; httpMock.scope('https://registry.npmjs.org').get('/q').reply(200, qJson); diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts index ffeec0853a8413..67aa57d5ecf031 100644 --- a/lib/workers/repository/process/lookup/index.ts +++ b/lib/workers/repository/process/lookup/index.ts @@ -372,32 +372,35 @@ export async function lookupUpdates( ); let shrinkedViaVulnerability = false; if (config.isVulnerabilityAlert) { - if (config.vulnerabilityFix) { - res.vulnerabilityFix = config.vulnerabilityFix; - if (versioning.isValid(config.vulnerabilityFix)) { - // Filter out versions if the vulnerabilityFix is higher + if (config.vulnerabilityFixVersion) { + res.vulnerabilityFixVersion = config.vulnerabilityFixVersion; + if (versioning.isValid(config.vulnerabilityFixVersion)) { + // Filter out versions if the vulnerabilityFixVersion is higher const fixedFilteredReleases = versioning.isVersion( - config.vulnerabilityFix, + config.vulnerabilityFixVersion, ) ? filteredReleases.filter( (r) => !versioning.isGreaterThan( - config.vulnerabilityFix!, + config.vulnerabilityFixVersion!, r.version, ), ) : filteredReleases.filter((r) => - versioning.matches(r.version, config.vulnerabilityFix!), + versioning.matches( + r.version, + config.vulnerabilityFixVersion!, + ), ); // Warn if this filtering results caused zero releases if (fixedFilteredReleases.length === 0 && filteredReleases.length) { logger.warn( { releases: filteredReleases, - vulnerabilityFix: config.vulnerabilityFix, + vulnerabilityFixVersion: config.vulnerabilityFixVersion, packageName: config.packageName, }, - 'No releases satisfy vulnerabilityFix', + 'No releases satisfy vulnerabilityFixVersion', ); } // Use the additionally filtered releases @@ -405,10 +408,10 @@ export async function lookupUpdates( } else { logger.warn( { - vulnerabilityFix: config.vulnerabilityFix, + vulnerabilityFixVersion: config.vulnerabilityFixVersion, packageName: config.packageName, }, - 'vulnerabilityFix is not valid', + 'vulnerabilityFixVersion is not valid', ); } } diff --git a/lib/workers/repository/process/lookup/types.ts b/lib/workers/repository/process/lookup/types.ts index 32de0dd3560b24..aaec2a405d532e 100644 --- a/lib/workers/repository/process/lookup/types.ts +++ b/lib/workers/repository/process/lookup/types.ts @@ -49,7 +49,7 @@ export interface LookupUpdateConfig replacementNameTemplate?: string; replacementVersion?: string; extractVersion?: string; - vulnerabilityFix?: string; + vulnerabilityFixVersion?: string; } export interface UpdateResult { @@ -69,5 +69,5 @@ export interface UpdateResult { warnings: ValidationMessage[]; versioning?: string; currentVersionTimestamp?: string; - vulnerabilityFix?: string; + vulnerabilityFixVersion?: string; } From 2377c5a0aa0fdb3eb2e6b7aa1fd53c1294cd823d Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 17 Sep 2024 07:11:42 +0200 Subject: [PATCH 08/11] add extra type --- lib/config/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/config/types.ts b/lib/config/types.ts index fc26ae82b380de..2575c6f91b25f7 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -383,6 +383,7 @@ export interface PackageRule matchUpdateTypes?: UpdateType[]; registryUrls?: string[] | null; vulnerabilitySeverity?: string; + vulnerabilityFixVersion?: string; } export interface ValidationMessage { From e74e433a9cd91ef751287abb5b49b06b8bfb0afb Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 17 Sep 2024 07:11:53 +0200 Subject: [PATCH 09/11] refactor/improve after Churro suggestion --- .../repository/process/lookup/index.ts | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts index 67aa57d5ecf031..f4fd09de75f114 100644 --- a/lib/workers/repository/process/lookup/index.ts +++ b/lib/workers/repository/process/lookup/index.ts @@ -376,22 +376,18 @@ export async function lookupUpdates( res.vulnerabilityFixVersion = config.vulnerabilityFixVersion; if (versioning.isValid(config.vulnerabilityFixVersion)) { // Filter out versions if the vulnerabilityFixVersion is higher - const fixedFilteredReleases = versioning.isVersion( - config.vulnerabilityFixVersion, - ) - ? filteredReleases.filter( - (r) => - !versioning.isGreaterThan( - config.vulnerabilityFixVersion!, - r.version, - ), - ) - : filteredReleases.filter((r) => - versioning.matches( - r.version, + const filterCondition = (release: Release): boolean => + versioning.isVersion(config.vulnerabilityFixVersion) + ? !versioning.isGreaterThan( config.vulnerabilityFixVersion!, - ), - ); + release.version, + ) + : versioning.matches( + release.version, + config.vulnerabilityFixVersion!, + ); + const fixedFilteredReleases = + filteredReleases.filter(filterCondition); // Warn if this filtering results caused zero releases if (fixedFilteredReleases.length === 0 && filteredReleases.length) { logger.warn( From 7518280d66f5edc7be85781582d6913be731518e Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 19 Sep 2024 07:32:33 +0200 Subject: [PATCH 10/11] Update lib/workers/repository/process/lookup/index.spec.ts --- lib/workers/repository/process/lookup/index.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 323c47bee56a61..ad3164c662056f 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -870,7 +870,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('takes next version when vulnerabilityFixVersion is missing', async () => { + it('takes a later release when vulnerabilityFixVersion does not exist', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.vulnerabilityFixVersion = '1.0.2'; From 1824e171217e49dd26a46f6edf600e83d48ec018 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 19 Sep 2024 07:33:04 +0200 Subject: [PATCH 11/11] Update lib/workers/repository/process/lookup/index.spec.ts --- lib/workers/repository/process/lookup/index.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index ad3164c662056f..ff3c0606733280 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -793,7 +793,7 @@ describe('workers/repository/process/lookup/index', () => { ]); }); - it('uses lowest version by default for vulnerabilityAlerts', async () => { + it('uses minimum version for vulnerabilityAlerts', async () => { config.currentValue = '1.0.0'; config.isVulnerabilityAlert = true; config.packageName = 'q';