mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
feat: show brief package list in image CVE listings (#2338)
Signed-off-by: Vishwas Rajashekar <vrajashe@cisco.com>
This commit is contained in:
parent
4105f120ef
commit
aa53782e5c
5 changed files with 146 additions and 49 deletions
|
@ -140,9 +140,22 @@ func TestSearchCVECmd(t *testing.T) {
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
err := cmd.Execute()
|
err := cmd.Execute()
|
||||||
space := regexp.MustCompile(`\s+`)
|
space := regexp.MustCompile(`\s+`)
|
||||||
str := space.ReplaceAllString(buff.String(), " ")
|
outputLines := strings.Split(buff.String(), "\n")
|
||||||
So(strings.TrimSpace(str), ShouldEqual, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1 "+
|
|
||||||
"ID SEVERITY TITLE dummyCVEID HIGH Title of that CVE")
|
expected := []string{
|
||||||
|
"CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1",
|
||||||
|
"",
|
||||||
|
"ID SEVERITY TITLE VULNERABLE PACKAGE PATH INSTALL-VER FIXED-VER",
|
||||||
|
"dummyCVEID HIGH Title of that CVE",
|
||||||
|
"packagename - installedver fixedver",
|
||||||
|
}
|
||||||
|
|
||||||
|
for expectedLineIndex, expectedLine := range expected {
|
||||||
|
currentOutputLine := outputLines[expectedLineIndex]
|
||||||
|
str := space.ReplaceAllString(currentOutputLine, " ")
|
||||||
|
So(strings.TrimSpace(str), ShouldEqual, expectedLine)
|
||||||
|
}
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -207,9 +220,22 @@ func TestSearchCVECmd(t *testing.T) {
|
||||||
cveCmd.SetArgs(args)
|
cveCmd.SetArgs(args)
|
||||||
err := cveCmd.Execute()
|
err := cveCmd.Execute()
|
||||||
space := regexp.MustCompile(`\s+`)
|
space := regexp.MustCompile(`\s+`)
|
||||||
str := space.ReplaceAllString(buff.String(), " ")
|
outputLines := strings.Split(buff.String(), "\n")
|
||||||
So(strings.TrimSpace(str), ShouldEqual, "CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1 "+
|
|
||||||
"ID SEVERITY TITLE dummyCVEID HIGH Title of that CVE")
|
expected := []string{
|
||||||
|
"CRITICAL 0, HIGH 1, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 1",
|
||||||
|
"",
|
||||||
|
"ID SEVERITY TITLE VULNERABLE PACKAGE PATH INSTALL-VER FIXED-VER",
|
||||||
|
"dummyCVEID HIGH Title of that CVE",
|
||||||
|
"packagename - installedver fixedver",
|
||||||
|
}
|
||||||
|
|
||||||
|
for expectedLineIndex, expectedLine := range expected {
|
||||||
|
currentOutputLine := outputLines[expectedLineIndex]
|
||||||
|
str := space.ReplaceAllString(currentOutputLine, " ")
|
||||||
|
So(strings.TrimSpace(str), ShouldEqual, expectedLine)
|
||||||
|
}
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -901,15 +901,25 @@ func TestCVESort(t *testing.T) {
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
err := cmd.Execute()
|
err := cmd.Execute()
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
str := space.ReplaceAllString(buff.String(), " ")
|
|
||||||
actual := strings.TrimSpace(str)
|
outputLines := strings.Split(buff.String(), "\n")
|
||||||
So(actual, ShouldResemble,
|
|
||||||
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5 ID SEVERITY TITLE "+
|
expected := []string{
|
||||||
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par... "+
|
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5",
|
||||||
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ... "+
|
"",
|
||||||
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif... "+
|
"ID SEVERITY TITLE VULNERABLE PACKAGE PATH INSTALL-VER FIXED-VER",
|
||||||
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ... "+
|
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par...",
|
||||||
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat...")
|
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ...",
|
||||||
|
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif...",
|
||||||
|
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ...",
|
||||||
|
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat...",
|
||||||
|
}
|
||||||
|
|
||||||
|
for expectedLineIndex, expectedLine := range expected {
|
||||||
|
currentOutputLine := outputLines[expectedLineIndex]
|
||||||
|
str := space.ReplaceAllString(currentOutputLine, " ")
|
||||||
|
So(strings.TrimSpace(str), ShouldResemble, expectedLine)
|
||||||
|
}
|
||||||
|
|
||||||
args = []string{"list", "repo:tag", "--sort-by", "alpha-asc", "--url", baseURL}
|
args = []string{"list", "repo:tag", "--sort-by", "alpha-asc", "--url", baseURL}
|
||||||
cmd = client.NewCVECommand(client.NewSearchService())
|
cmd = client.NewCVECommand(client.NewSearchService())
|
||||||
|
@ -919,15 +929,25 @@ func TestCVESort(t *testing.T) {
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
err = cmd.Execute()
|
err = cmd.Execute()
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
str = space.ReplaceAllString(buff.String(), " ")
|
|
||||||
actual = strings.TrimSpace(str)
|
outputLines = strings.Split(buff.String(), "\n")
|
||||||
So(actual, ShouldResemble,
|
|
||||||
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5 ID SEVERITY TITLE "+
|
expected = []string{
|
||||||
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat... "+
|
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5",
|
||||||
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif... "+
|
"",
|
||||||
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ... "+
|
"ID SEVERITY TITLE VULNERABLE PACKAGE PATH INSTALL-VER FIXED-VER",
|
||||||
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par... "+
|
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat...",
|
||||||
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ...")
|
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif...",
|
||||||
|
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ...",
|
||||||
|
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par...",
|
||||||
|
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ...",
|
||||||
|
}
|
||||||
|
|
||||||
|
for expectedLineIndex, expectedLine := range expected {
|
||||||
|
currentOutputLine := outputLines[expectedLineIndex]
|
||||||
|
str := space.ReplaceAllString(currentOutputLine, " ")
|
||||||
|
So(strings.TrimSpace(str), ShouldResemble, expectedLine)
|
||||||
|
}
|
||||||
|
|
||||||
args = []string{"list", "repo:tag", "--sort-by", "alpha-dsc", "--url", baseURL}
|
args = []string{"list", "repo:tag", "--sort-by", "alpha-dsc", "--url", baseURL}
|
||||||
cmd = client.NewCVECommand(client.NewSearchService())
|
cmd = client.NewCVECommand(client.NewSearchService())
|
||||||
|
@ -937,15 +957,25 @@ func TestCVESort(t *testing.T) {
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
err = cmd.Execute()
|
err = cmd.Execute()
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
str = space.ReplaceAllString(buff.String(), " ")
|
|
||||||
actual = strings.TrimSpace(str)
|
outputLines = strings.Split(buff.String(), "\n")
|
||||||
So(actual, ShouldResemble,
|
|
||||||
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5 ID SEVERITY TITLE "+
|
expected = []string{
|
||||||
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ... "+
|
"CRITICAL 1, HIGH 1, MEDIUM 2, LOW 1, UNKNOWN 0, TOTAL 5",
|
||||||
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par... "+
|
"",
|
||||||
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ... "+
|
"ID SEVERITY TITLE VULNERABLE PACKAGE PATH INSTALL-VER FIXED-VER",
|
||||||
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif... "+
|
"CVE-2023-3817 MEDIUM Excessive time spent checking DH q parameter ...",
|
||||||
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat...")
|
"CVE-2023-3446 CRITICAL Excessive time spent checking DH keys and par...",
|
||||||
|
"CVE-2023-2975 HIGH AES-SIV cipher implementation contains a bug ...",
|
||||||
|
"CVE-2023-2650 MEDIUM Possible DoS translating ASN.1 object identif...",
|
||||||
|
"CVE-2023-1255 LOW Input buffer over-read in AES-XTS implementat...",
|
||||||
|
}
|
||||||
|
|
||||||
|
for expectedLineIndex, expectedLine := range expected {
|
||||||
|
currentOutputLine := outputLines[expectedLineIndex]
|
||||||
|
str := space.ReplaceAllString(currentOutputLine, " ")
|
||||||
|
So(strings.TrimSpace(str), ShouldResemble, expectedLine)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,9 +390,12 @@ func TestSearchCVEForImageGQL(t *testing.T) {
|
||||||
expected := []string{
|
expected := []string{
|
||||||
"CRITICAL 0, HIGH 2, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 2",
|
"CRITICAL 0, HIGH 2, MEDIUM 0, LOW 0, UNKNOWN 0, TOTAL 2",
|
||||||
"",
|
"",
|
||||||
"ID SEVERITY TITLE",
|
"ID SEVERITY TITLE VULNERABLE PACKAGE PATH INSTALL-VER FIXED-VER",
|
||||||
"dummyCVEID HIGH Title of that CVE",
|
"dummyCVEID HIGH Title of that CVE",
|
||||||
|
"packagename - installedver fixedver",
|
||||||
"test-cve-id2 HIGH Test CVE 2",
|
"test-cve-id2 HIGH Test CVE 2",
|
||||||
|
"packagename /usr/bin/dummy.jar installedver fixedver",
|
||||||
|
"packagename /usr/bin/dummy.gem installedver fixedver",
|
||||||
}
|
}
|
||||||
|
|
||||||
space := regexp.MustCompile(`\s+`)
|
space := regexp.MustCompile(`\s+`)
|
||||||
|
|
|
@ -877,16 +877,21 @@ func (cve cveResult) stringPlainText() string {
|
||||||
|
|
||||||
table := getCVETableWriter(&builder)
|
table := getCVETableWriter(&builder)
|
||||||
|
|
||||||
for _, c := range cve.Data.CVEListForImage.CVEList {
|
for _, cveListItem := range cve.Data.CVEListForImage.CVEList {
|
||||||
id := ellipsize(c.ID, cveIDWidth, ellipsis)
|
id := ellipsize(cveListItem.ID, cveIDWidth, ellipsis)
|
||||||
title := ellipsize(c.Title, cveTitleWidth, ellipsis)
|
title := ellipsize(cveListItem.Title, cveTitleWidth, ellipsis)
|
||||||
severity := ellipsize(c.Severity, cveSeverityWidth, ellipsis)
|
severity := ellipsize(cveListItem.Severity, cveSeverityWidth, ellipsis)
|
||||||
row := make([]string, 3) //nolint:gomnd
|
row := make([]string, 3) //nolint:gomnd
|
||||||
row[colCVEIDIndex] = id
|
row[colCVEIDIndex] = id
|
||||||
row[colCVESeverityIndex] = severity
|
row[colCVESeverityIndex] = severity
|
||||||
row[colCVETitleIndex] = title
|
row[colCVETitleIndex] = title
|
||||||
|
|
||||||
table.Append(row)
|
table.Append(row)
|
||||||
|
|
||||||
|
for _, pkg := range cveListItem.PackageList {
|
||||||
|
pkgRow := generateTableRowForVulnerablePackage(pkg)
|
||||||
|
table.Append(pkgRow)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.Render()
|
table.Render()
|
||||||
|
@ -894,6 +899,25 @@ func (cve cveResult) stringPlainText() string {
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateTableRowForVulnerablePackage(pkg packageList) []string {
|
||||||
|
row := make([]string, cveColTotalCount)
|
||||||
|
pkgName := ellipsize(pkg.Name, cveVulnPkgNameWidth, ellipsis)
|
||||||
|
pkgPath := "-"
|
||||||
|
|
||||||
|
if pkg.PackagePath != "" {
|
||||||
|
pkgPath = ellipsize(pkg.PackagePath, cveVulnPkgPathWidth, ellipsis)
|
||||||
|
}
|
||||||
|
pkgInstalledVer := ellipsize(pkg.InstalledVersion, cveVulnPkgInstalledVerWidth, ellipsis)
|
||||||
|
pkgFixedVer := ellipsize(pkg.FixedVersion, cveVulnPkgFixedVerWidth, ellipsis)
|
||||||
|
|
||||||
|
row[colCVEVulnPkgNameIndex] = pkgName
|
||||||
|
row[colCVEVulnPkgPathIndex] = pkgPath
|
||||||
|
row[colCVEVulnPkgInstalledVerIndex] = pkgInstalledVer
|
||||||
|
row[colCVEVulnPkgFixedVerIndex] = pkgFixedVer
|
||||||
|
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
|
||||||
func (cve cveResult) stringJSON() (string, error) {
|
func (cve cveResult) stringJSON() (string, error) {
|
||||||
// Output is in json lines format - do not indent, append new line after json
|
// Output is in json lines format - do not indent, append new line after json
|
||||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
@ -1362,6 +1386,10 @@ func getCVETableWriter(writer io.Writer) *tablewriter.Table {
|
||||||
table.SetColMinWidth(colCVEIDIndex, cveIDWidth)
|
table.SetColMinWidth(colCVEIDIndex, cveIDWidth)
|
||||||
table.SetColMinWidth(colCVESeverityIndex, cveSeverityWidth)
|
table.SetColMinWidth(colCVESeverityIndex, cveSeverityWidth)
|
||||||
table.SetColMinWidth(colCVETitleIndex, cveTitleWidth)
|
table.SetColMinWidth(colCVETitleIndex, cveTitleWidth)
|
||||||
|
table.SetColMinWidth(colCVEVulnPkgNameIndex, cveVulnPkgNameWidth)
|
||||||
|
table.SetColMinWidth(colCVEVulnPkgPathIndex, cveVulnPkgPathWidth)
|
||||||
|
table.SetColMinWidth(colCVEVulnPkgInstalledVerIndex, cveVulnPkgInstalledVerWidth)
|
||||||
|
table.SetColMinWidth(colCVEVulnPkgFixedVerIndex, cveVulnPkgFixedVerWidth)
|
||||||
|
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
@ -1459,13 +1487,23 @@ const (
|
||||||
layersWidth = 8
|
layersWidth = 8
|
||||||
ellipsis = "..."
|
ellipsis = "..."
|
||||||
|
|
||||||
cveIDWidth = 16
|
cveIDWidth = 16
|
||||||
cveSeverityWidth = 8
|
cveSeverityWidth = 8
|
||||||
cveTitleWidth = 48
|
cveTitleWidth = 48
|
||||||
|
cveVulnPkgNameWidth = 35
|
||||||
|
cveVulnPkgPathWidth = 30
|
||||||
|
cveVulnPkgInstalledVerWidth = 20
|
||||||
|
cveVulnPkgFixedVerWidth = 20
|
||||||
|
|
||||||
colCVEIDIndex = 0
|
colCVEIDIndex = 0
|
||||||
colCVESeverityIndex = 1
|
colCVESeverityIndex = 1
|
||||||
colCVETitleIndex = 2
|
colCVETitleIndex = 2
|
||||||
|
colCVEVulnPkgNameIndex = 3
|
||||||
|
colCVEVulnPkgPathIndex = 4
|
||||||
|
colCVEVulnPkgInstalledVerIndex = 5
|
||||||
|
colCVEVulnPkgFixedVerIndex = 6
|
||||||
|
|
||||||
|
cveColTotalCount = 7
|
||||||
|
|
||||||
defaultOutputFormat = "text"
|
defaultOutputFormat = "text"
|
||||||
)
|
)
|
||||||
|
|
|
@ -184,12 +184,12 @@ func printImageTableHeader(writer io.Writer, verbose bool, maxImageNameLen, maxT
|
||||||
|
|
||||||
func printCVETableHeader(writer io.Writer) {
|
func printCVETableHeader(writer io.Writer) {
|
||||||
table := getCVETableWriter(writer)
|
table := getCVETableWriter(writer)
|
||||||
row := make([]string, 3) //nolint:gomnd
|
columnHeadingsRow := []string{
|
||||||
row[colCVEIDIndex] = "ID"
|
"ID", "SEVERITY", "TITLE",
|
||||||
row[colCVESeverityIndex] = "SEVERITY"
|
"VULNERABLE PACKAGE", "PATH", "INSTALL-VER", "FIXED-VER",
|
||||||
row[colCVETitleIndex] = "TITLE"
|
}
|
||||||
|
|
||||||
table.Append(row)
|
table.Append(columnHeadingsRow)
|
||||||
table.Render()
|
table.Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue