diff --git a/CHANGELOG.md b/CHANGELOG.md index 65cc69c..dfd23cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- include vulnerable versions in findings when available ([#14][]) - sort the order of vulnerability paths when using the `paths` output ([#13][]) # [0.5.3](https://github.com/G-Rath/audit-app/compare/v0.5.2...v0.5.3) (2021-06-11) @@ -98,6 +99,7 @@ to be updated. Initial Release 🎉 +[#14]: https://github.com/G-Rath/audit-app/pull/14 [#13]: https://github.com/G-Rath/audit-app/pull/13 [#11]: https://github.com/G-Rath/audit-app/pull/11 [#10]: https://github.com/G-Rath/audit-app/pull/10 diff --git a/src/audit.ts b/src/audit.ts index f215fcf..fc5cac2 100644 --- a/src/audit.ts +++ b/src/audit.ts @@ -78,6 +78,7 @@ const npm7AdvisoryToFinding = (advisory: Npm7Advisory): Finding => ({ id: advisory.source, name: advisory.name, paths: [advisory.dependency], + versions: [], range: advisory.range, severity: advisory.severity, title: advisory.title, @@ -91,6 +92,7 @@ const npm6AdvisoryToFinding = (advisory: Npm6Advisory): Finding => ({ (acc, finding) => acc.concat(finding.paths), [] ), + versions: advisory.findings.map(finding => finding.version), range: advisory.vulnerable_versions, severity: advisory.severity, title: advisory.title, diff --git a/src/formatReport.ts b/src/formatReport.ts index 6feafca..3f92770 100644 --- a/src/formatReport.ts +++ b/src/formatReport.ts @@ -160,7 +160,12 @@ const buildFindingsTable = (finding: Finding): string => severityColors[finding.severity](finding.severity), chalk.whiteBright(`${finding.title} (#${finding.id})`) ], - ['Package', finding.name], + [ + 'Package', + `${finding.name} ${Array.from(new Set(finding.versions)) + .map(version => `v${version}`) + .join(', ')}` + ], ['Vulnerable range', finding.range], ['More info', finding.url] ]).join('\n'); diff --git a/src/types.ts b/src/types.ts index ed36ffe..a281b28 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,6 +47,7 @@ export interface Finding { id: number; name: string; paths: string[]; + versions: string[]; range: string; severity: Severity; title: string; diff --git a/test/buildFinding.ts b/test/buildFinding.ts index 8007da7..4ff94ab 100644 --- a/test/buildFinding.ts +++ b/test/buildFinding.ts @@ -4,6 +4,7 @@ export const buildFinding = (finding: Partial): Finding => ({ id: 1500, name: 'yargs-parser', paths: [`${finding.id ?? 1500}|${finding.name ?? 'yargs-parser'}`], + versions: ['9.0.2', '10.1.0'], range: '<13.1.2 || >=14.0.0 <15.0.1 || >=16.0.0 <18.1.2', severity: 'low', title: 'Prototype Pollution', diff --git a/test/src/audit.spec.ts b/test/src/audit.spec.ts index 813e782..ec72929 100644 --- a/test/src/audit.spec.ts +++ b/test/src/audit.spec.ts @@ -102,6 +102,9 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [ + "0.0.8", + ], }, } `); @@ -136,6 +139,9 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [ + "0.0.8", + ], }, } `); @@ -187,6 +193,9 @@ describe('audit', () => { "severity": "moderate", "title": "Cross-Site Scripting", "url": "https://npmjs.com/advisories/1429", + "versions": Array [ + "1.0.0", + ], }, "790": Object { "id": 790, @@ -198,6 +207,9 @@ describe('audit', () => { "severity": "high", "title": "Denial of Service", "url": "https://npmjs.com/advisories/790", + "versions": Array [ + "1.0.0", + ], }, } `); @@ -271,6 +283,7 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [], }, } `); @@ -309,6 +322,7 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [], }, } `); @@ -346,6 +360,7 @@ describe('audit', () => { "severity": "moderate", "title": "Cross-Site Scripting", "url": "https://npmjs.com/advisories/1429", + "versions": Array [], }, "790": Object { "id": 790, @@ -357,6 +372,7 @@ describe('audit', () => { "severity": "high", "title": "Denial of Service", "url": "https://npmjs.com/advisories/790", + "versions": Array [], }, } `); @@ -460,6 +476,9 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [ + "0.0.8", + ], }, } `); @@ -493,6 +512,9 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [ + "0.0.8", + ], }, } `); @@ -527,6 +549,9 @@ describe('audit', () => { "severity": "moderate", "title": "Cross-Site Scripting", "url": "https://npmjs.com/advisories/1429", + "versions": Array [ + "1.0.0", + ], }, "790": Object { "id": 790, @@ -538,6 +563,9 @@ describe('audit', () => { "severity": "high", "title": "Denial of Service", "url": "https://npmjs.com/advisories/790", + "versions": Array [ + "1.0.0", + ], }, } `); @@ -617,6 +645,9 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [ + "0.0.8", + ], }, } `); @@ -655,6 +686,9 @@ describe('audit', () => { "severity": "low", "title": "Prototype Pollution", "url": "https://npmjs.com/advisories/1179", + "versions": Array [ + "0.0.8", + ], }, } `); @@ -693,6 +727,9 @@ describe('audit', () => { "severity": "moderate", "title": "Cross-Site Scripting", "url": "https://npmjs.com/advisories/1429", + "versions": Array [ + "1.0.0", + ], }, "790": Object { "id": 790, @@ -704,6 +741,9 @@ describe('audit', () => { "severity": "high", "title": "Denial of Service", "url": "https://npmjs.com/advisories/790", + "versions": Array [ + "1.0.0", + ], }, } `); diff --git a/test/src/formatReport.spec.ts b/test/src/formatReport.spec.ts index bcd5474..b47cf5e 100644 --- a/test/src/formatReport.spec.ts +++ b/test/src/formatReport.spec.ts @@ -192,7 +192,7 @@ describe('formatReport', () => { ┌──────────────────┬──────────────────────────────────────────────────────────────┐ │ low │ My Second Advisory (#1234) │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ - │ Package │ yargs-parser │ + │ Package │ yargs-parser v9.0.2, v10.1.0 │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ │ Vulnerable range │ <13.1.2 || >=14.0.0 <15.0.1 || >=16.0.0 <18.1.2 │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ @@ -222,7 +222,7 @@ describe('formatReport', () => { │ │ looooooooooooooooooooooooooooooooooooooooooooooooooooooong │ │ │ name (#1234) │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ - │ Package │ yargs-parser │ + │ Package │ yargs-parser v9.0.2, v10.1.0 │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ │ Vulnerable range │ <1.2.3 || >2.0.0 < 2.2.1 || >=3.0.0 <3.0.1 || >= 4.0.0 │ │ │ <4.0.3 │ @@ -253,7 +253,7 @@ describe('formatReport', () => { │ │ looooooooooooooooooooooooooooooooooooooooooooooooooooooooooo │ │ │ ooooooooooooooooooooooooooooooooooooooooong name (#1234) │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ - │ Package │ yargs-parser │ + │ Package │ yargs-parser v9.0.2, v10.1.0 │ ├──────────────────┼──────────────────────────────────────────────────────────────┤ │ Vulnerable range │ >=1.0.000000000000000000000000000000000000000000000000000000 │ │ │ 0000000000000000000000000000000000000000000000 < 1.5.0 │ @@ -307,9 +307,9 @@ describe('formatReport', () => { ).toMatchInlineSnapshot(` " ┌────────────┬────────────────────────────────────────────────────────────────────┐ - │ Package │ A │ - │ Package │ B │ - │ Package │ C │ + │ Package │ A v9.0.2, v10.1.0 │ + │ Package │ B v9.0.2, v10.1.0 │ + │ Package │ C v9.0.2, v10.1.0 │ └────────────┴────────────────────────────────────────────────────────────────────┘ " `);