Skip to content

Commit 0e483c3

Browse files
Add filter by package name/version to avoid flood of issues for the same package (#23)
* Add filter by package name/version to avoid duplicating on the build output
1 parent cda2e24 commit 0e483c3

File tree

9 files changed

+103
-8
lines changed

9 files changed

+103
-8
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ Possible values:
7272
- negligible
7373
- unknown
7474

75+
### `unique-report-by-package`
76+
77+
Only one annotation by package name/version will be displayed in the build output.
78+
The last highest (by severity) vulnerability will be displayed by package.
79+
It increases the readability of the output, avoiding duplicates for the same package.
80+
Default to false.
81+
7582

7683
### `inline-scan-image`
7784

action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ inputs:
2424
ignore-failed-scan:
2525
description: Don't fail the execution of this action even if the scan result is FAILED.
2626
required: false
27+
unique-report-by-package:
28+
description: Report only once an issue with a specific package and its version. Default to false
29+
required: false
2730
input-type:
2831
description: |
2932
If specified, where should we scan the image from. Possible values:

dist/index.js

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,16 @@ function getReportAnnotations(evaluationResults, vulnerabilities) {
504504
title: `${g[actionCol]} ${g[gateCol]}`
505505
}
506506
});
507-
let severities = {"critcal":0,"high":1, "medium":2, "low":3, "negligible":4,"unknown":5}
507+
let severities = {"critical":0,"high":1, "medium":2, "low":3, "negligible":4,"unknown":5}
508508
let severity = core.getInput('severity') || "unknown";
509-
let vulns = vulnerabilities.filter(v => severities[v.severity.toLowerCase()] <= severities[severity.toLowerCase()]).map(v => {
509+
let uniqueReportByPackage = core.getInput('unique-report-by-package') === 'true' || false;
510+
let _vulns = vulnerabilities
511+
if(uniqueReportByPackage) {
512+
const key = 'package'; // Show only one issue by package, avoiding flood of annotations
513+
let _sortedVulns = _vulns.sort((a, b) => severities[b.severity.toLowerCase()] - severities[a.severity.toLowerCase()]);
514+
_vulns = [...new Map(_sortedVulns.map(item => [item[key], item])).values()];
515+
}
516+
let vulns = _vulns.filter(v => severities[v.severity.toLowerCase()] <= severities[severity.toLowerCase()]).map(v => {
510517
return {
511518
path: "Dockerfile",
512519
start_line: 1,

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "secure-inline-scan-action",
3-
"version": "3.3.0",
3+
"version": "3.4.0",
44
"description": "This actions performs image analysis on locally built container image and posts the result of the analysis to Sysdig Secure.",
55
"main": "index.js",
66
"scripts": {

tests/fixtures/report.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,37 @@
141141
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3374",
142142
"vendor_data": [],
143143
"vuln": "CVE-2011-3374"
144+
},
145+
{
146+
"feed": "vulnerabilities",
147+
"feed_group": "alpine:3.7",
148+
"fix": "1.1.18-r4",
149+
"nvd_data": [
150+
{
151+
"cvss_v2": {
152+
"base_score": 7.5,
153+
"exploitability_score": 10,
154+
"impact_score": 6.4
155+
},
156+
"cvss_v3": {
157+
"base_score": 9.8,
158+
"exploitability_score": 3.9,
159+
"impact_score": 5.9
160+
},
161+
"id": "CVE-2019-14698"
162+
}
163+
],
164+
"package": "musl-utils-1.1.18-r3",
165+
"package_cpe": "None",
166+
"package_cpe23": "None",
167+
"package_name": "musl-utils",
168+
"package_path": "pkgdb",
169+
"package_type": "APKG",
170+
"package_version": "1.1.18-r3",
171+
"severity": "Medium",
172+
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14698",
173+
"vendor_data": [],
174+
"vuln": "CVE-2019-14698"
144175
}
145176
]
146177
}

tests/index.test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,46 @@ describe("process scan results", () => {
421421
expect(data.name).toBe("Scan results for myimage:mytag");
422422
expect(data.output.annotations).toContainEqual({ "annotation_level": "warning", "end_line": 1, "message": "CVE-2019-14697 Severity=High Package=musl-1.1.18-r3 Type=APKG Fix=1.1.18-r4 Url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14697", "path": "Dockerfile", "start_line": 1, "title": "Vulnerability found: CVE-2019-14697" });
423423
expect(data.output.annotations).not.toContainEqual({"path": "Dockerfile", "start_line": 1, "end_line": 1, "annotation_level": "warning", "message": "CVE-2011-3374 Severity=Negligible Package=apt-1.0 Type=APKG Fix=null Url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3374", "title": "Vulnerability found: CVE-2011-3374"});
424+
expect(data.output.annotations).toContainEqual({"path": "Dockerfile", "start_line": 1, "end_line": 1, "annotation_level": "warning", "message": "CVE-2019-14697 Severity=High Package=musl-utils-1.1.18-r3 Type=APKG Fix=1.1.18-r4 Url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14697", "title": "Vulnerability found: CVE-2019-14697"});
425+
expect(data.output.annotations).toContainEqual({"path": "Dockerfile", "start_line": 1, "end_line": 1, "annotation_level": "warning", "message": "CVE-2019-14698 Severity=Medium Package=musl-utils-1.1.18-r3 Type=APKG Fix=1.1.18-r4 Url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14698", "title": "Vulnerability found: CVE-2019-14698"});
426+
})
427+
428+
it("generates a check run with unique vulnerability annotations", async () => {
429+
let data;
430+
github.context = { repo: { repo: "foo-repo", owner: "foo-owner" } };
431+
432+
core.getInput = jest.fn();
433+
core.getInput.mockReturnValueOnce("foo");
434+
435+
436+
github.getOctokit = jest.fn(() => {
437+
return {
438+
rest: {
439+
checks: {
440+
create: async function (receivedData) {
441+
data = receivedData;
442+
}
443+
}
444+
}
445+
}
446+
});
447+
448+
let scanResult = {
449+
ReturnCode: 0,
450+
Output: exampleReport,
451+
Error: ""
452+
};
453+
core.getInput.mockReturnValueOnce("medium")
454+
core.getInput.mockReturnValueOnce("true")
455+
456+
await index.processScanResult(scanResult);
457+
expect(github.getOctokit).toBeCalledWith("foo");
458+
expect(data).not.toBeUndefined();
459+
expect(data.name).toBe("Scan results for myimage:mytag");
460+
//Should display the vulnerability with the highest severity
461+
expect(data.output.annotations).toContainEqual({"path": "Dockerfile", "start_line": 1, "end_line": 1, "annotation_level": "warning", "message": "CVE-2019-14697 Severity=High Package=musl-utils-1.1.18-r3 Type=APKG Fix=1.1.18-r4 Url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14697", "title": "Vulnerability found: CVE-2019-14697"});
462+
expect(data.output.annotations).not.toContainEqual({"path": "Dockerfile", "start_line": 1, "end_line": 1, "annotation_level": "warning", "message": "CVE-2019-14698 Severity=Medium Package=musl-utils-1.1.18-r3 Type=APKG Fix=1.1.18-r4 Url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14698", "title": "Vulnerability found: CVE-2019-14698"});
463+
424464
})
425465

426466
it("generates a check run with gate annotations", async () => {

0 commit comments

Comments
 (0)