Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vulnerabilities): add feature-flagged support for OSV #20226

Merged
merged 23 commits into from Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8b603e0
feat(vulnerabilities): add feature-flagged support for osv
JamieMagee Oct 9, 2022
3a0601d
add OSV vulnerability alerts
Churro Feb 4, 2023
9e89551
allow dep to override datasource default versioning
Churro Feb 4, 2023
2a7b57b
Update lib/workers/repository/process/vulnerabilities.ts
Churro Feb 5, 2023
cab7e99
Update lib/workers/repository/process/vulnerabilities.ts
Churro Feb 5, 2023
4583e25
Update lib/workers/repository/process/vulnerabilities.ts
Churro Feb 5, 2023
332a7dd
run prettier
Churro Feb 5, 2023
3cd3892
extract-update.spec.ts: remove superfluous jest.clearAllMocks
Churro Feb 5, 2023
bb06cf0
configuration-options.md: vulnerabilities fixes -> vulnerability fixes
Churro Feb 5, 2023
8a30ac7
sortByFixedVersion: preprocess allowedVersions
Churro Feb 5, 2023
4c02086
extract version comparisons into separate methods
Churro Feb 5, 2023
eeca5f9
index.ts: don't always pick the first release for OSV-based rules bas…
Churro Feb 5, 2023
0f5e534
Update docs/usage/configuration-options.md
Churro Feb 6, 2023
8cb5ab5
Update docs/usage/configuration-options.md
Churro Feb 6, 2023
33e66ce
Update docs/usage/configuration-options.md
Churro Feb 6, 2023
2014a4c
Update docs/usage/configuration-options.md
Churro Feb 6, 2023
c42f251
prefer CVSS_V3 over CVSS_V2 , don't show CVSS 0 in case of exception
Churro Feb 6, 2023
5defea7
vulnerabilities.spec.ts: replace string concat in prBodyNotes with co…
Churro Feb 6, 2023
e4ce5e4
Update lib/workers/repository/process/extract-update.spec.ts
Churro Feb 8, 2023
d301c00
add comment about pre-processing
Churro Feb 9, 2023
60e9988
change log level for vulns without fixes to info
Churro Feb 9, 2023
4c271f3
Merge branch 'main' into feat-osv-vuln
Churro Feb 9, 2023
955a174
Merge branch 'main' into feat-osv-vuln
secustor Feb 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/usage/configuration-options.md
Expand Up @@ -1492,6 +1492,24 @@ A use case for the latter is if you are a Renovate bot admin and wish to provide
If `false` (default), it means that defining `config.npmrc` will result in any `.npmrc` file in the repo being overridden and its values ignored.
If configured to `true`, it means that any `.npmrc` file in the repo will have `config.npmrc` prepended to it before running `npm`.

## osvVulnerabilityAlerts

