mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 07:40:48 -08:00
216 lines
7.4 KiB
Go
216 lines
7.4 KiB
Go
package report_test
|
|
|
|
import (
|
|
"bytes"
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
|
"github.com/aquasecurity/trivy/pkg/report"
|
|
"github.com/aquasecurity/trivy/pkg/types"
|
|
)
|
|
|
|
func TestReportWriter_Template(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
detectedVulns []types.DetectedVulnerability
|
|
template string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "happy path",
|
|
detectedVulns: []types.DetectedVulnerability{
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "foo",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Severity: dbTypes.SeverityHigh.String(),
|
|
},
|
|
},
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "bar",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Severity: dbTypes.SeverityHigh.String()},
|
|
},
|
|
{
|
|
VulnerabilityID: "CVE-2019-0001",
|
|
PkgName: "baz",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Severity: dbTypes.SeverityCritical.String(),
|
|
},
|
|
},
|
|
},
|
|
template: "{{ range . }}{{ range .Vulnerabilities}}{{ println .VulnerabilityID .Severity }}{{ end }}{{ end }}",
|
|
expected: "CVE-2019-0000 HIGH\nCVE-2019-0000 HIGH\nCVE-2019-0001 CRITICAL\n",
|
|
},
|
|
{
|
|
name: "happy path",
|
|
detectedVulns: []types.DetectedVulnerability{
|
|
{
|
|
VulnerabilityID: "123",
|
|
PkgName: `foo \ test`,
|
|
InstalledVersion: "1.2.3",
|
|
FixedVersion: "3.4.5",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Title: `gcc: POWER9 "DARN" RNG intrinsic produces repeated output`,
|
|
Description: `curl version curl \X 7.20.0 to and including curl 7.59.0 contains a CWE-126: Buffer Over-read vulnerability in denial of service that can result in curl can be tricked into reading data beyond the end of a heap based buffer used to store downloaded RTSP content.. This vulnerability appears to have been fixed in curl < 7.20.0 and curl >= 7.60.0.`,
|
|
Severity: "HIGH",
|
|
},
|
|
},
|
|
},
|
|
template: `<testsuites>
|
|
{{- range . -}}
|
|
{{- $failures := len .Vulnerabilities }}
|
|
<testsuite tests="{{ $failures }}" failures="{{ $failures }}" name="{{ .Target }}" errors="0" skipped="0" time="">
|
|
{{- if not (eq .Type "") }}
|
|
<properties>
|
|
<property name="type" value="{{ .Type }}"></property>
|
|
</properties>
|
|
{{- end -}}
|
|
{{ range .Vulnerabilities }}
|
|
<testcase classname="{{ .PkgName }}-{{ .InstalledVersion }}" name="[{{ .Vulnerability.Severity }}] {{ .VulnerabilityID }}" time="">
|
|
<failure message="{{ escapeXML .Title }}" type="description">{{ escapeXML .Description }}</failure>
|
|
</testcase>
|
|
{{- end }}
|
|
</testsuite>
|
|
{{- end }}
|
|
</testsuites>`,
|
|
|
|
expected: `<testsuites>
|
|
<testsuite tests="1" failures="1" name="foojunit" errors="0" skipped="0" time="">
|
|
<properties>
|
|
<property name="type" value="test"></property>
|
|
</properties>
|
|
<testcase classname="foo \ test-1.2.3" name="[HIGH] 123" time="">
|
|
<failure message="gcc: POWER9 "DARN" RNG intrinsic produces repeated output" type="description">curl version curl \X 7.20.0 to and including curl 7.59.0 contains a CWE-126: Buffer Over-read vulnerability in denial of service that can result in curl can be tricked into reading data beyond the end of a heap based buffer used to store downloaded RTSP content.. This vulnerability appears to have been fixed in curl < 7.20.0 and curl >= 7.60.0.</failure>
|
|
</testcase>
|
|
</testsuite>
|
|
</testsuites>`,
|
|
},
|
|
{
|
|
name: "happy path with/without period description should return with period",
|
|
detectedVulns: []types.DetectedVulnerability{
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "foo",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Description: "without period",
|
|
},
|
|
},
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "bar",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Description: "with period.",
|
|
},
|
|
},
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "bar",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Description: `with period and unescaped string curl: Use-after-free when closing 'easy' handle in Curl_close().`,
|
|
},
|
|
},
|
|
},
|
|
template: `{{ range . }}{{ range .Vulnerabilities}}{{.VulnerabilityID}} {{ endWithPeriod (escapeString .Description) | printf "%q" }}{{ end }}{{ end }}`,
|
|
expected: `CVE-2019-0000 "without period."CVE-2019-0000 "with period."CVE-2019-0000 "with period and unescaped string curl: Use-after-free when closing 'easy' handle in Curl_close()."`,
|
|
},
|
|
{
|
|
name: "Calculate using sprig",
|
|
detectedVulns: []types.DetectedVulnerability{
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "foo",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Description: "without period",
|
|
Severity: dbTypes.SeverityCritical.String(),
|
|
},
|
|
},
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "bar",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Description: "with period.",
|
|
Severity: dbTypes.SeverityCritical.String(),
|
|
},
|
|
},
|
|
{
|
|
VulnerabilityID: "CVE-2019-0000",
|
|
PkgName: "bar",
|
|
Vulnerability: dbTypes.Vulnerability{
|
|
Description: `with period and unescaped string curl: Use-after-free when closing 'easy' handle in Curl_close().`,
|
|
Severity: dbTypes.SeverityHigh.String(),
|
|
},
|
|
},
|
|
},
|
|
template: `{{ $high := 0 }}{{ $critical := 0 }}{{ range . }}{{ range .Vulnerabilities}}{{ if eq .Severity "HIGH" }}{{ $high = add $high 1 }}{{ end }}{{ if eq .Severity "CRITICAL" }}{{ $critical = add $critical 1 }}{{ end }}{{ end }}Critical: {{ $critical }}, High: {{ $high }}{{ end }}`,
|
|
expected: `Critical: 2, High: 1`,
|
|
},
|
|
{
|
|
name: "happy path: env var parsing and getCurrentTime",
|
|
detectedVulns: []types.DetectedVulnerability{},
|
|
template: `{{ toLower (getEnv "AWS_ACCOUNT_ID") }} {{ getCurrentTime }}`,
|
|
expected: `123456789012 2020-08-10T07:28:17.000958601Z`,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
report.Now = func() time.Time {
|
|
return time.Date(2020, 8, 10, 7, 28, 17, 958601, time.UTC)
|
|
}
|
|
os.Setenv("AWS_ACCOUNT_ID", "123456789012")
|
|
tmplWritten := bytes.Buffer{}
|
|
inputReport := report.Report{
|
|
Results: report.Results{
|
|
{
|
|
Target: "foojunit",
|
|
Type: "test",
|
|
Vulnerabilities: tc.detectedVulns,
|
|
},
|
|
},
|
|
}
|
|
|
|
assert.NoError(t, report.Write("template", &tmplWritten, nil, inputReport, tc.template, false, false))
|
|
assert.Equal(t, tc.expected, tmplWritten.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReportWriter_Template_SARIF(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
target string
|
|
detectedVulns []types.DetectedVulnerability
|
|
want string
|
|
}{
|
|
//TODO: refactor tests
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
templateFile := "../../contrib/sarif.tpl"
|
|
got := bytes.Buffer{}
|
|
|
|
template, err := ioutil.ReadFile(templateFile)
|
|
require.NoError(t, err, tc.name)
|
|
|
|
inputReport := report.Report{
|
|
Results: report.Results{
|
|
{
|
|
Target: tc.target,
|
|
Type: "footype",
|
|
Vulnerabilities: tc.detectedVulns,
|
|
},
|
|
},
|
|
}
|
|
assert.NoError(t, report.Write("template", &got, nil, inputReport, string(template), false, false), tc.name)
|
|
assert.JSONEq(t, tc.want, got.String(), tc.name)
|
|
})
|
|
}
|
|
}
|