-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cap number of scan vulnerabilities reported (#728)
Signed-off-by: munishchouhan <[email protected]> Signed-off-by: Paolo Di Tommaso <[email protected]> Co-authored-by: Paolo Di Tommaso <[email protected]>
- Loading branch information
1 parent
adb7500
commit 2f0d8f9
Showing
6 changed files
with
114 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,8 @@ package io.seqera.wave.service.scan | |
import java.nio.file.Path | ||
|
||
import groovy.json.JsonSlurper | ||
import groovy.transform.CompileDynamic | ||
import groovy.transform.CompileStatic | ||
import groovy.util.logging.Slf4j | ||
import io.seqera.wave.exception.ScanRuntimeException | ||
/** | ||
|
@@ -30,16 +32,23 @@ import io.seqera.wave.exception.ScanRuntimeException | |
* @author Paolo Di Tommaso <[email protected]> | ||
*/ | ||
@Slf4j | ||
@CompileStatic | ||
class TrivyResultProcessor { | ||
|
||
static List<ScanVulnerability> process(Path reportFile) { | ||
process(reportFile.getText()) | ||
static List<ScanVulnerability> parse(Path scanFile) { | ||
return parse(scanFile.getText()) | ||
} | ||
|
||
static List<ScanVulnerability> process(String trivyResult) { | ||
static List<ScanVulnerability> parse(Path scanFile, int maxEntries) { | ||
final result = parse(scanFile) | ||
return filter(result, maxEntries) | ||
} | ||
|
||
@CompileDynamic | ||
static List<ScanVulnerability> parse(String scanJson) { | ||
final slurper = new JsonSlurper() | ||
try{ | ||
final jsonMap = slurper.parseText(trivyResult) as Map | ||
final jsonMap = slurper.parseText(scanJson) as Map | ||
return jsonMap.Results.collect { result -> | ||
result.Vulnerabilities.collect { vulnerability -> | ||
new ScanVulnerability( | ||
|
@@ -57,4 +66,8 @@ class TrivyResultProcessor { | |
throw new ScanRuntimeException("Failed to parse the trivy result", e) | ||
} | ||
} | ||
|
||
static protected List<ScanVulnerability> filter(List<ScanVulnerability> vulnerabilities, int limit){ | ||
vulnerabilities.toSorted((v,w) -> w.compareTo(v)).take(limit) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,7 +91,7 @@ class TrivyResultProcessorTest extends Specification { | |
""" | ||
|
||
when: | ||
def result = TrivyResultProcessor.process(trivyDockerResulJson) | ||
def result = TrivyResultProcessor.parse(trivyDockerResulJson) | ||
|
||
then: | ||
def vulnerability = result[0] | ||
|
@@ -105,9 +105,94 @@ class TrivyResultProcessorTest extends Specification { | |
|
||
} | ||
|
||
def "should return a sorted map of vulnerabilities"() { | ||
given: | ||
def trivyDockerResulJson = """ | ||
{ "Results": [ | ||
{ | ||
"Target": "sample-application", | ||
"Class": "os-pkgs", | ||
"Type": "linux", | ||
"Vulnerabilities": [ | ||
{ | ||
"VulnerabilityID": "CVE-2023-0001", | ||
"PkgID": "[email protected]", | ||
"PkgName": "example-lib", | ||
"InstalledVersion": "1.0.0", | ||
"FixedVersion": "1.0.1", | ||
"Severity": "LOW", | ||
"Description": "A minor vulnerability with low impact.", | ||
"PrimaryURL": "https://example.com/CVE-2023-0001" | ||
}, | ||
{ | ||
"VulnerabilityID": "CVE-2023-0002", | ||
"PkgID": "[email protected]", | ||
"PkgName": "example-lib", | ||
"InstalledVersion": "1.2.3", | ||
"FixedVersion": "1.2.4", | ||
"Severity": "MEDIUM", | ||
"Description": "A vulnerability that allows unauthorized access.", | ||
"PrimaryURL": "https://example.com/CVE-2023-0002" | ||
}, | ||
{ | ||
"VulnerabilityID": "CVE-2023-0003", | ||
"PkgID": "[email protected]", | ||
"PkgName": "example-lib", | ||
"InstalledVersion": "2.3.4", | ||
"FixedVersion": "2.3.5", | ||
"Severity": "HIGH", | ||
"Description": "A vulnerability that could lead to remote code execution.", | ||
"PrimaryURL": "https://example.com/CVE-2023-0003" | ||
}, | ||
{ | ||
"VulnerabilityID": "CVE-2023-0004", | ||
"PkgID": "[email protected]", | ||
"PkgName": "example-lib", | ||
"InstalledVersion": "3.0.0", | ||
"FixedVersion": "3.0.1", | ||
"Severity": "HIGH", | ||
"Description": "A random test vulnerability with unspecified impact.", | ||
"PrimaryURL": "https://example.com/CVE-2023-0004" | ||
}, | ||
{ | ||
"VulnerabilityID": "CVE-2023-0005", | ||
"PkgID": "[email protected]", | ||
"PkgName": "example-lib", | ||
"InstalledVersion": "3.1.0", | ||
"FixedVersion": "3.1.1", | ||
"Severity": "CRITICAL", | ||
"Description": "Another random test vulnerability for testing purposes.", | ||
"PrimaryURL": "https://example.com/CVE-2023-0005" | ||
} | ||
] | ||
} | ||
] | ||
}""".stripIndent() | ||
|
||
when: | ||
def result = TrivyResultProcessor.parse(trivyDockerResulJson) | ||
result = TrivyResultProcessor.filter(result, 4) | ||
|
||
then: | ||
result.size() == 4 | ||
result[0].severity == "CRITICAL" | ||
result[0].id == "CVE-2023-0005" | ||
result[1].severity == "HIGH" | ||
result[1].id == "CVE-2023-0003" | ||
result[2].severity == "HIGH" | ||
result[2].id == "CVE-2023-0004" | ||
result[3].severity == "MEDIUM" | ||
result[3].id == "CVE-2023-0002" | ||
} | ||
|
||
def 'should not fail with empty list' () { | ||
expect: | ||
TrivyResultProcessor.filter([], 10) == [] | ||
} | ||
|
||
def "process should throw exception if json is not correct"() { | ||
when: | ||
TrivyResultProcessor.process("invalid json") | ||
TrivyResultProcessor.parse("invalid json") | ||
then: | ||
thrown ScanRuntimeException | ||
} | ||
|