Renovate integrates with [OSV](https://osv.dev/), an open-source vulnerability database, to check if extracted dependencies have known vulnerabilities.
Set `osvVulnerabilityAlerts` to `true` to get pull requests with vulnerability fixes (once they are available).

You will only get OSV-based vulnerability alerts for _direct_ dependencies.
Renovate only queries the OSV database for dependencies that use one of these datasources:

- [`crate`](https://docs.renovatebot.com/modules/datasource/crate/)
Churro marked this conversation as resolved.
Show resolved Hide resolved
- [`go`](https://docs.renovatebot.com/modules/datasource/go/)
- [`hex`](https://docs.renovatebot.com/modules/datasource/hex/)
- [`maven`](https://docs.renovatebot.com/modules/datasource/maven/)
- [`npm`](https://docs.renovatebot.com/modules/datasource/npm/)
- [`nuget`](https://docs.renovatebot.com/modules/datasource/nuget/)
- [`packagist`](https://docs.renovatebot.com/modules/datasource/packagist/)
- [`pypi`](https://docs.renovatebot.com/modules/datasource/pypi/)
- [`rubygems`](https://docs.renovatebot.com/modules/datasource/rubygems/)

## packageRules

`packageRules` is a powerful feature that lets you apply rules to individual packages or to groups of packages using regex pattern matching.
Expand Down
8 changes: 8 additions & 0 deletions lib/config/options/index.ts
Expand Up @@ -1670,6 +1670,14 @@ const options: RenovateOptions[] = [
env: false,
supportedPlatforms: ['github'],
},
{
name: 'osvVulnerabilityAlerts',
description: 'Use vulnerability alerts from `osv.dev`.',
type: 'boolean',
default: false,
experimental: true,
experimentalIssues: [6562],
},
{
name: 'pruneBranchAfterAutomerge',
description: 'Set to `true` to enable branch pruning after automerging.',
Expand Down
1 change: 1 addition & 0 deletions lib/config/types.ts
Expand Up @@ -243,6 +243,7 @@ export interface RenovateConfig

warnings?: ValidationMessage[];
vulnerabilityAlerts?: RenovateSharedConfig;
osvVulnerabilityAlerts?: boolean;
regexManagers?: RegExManager[];

fetchReleaseNotes?: boolean;
Expand Down
50 changes: 49 additions & 1 deletion lib/workers/repository/process/extract-update.spec.ts
Expand Up @@ -7,9 +7,21 @@ import { generateFingerprintConfig } from '../extract/extract-fingerprint-config
import * as _branchify from '../updates/branchify';
import { extract, isCacheExtractValid, lookup, update } from './extract-update';

const createVulnerabilitiesMock = jest.fn();

jest.mock('./write');
jest.mock('./sort');
jest.mock('./fetch');
jest.mock('./vulnerabilities', () => {
return {
__esModule: true,
Vulnerabilities: class {
static create() {
return createVulnerabilitiesMock();
}
},
};
});
jest.mock('../updates/branchify');
jest.mock('../extract');
jest.mock('../../../util/cache/repository');
Expand All @@ -18,7 +30,7 @@ jest.mock('../../../util/git');
const branchify = mocked(_branchify);
const repositoryCache = mocked(_repositoryCache);
JamieMagee marked this conversation as resolved.
Show resolved Hide resolved

branchify.branchifyUpgrades.mockResolvedValueOnce({
branchify.branchifyUpgrades.mockResolvedValue({
branches: [
{
manager: 'some-manager',
Expand Down Expand Up @@ -97,6 +109,42 @@ describe('workers/repository/process/extract-update', () => {
const res = await extract(config);
expect(res).toEqual(packageFiles);
});

it('fetches vulnerabilities', async () => {
const config = {
repoIsOnboarded: true,
suppressNotifications: ['deprecationWarningIssues'],
osvVulnerabilityAlerts: true,
};
const fetchVulnerabilitiesMock = jest.fn();
createVulnerabilitiesMock.mockResolvedValueOnce({
fetchVulnerabilities: fetchVulnerabilitiesMock,
});
repositoryCache.getCache.mockReturnValueOnce({ scan: {} });
git.checkoutBranch.mockResolvedValueOnce('123test');

const packageFiles = await extract(config);
await lookup(config, packageFiles);

expect(createVulnerabilitiesMock).toHaveBeenCalledOnce();
expect(fetchVulnerabilitiesMock).toHaveBeenCalledOnce();
});

it('handles exception when fetching vulnerabilities', async () => {
const config = {
repoIsOnboarded: true,
suppressNotifications: ['deprecationWarningIssues'],
osvVulnerabilityAlerts: true,
};
createVulnerabilitiesMock.mockRejectedValueOnce(new Error());
repositoryCache.getCache.mockReturnValueOnce({ scan: {} });
git.checkoutBranch.mockResolvedValueOnce('123test');

const packageFiles = await extract(config);
await lookup(config, packageFiles);

expect(createVulnerabilitiesMock).toHaveBeenCalledOnce();
});
});

describe('isCacheExtractValid()', () => {
Expand Down
16 changes: 16 additions & 0 deletions lib/workers/repository/process/extract-update.ts
Expand Up @@ -15,6 +15,7 @@ import { branchifyUpgrades } from '../updates/branchify';
import { raiseDeprecationWarnings } from './deprecated';
import { fetchUpdates } from './fetch';
import { sortBranches } from './sort';
import { Vulnerabilities } from './vulnerabilities';
import { WriteUpdateResult, writeUpdates } from './write';

export interface ExtractResult {
Expand Down Expand Up @@ -166,10 +167,25 @@ export async function extract(
return packageFiles;
}

async function fetchVulnerabilities(
Churro marked this conversation as resolved.
Show resolved Hide resolved
config: RenovateConfig,
packageFiles: Record<string, PackageFile[]>
): Promise<void> {
if (config.osvVulnerabilityAlerts) {
try {
const vulnerabilities = await Vulnerabilities.create();
await vulnerabilities.fetchVulnerabilities(config, packageFiles);
} catch (err) {
logger.warn({ err }, 'Unable to read vulnerability information');
}
}
}

export async function lookup(
config: RenovateConfig,
packageFiles: Record<string, PackageFile[]>
): Promise<ExtractResult> {
await fetchVulnerabilities(config, packageFiles);
await fetchUpdates(config, packageFiles);
await raiseDeprecationWarnings(config, packageFiles);
const { branches, branchList } = await branchifyUpgrades(
Expand Down
2 changes: 1 addition & 1 deletion lib/workers/repository/process/lookup/index.ts
Expand Up @@ -252,7 +252,7 @@ export async function lookupUpdates(
// Leave only compatible versions
unconstrainedValue || versioning.isCompatible(v.version, currentValue)
);
if (isVulnerabilityAlert) {
if (isVulnerabilityAlert && !config.osvVulnerabilityAlerts) {
filteredReleases = filteredReleases.slice(0, 1);
}
const buckets: Record<string, [Release]> = {};
Expand Down