From 96c3592db1c4b3d658e8e8169fdc17c670e48379 Mon Sep 17 00:00:00 2001 From: MaineK00n Date: Fri, 13 Aug 2021 18:00:55 +0900 Subject: [PATCH] breaking-change(go-cve-dict): support new go-cve-dictionary (#1277) * feat(model): change CveContents(map[string]CveContent) to map[string][]CveContent * fix(cpescan): use CveIDSource * chore: check Nvd, Jvn data * chore: go-cve-dictionary update * chore: add to cveDetails as is, since CveID is embedded in the response --- contrib/trivy/parser/parser.go | 4 +- contrib/trivy/parser/parser_test.go | 324 ++++++++++++++-------------- detector/cve_client.go | 14 +- detector/detector.go | 36 ++-- detector/github.go | 2 +- detector/util.go | 19 +- go.mod | 2 +- go.sum | 4 +- gost/debian.go | 2 +- gost/microsoft.go | 2 +- gost/redhat.go | 4 +- gost/ubuntu.go | 2 +- models/cvecontents.go | 97 +++++---- models/cvecontents_test.go | 28 +-- models/library.go | 6 +- models/scanresults.go | 25 ++- models/scanresults_test.go | 32 +-- models/utils.go | 192 +++++++++-------- models/vulninfos.go | 200 ++++++++++------- models/vulninfos_test.go | 260 +++++++++++----------- oval/debian.go | 18 +- oval/redhat.go | 28 ++- oval/suse.go | 10 +- reporter/slack.go | 19 +- reporter/syslog.go | 20 +- reporter/syslog_test.go | 8 +- reporter/util.go | 21 +- tui/tui.go | 8 +- 28 files changed, 740 insertions(+), 647 deletions(-) diff --git a/contrib/trivy/parser/parser.go b/contrib/trivy/parser/parser.go index 8d2b7a7e..a690f0aa 100644 --- a/contrib/trivy/parser/parser.go +++ b/contrib/trivy/parser/parser.go @@ -71,14 +71,14 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR } vulnInfo.CveContents = models.CveContents{ - models.Trivy: models.CveContent{ + models.Trivy: []models.CveContent{{ Cvss3Severity: vuln.Severity, References: references, Title: vuln.Title, Summary: vuln.Description, Published: published, LastModified: lastModified, - }, + }}, } // do only if image type is Vuln if IsTrivySupportedOS(trivyResult.Type) { diff --git a/contrib/trivy/parser/parser_test.go b/contrib/trivy/parser/parser_test.go index 43d117a9..c1bd5c00 100644 --- a/contrib/trivy/parser/parser_test.go +++ b/contrib/trivy/parser/parser_test.go @@ -88,7 +88,7 @@ func TestParse(t *testing.T) { FixedIn: "1.1.1g-r0", }}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Title: "openssl: Segmentation fault in SSL_check_chain causes denial of service", Summary: "Server or client applications that call the SSL_check_chain() function during or after a TLS 1.3 handshake may crash due to a NULL pointer dereference as a result of incorrect handling of the \"signature_algorithms_cert\" TLS extension. The crash occurs if an invalid or unrecognised signature algorithm is received from the peer. This could be exploited by a malicious peer in a Denial of Service attack. OpenSSL version 1.1.1d, 1.1.1e, and 1.1.1f are affected by this issue. This issue did not affect OpenSSL versions prior to 1.1.1d. Fixed in OpenSSL 1.1.1g (Affected 1.1.1d-1.1.1f).", Cvss3Severity: "MEDIUM", @@ -114,7 +114,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.synology.com/security/advisory/Synology_SA_20_05_OpenSSL"}, {Source: "trivy", Link: "https://www.tenable.com/security/tns-2020-03"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, }, @@ -157,7 +157,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Title: "PHP: sets environmental variable based on user supplied Proxy request header", Summary: "PHP through 7.0.8 does not attempt to address RFC 3875 section 4.1.18 namespace conflicts and therefore does not protect applications from the presence of untrusted client data in the HTTP_PROXY environment variable, which might allow remote attackers to redirect an application's outbound HTTP traffic to an arbitrary proxy server via a crafted Proxy header in an HTTP request, as demonstrated by (1) an application that makes a getenv('HTTP_PROXY') call or (2) a CGI configuration of PHP, aka an \"httpoxy\" issue.", Cvss3Severity: "MEDIUM", @@ -192,7 +192,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.gentoo.org/glsa/201611-22"}, {Source: "trivy", Link: "https://www.drupal.org/SA-CORE-2016-003"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -214,7 +214,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "LOW", References: models.References{ {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3721"}, @@ -224,7 +224,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2018-3721"}, {Source: "trivy", Link: "https://security.netapp.com/advisory/ntap-20190919-0004/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -246,7 +246,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3741"}, @@ -255,7 +255,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://groups.google.com/d/msg/rubyonrails-security/tP7W3kLc5u4/uDy2Br7xBgAJ"}, {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2018-3741"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -284,7 +284,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-6952.html"}, @@ -294,7 +294,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://savannah.gnu.org/bugs/index.php?53133"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/201904-17"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -316,13 +316,13 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "LOW", References: models.References{ {Source: "trivy", Link: "https://bugzilla.gnome.org/show_bug.cgi?id=794914"}, {Source: "trivy", Link: "https://lists.debian.org/debian-lts-announce/2018/09/msg00035.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -344,14 +344,14 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://subversion.apache.org/security/CVE-2018-11782-advisory.txt"}, {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11782"}, {Source: "trivy", Link: "https://subversion.apache.org/security/CVE-2018-11782-advisory.txt"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -373,7 +373,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-14404.html"}, @@ -394,7 +394,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/3739-1/"}, {Source: "trivy", Link: "https://usn.ubuntu.com/3739-2/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -416,7 +416,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-14567.html"}, @@ -427,7 +427,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://lists.debian.org/debian-lts-announce/2018/09/msg00035.html"}, {Source: "trivy", Link: "https://usn.ubuntu.com/3739-1/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -449,7 +449,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-14618.html"}, @@ -467,7 +467,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/3765-2/"}, {Source: "trivy", Link: "https://www.debian.org/security/2018/dsa-4286"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -482,7 +482,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487"}, @@ -492,7 +492,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.netapp.com/advisory/ntap-20190919-0004/"}, {Source: "trivy", Link: "https://www.npmjs.com/advisories/782"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -521,7 +521,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://www.securitytracker.com/id/1042012"}, @@ -535,7 +535,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/3805-1/"}, {Source: "trivy", Link: "https://www.debian.org/security/2018/dsa-4331"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -557,7 +557,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://www.securitytracker.com/id/1042013"}, @@ -568,7 +568,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.gentoo.org/glsa/201903-03"}, {Source: "trivy", Link: "https://usn.ubuntu.com/3805-1/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -590,7 +590,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-16842.html"}, @@ -608,7 +608,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.debian.org/security/2018/dsa-4331"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -630,7 +630,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-16890.html"}, @@ -649,7 +649,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -671,7 +671,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-17456.html"}, @@ -696,7 +696,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.exploit-db.com/exploits/45631/"}, {Source: "trivy", Link: "https://www.openwall.com/lists/oss-security/2018/10/06/3"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -718,7 +718,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://www.securityfocus.com/bid/106020"}, @@ -730,7 +730,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.gentoo.org/glsa/201904-13"}, {Source: "trivy", Link: "https://usn.ubuntu.com/3829-1/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -752,7 +752,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00040.html"}, @@ -788,7 +788,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.sqlite.org/releaselog/3_25_3.html"}, {Source: "trivy", Link: "https://www.synology.com/security/advisory/Synology_SA_18_61"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -810,7 +810,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "LOW", References: models.References{ {Source: "trivy", Link: "http://git.savannah.gnu.org/cgit/tar.git/commit/?id=c15c42ccd1e2377945fd0414eca1a49294bff454"}, @@ -824,7 +824,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://twitter.com/thatcks/status/1076166645708668928"}, {Source: "trivy", Link: "https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -846,7 +846,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "LOW", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-20685.html"}, @@ -866,7 +866,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -888,7 +888,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-07/msg00039.html"}, @@ -911,7 +911,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.debian.org/security/2019/dsa-4472"}, {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpuapr2020.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -933,7 +933,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2018-1000156.html"}, @@ -960,7 +960,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/3624-1/"}, {Source: "trivy", Link: "https://usn.ubuntu.com/3624-2/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -982,7 +982,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-0203.html"}, @@ -991,7 +991,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-0203"}, {Source: "trivy", Link: "https://subversion.apache.org/security/CVE-2019-0203-advisory.txt"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1013,7 +1013,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "LOW", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-1348.html"}, @@ -1029,7 +1029,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-42"}, {Source: "trivy", Link: "https://support.apple.com/kb/HT210729"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1051,7 +1051,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-1349.html"}, @@ -1065,7 +1065,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://public-inbox.org/git/xmqqr21cqcn9.fsf@gitster-ct.c.googlers.com/"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1087,7 +1087,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-01/msg00056.html"}, @@ -1099,7 +1099,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-42"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1121,7 +1121,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-01/msg00056.html"}, @@ -1132,7 +1132,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://public-inbox.org/git/xmqqr21cqcn9.fsf@gitster-ct.c.googlers.com/"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1154,7 +1154,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-1352.html"}, @@ -1168,7 +1168,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://public-inbox.org/git/xmqqr21cqcn9.fsf@gitster-ct.c.googlers.com/"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1190,7 +1190,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-01/msg00056.html"}, @@ -1201,7 +1201,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://public-inbox.org/git/xmqqr21cqcn9.fsf@gitster-ct.c.googlers.com/"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1223,7 +1223,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-01/msg00056.html"}, @@ -1234,7 +1234,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://public-inbox.org/git/xmqqr21cqcn9.fsf@gitster-ct.c.googlers.com/"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1256,7 +1256,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-1387.html"}, @@ -1276,7 +1276,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-30"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-42"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1298,7 +1298,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3822.html"}, @@ -1320,7 +1320,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1342,7 +1342,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3823.html"}, @@ -1360,7 +1360,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1382,7 +1382,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3855.html"}, @@ -1416,7 +1416,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3855.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1438,7 +1438,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3856.html"}, @@ -1461,7 +1461,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3856.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1483,7 +1483,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3857.html"}, @@ -1506,7 +1506,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3857.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1528,7 +1528,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3858.html"}, @@ -1552,7 +1552,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3858.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1574,7 +1574,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-03/msg00040.html"}, @@ -1599,7 +1599,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3859.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1621,7 +1621,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-03/msg00040.html"}, @@ -1638,7 +1638,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3860.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1660,7 +1660,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3861.html"}, @@ -1678,7 +1678,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3861.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1700,7 +1700,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3862.html"}, @@ -1725,7 +1725,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpujan2020.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1747,7 +1747,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-3863.html"}, @@ -1770,7 +1770,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.libssh2.org/CVE-2019-3863.html"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1792,7 +1792,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2019-3902"}, @@ -1801,7 +1801,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/4086-1/"}, {Source: "trivy", Link: "https://www.mercurial-scm.org/wiki/WhatsNew#Mercurial_4.9_.282019-02-01.29"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1816,14 +1816,14 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "https://github.com/advisories/GHSA-wv67-q8rr-grjp"}, {Source: "trivy", Link: "https://hackerone.com/reports/454365"}, {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2019-5428"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -1845,7 +1845,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5477"}, @@ -1860,7 +1860,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2019-5477"}, {Source: "trivy", Link: "https://usn.ubuntu.com/4175-1/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -1889,7 +1889,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-09/msg00048.html"}, @@ -1906,7 +1906,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpuapr2020.html"}, {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpujan2020.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1928,7 +1928,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-5482.html"}, @@ -1948,7 +1948,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpuapr2020.html"}, {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpujan2020.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -1970,7 +1970,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-6109.html"}, @@ -1989,7 +1989,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.debian.org/security/2019/dsa-4387"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2011,7 +2011,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-6111.html"}, @@ -2039,7 +2039,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.freebsd.org/security/advisories/FreeBSD-EN-19:10.scp.asc"}, {Source: "trivy", Link: "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2061,7 +2061,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00074.html"}, @@ -2079,7 +2079,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.sqlite.org/releaselog/3_28_0.html"}, {Source: "trivy", Link: "https://www.sqlite.org/src/info/90acdbfce9c08858"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2094,7 +2094,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-11236.html"}, @@ -2114,7 +2114,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/3990-1/"}, {Source: "trivy", Link: "https://usn.ubuntu.com/3990-2/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2136,7 +2136,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-11324.html"}, @@ -2154,7 +2154,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/3990-1/"}, {Source: "trivy", Link: "https://www.openwall.com/lists/oss-security/2019/04/17/3"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2176,7 +2176,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00006.html"}, @@ -2247,7 +2247,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.tenable.com/security/tns-2019-08"}, {Source: "trivy", Link: "https://www.tenable.com/security/tns-2020-02"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2276,7 +2276,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2019-07/msg00040.html"}, @@ -2301,7 +2301,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/4146-1/"}, {Source: "trivy", Link: "https://usn.ubuntu.com/4146-2/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2316,7 +2316,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://www.openwall.com/lists/oss-security/2019/11/17/2"}, @@ -2335,7 +2335,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/4164-1/"}, {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpujan2020.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2364,7 +2364,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://packetstormsecurity.com/files/154124/GNU-patch-Command-Injection-Directory-Traversal.html"}, @@ -2381,7 +2381,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://usn.ubuntu.com/4071-2/"}, {Source: "trivy", Link: "https://www.debian.org/security/2019/dsa-4489"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2403,7 +2403,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-13638.html"}, @@ -2425,7 +2425,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.netapp.com/advisory/ntap-20190828-0001/"}, {Source: "trivy", Link: "https://www.debian.org/security/2019/dsa-4489"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2447,14 +2447,14 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://www.openwall.com/lists/oss-security/2019/08/06/4"}, {Source: "trivy", Link: "https://security.gentoo.org/glsa/202003-13"}, {Source: "trivy", Link: "https://www.openwall.com/lists/musl/2019/08/06/1"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, VulnType: "", @@ -2469,7 +2469,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-15587"}, @@ -2482,7 +2482,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://security.netapp.com/advisory/ntap-20191122-0003/"}, {Source: "trivy", Link: "https://www.debian.org/security/2019/dsa-4554"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2512,7 +2512,7 @@ func TestParse(t *testing.T) { }, }, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://linux.oracle.com/cve/CVE-2019-15903.html"}, @@ -2576,7 +2576,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://www.debian.org/security/2019/dsa-4571"}, {Source: "trivy", Link: "https://www.oracle.com/security-alerts/cpuapr2020.html"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{}, }, @@ -2590,7 +2590,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-02/msg00016.html"}, @@ -2605,7 +2605,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/HZXMWILCICQLA2BYSP6I2CRMUG53YBLX/"}, {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2019-16782"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2626,7 +2626,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-04/msg00017.html"}, @@ -2637,7 +2637,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WORRFHPQVAFKKXXWLSSW6XKUYLWM6CSH/"}, {Source: "trivy", Link: "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZBJA3SGNJKCAYPSHOHWY3KBCWNM5NYK2/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2658,7 +2658,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "LOW", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-05/msg00019.html"}, @@ -2672,7 +2672,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2020-5267"}, {Source: "trivy", Link: "https://www.openwall.com/lists/oss-security/2020/03/19/1"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2693,7 +2693,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "https://github.com/advisories/GHSA-7553-jr98-vx47"}, @@ -2705,7 +2705,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2020-7595"}, {Source: "trivy", Link: "https://usn.ubuntu.com/4274-1/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ models.LibraryFixedIn{ @@ -2726,7 +2726,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "CRITICAL", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-03/msg00041.html"}, @@ -2739,7 +2739,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://nvd.nist.gov/vuln/detail/CVE-2020-8130"}, {Source: "trivy", Link: "https://usn.ubuntu.com/4295-1/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ models.LibraryFixedIn{ @@ -2760,7 +2760,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ { @@ -2768,7 +2768,7 @@ func TestParse(t *testing.T) { Link: "https://groups.google.com/forum/#!topic/ruby-security-ann/T4ZIsfRf2eA", }, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ models.LibraryFixedIn{ @@ -2789,7 +2789,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ { @@ -2797,7 +2797,7 @@ func TestParse(t *testing.T) { Link: "https://groups.google.com/forum/#!topic/rubyonrails-security/PjU3946mreQ", }, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ models.LibraryFixedIn{ @@ -2818,7 +2818,7 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "MEDIUM", References: models.References{ {Source: "trivy", Link: "http://lists.opensuse.org/opensuse-security-announce/2020-05/msg00004.html"}, @@ -2829,7 +2829,7 @@ func TestParse(t *testing.T) { {Source: "trivy", Link: "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/NK2PBXWMFRUD7U7Q7LHV4KYLYID77RI4/"}, {Source: "trivy", Link: "https://www.ruby-lang.org/en/news/2020/03/19/json-dos-cve-2020-10663/"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ models.LibraryFixedIn{ @@ -2850,12 +2850,12 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ models.Reference{Source: "trivy", Link: "https://groups.google.com/forum/#!topic/rubyonrails-security/f6ioe4sdpbY"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2876,12 +2876,12 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ models.Reference{Source: "trivy", Link: "https://groups.google.com/forum/#!topic/rubyonrails-security/bv6fW4S0Y1c"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2902,12 +2902,12 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ models.Reference{Source: "trivy", Link: "https://groups.google.com/forum/#!topic/rubyonrails-security/NOjKiGeXUgw"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2928,12 +2928,12 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ models.Reference{Source: "trivy", Link: "https://groups.google.com/forum/#!topic/rubyonrails-security/x9DixQDG9a0"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2954,12 +2954,12 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "HIGH", References: models.References{ models.Reference{Source: "trivy", Link: "https://hackerone.com/reports/712065"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2980,10 +2980,10 @@ func TestParse(t *testing.T) { }, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": models.CveContent{ + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References(nil), - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -2999,12 +2999,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/sfackler/rust-openssl/releases/tag/v0.9.0"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -3020,12 +3020,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/servo/rust-smallvec/issues/96"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -3041,12 +3041,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/sfackler/rust-openssl/pull/942"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -3062,12 +3062,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/rust-lang-deprecated/tempdir/pull/46"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -3083,12 +3083,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/rust-ammonia/ammonia/blob/master/CHANGELOG.md#210"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -3103,12 +3103,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/servo/rust-smallvec/issues/148"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { @@ -3124,12 +3124,12 @@ func TestParse(t *testing.T) { Confidences: models.Confidences{{Score: 100, DetectionMethod: "TrivyMatch"}}, AffectedPackages: models.PackageFixStatuses{}, CveContents: models.CveContents{ - "trivy": { + "trivy": []models.CveContent{{ Cvss3Severity: "UNKNOWN", References: models.References{ {Source: "trivy", Link: "https://github.com/servo/rust-smallvec/issues/149"}, }, - }, + }}, }, LibraryFixedIns: models.LibraryFixedIns{ { diff --git a/detector/cve_client.go b/detector/cve_client.go index f29b110b..f8610870 100644 --- a/detector/cve_client.go +++ b/detector/cve_client.go @@ -53,11 +53,7 @@ func (api goCveDictClient) fetchCveDetails(cveIDs []string) (cveDetails []cvemod if err != nil { return nil, xerrors.Errorf("Failed to fetch CVE. err: %w", err) } - if len(cveDetail.CveID) == 0 { - cveDetails = append(cveDetails, cvemodels.CveDetail{CveID: cveID}) - } else { - cveDetails = append(cveDetails, *cveDetail) - } + cveDetails = append(cveDetails, *cveDetail) } return } @@ -103,13 +99,7 @@ func (api goCveDictClient) fetchCveDetailsViaHTTP(cveIDs []string) (cveDetails [ for range cveIDs { select { case res := <-resChan: - if len(res.CveDetail.CveID) == 0 { - cveDetails = append(cveDetails, cvemodels.CveDetail{ - CveID: res.Key, - }) - } else { - cveDetails = append(cveDetails, res.CveDetail) - } + cveDetails = append(cveDetails, res.CveDetail) case err := <-errChan: errs = append(errs, err) case <-timeout: diff --git a/detector/detector.go b/detector/detector.go index 9cdd2f46..4c1b8f2f 100644 --- a/detector/detector.go +++ b/detector/detector.go @@ -284,8 +284,8 @@ func FillCvesWithNvdJvn(r *models.ScanResult, cnf config.GoCveDictConf, logOpts } for _, d := range ds { - nvd, exploits, mitigations := models.ConvertNvdJSONToModel(d.CveID, d.NvdJSON) - jvn := models.ConvertJvnToModel(d.CveID, d.Jvn) + nvds, exploits, mitigations := models.ConvertNvdToModel(d.CveID, d.Nvd) + jvns := models.ConvertJvnToModel(d.CveID, d.Jvn) alerts := fillCertAlerts(&d) for cveID, vinfo := range r.ScannedCves { @@ -293,9 +293,9 @@ func FillCvesWithNvdJvn(r *models.ScanResult, cnf config.GoCveDictConf, logOpts if vinfo.CveContents == nil { vinfo.CveContents = models.CveContents{} } - for _, con := range []*models.CveContent{nvd, jvn} { - if con != nil && !con.Empty() { - vinfo.CveContents[con.Type] = *con + for _, con := range append(nvds, jvns...) { + if !con.Empty() { + vinfo.CveContents[con.Type] = append(vinfo.CveContents[con.Type], con) } } vinfo.AlertDict = alerts @@ -310,8 +310,8 @@ func FillCvesWithNvdJvn(r *models.ScanResult, cnf config.GoCveDictConf, logOpts } func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) { - if cvedetail.NvdJSON != nil { - for _, cert := range cvedetail.NvdJSON.Certs { + for _, nvd := range cvedetail.Nvd { + for _, cert := range nvd.Certs { dict.En = append(dict.En, models.Alert{ URL: cert.Link, Title: cert.Title, @@ -319,8 +319,9 @@ func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) { }) } } - if cvedetail.Jvn != nil { - for _, cert := range cvedetail.Jvn.Certs { + + for _, jvn := range cvedetail.Jvn { + for _, cert := range jvn.Certs { dict.Ja = append(dict.Ja, models.Alert{ URL: cert.Link, Title: cert.Title, @@ -328,6 +329,7 @@ func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) { }) } } + return dict } @@ -422,8 +424,8 @@ func DetectCpeURIsCves(r *models.ScanResult, cpeURIs []string, cnf config.GoCveD for _, detail := range details { confidence := models.CpeVersionMatch - if detail.HasJvn() && !detail.HasNvd() { - // In the case of CpeVendorProduct-match, only the JVN is set(Nvd is not set). + if detail.CveIDSource == cvemodels.JvnType { + // In the case of CpeVendorProduct-match confidence = models.CpeVendorProductMatch } @@ -450,11 +452,13 @@ func DetectCpeURIsCves(r *models.ScanResult, cpeURIs []string, cnf config.GoCveD func FillCweDict(r *models.ScanResult) { uniqCweIDMap := map[string]bool{} for _, vinfo := range r.ScannedCves { - for _, cont := range vinfo.CveContents { - for _, id := range cont.CweIDs { - if strings.HasPrefix(id, "CWE-") { - id = strings.TrimPrefix(id, "CWE-") - uniqCweIDMap[id] = true + for _, conts := range vinfo.CveContents { + for _, cont := range conts { + for _, id := range cont.CweIDs { + if strings.HasPrefix(id, "CWE-") { + id = strings.TrimPrefix(id, "CWE-") + uniqCweIDMap[id] = true + } } } } diff --git a/detector/github.go b/detector/github.go index 23b83d0c..dd05e980 100644 --- a/detector/github.go +++ b/detector/github.go @@ -125,7 +125,7 @@ func DetectGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string, if val, ok := r.ScannedCves[cveID]; ok { val.GitHubSecurityAlerts = val.GitHubSecurityAlerts.Add(m) - val.CveContents[models.GitHub] = cveContent + val.CveContents[models.GitHub] = append(val.CveContents[models.GitHub], cveContent) r.ScannedCves[cveID] = val } else { v := models.VulnInfo{ diff --git a/detector/util.go b/detector/util.go index 0e16b875..7c56e078 100644 --- a/detector/util.go +++ b/detector/util.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "regexp" "sort" "time" @@ -196,30 +197,34 @@ func isCveInfoUpdated(cveID string, previous, current models.ScanResult) bool { models.NewCveContentType(current.Family), } - prevLastModified := map[models.CveContentType]time.Time{} + prevLastModified := map[models.CveContentType][]time.Time{} preVinfo, ok := previous.ScannedCves[cveID] if !ok { return true } for _, cType := range cTypes { - if content, ok := preVinfo.CveContents[cType]; ok { - prevLastModified[cType] = content.LastModified + if conts, ok := preVinfo.CveContents[cType]; ok { + for _, cont := range conts { + prevLastModified[cType] = append(prevLastModified[cType], cont.LastModified) + } } } - curLastModified := map[models.CveContentType]time.Time{} + curLastModified := map[models.CveContentType][]time.Time{} curVinfo, ok := current.ScannedCves[cveID] if !ok { return true } for _, cType := range cTypes { - if content, ok := curVinfo.CveContents[cType]; ok { - curLastModified[cType] = content.LastModified + if conts, ok := curVinfo.CveContents[cType]; ok { + for _, cont := range conts { + curLastModified[cType] = append(curLastModified[cType], cont.LastModified) + } } } for _, t := range cTypes { - if !curLastModified[t].Equal(prevLastModified[t]) { + if !reflect.DeepEqual(curLastModified[t], prevLastModified[t]) { logging.Log.Debugf("%s LastModified not equal: \n%s\n%s", cveID, curLastModified[t], prevLastModified[t]) return true diff --git a/go.mod b/go.mod index 4ca1d7bd..fb45271d 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936 github.com/knqyf263/gost v0.2.0 - github.com/kotakanbe/go-cve-dictionary v0.6.3-0.20210813002409-8e5fc26823ac + github.com/kotakanbe/go-cve-dictionary v0.6.3-0.20210813065642-21ddcc77c887 github.com/kotakanbe/go-pingscanner v0.1.0 github.com/kotakanbe/goval-dictionary v0.3.6-0.20210625044258-9be85404d7dd github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96 diff --git a/go.sum b/go.sum index d2304314..720a937f 100644 --- a/go.sum +++ b/go.sum @@ -924,8 +924,8 @@ github.com/knqyf263/nested v0.0.1/go.mod h1:zwhsIhMkBg90DTOJQvxPkKIypEHPYkgWHs4g github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kotakanbe/go-cve-dictionary v0.6.3-0.20210813002409-8e5fc26823ac h1:389f1+HuSGoVYFV7o2b+ANDJWA6k7Zy1okJ2um9Kbzs= -github.com/kotakanbe/go-cve-dictionary v0.6.3-0.20210813002409-8e5fc26823ac/go.mod h1:Ht9ESpkhbQtdVRoo/lEPZ6B8j6lVUsfRkxpfl6FlwD8= +github.com/kotakanbe/go-cve-dictionary v0.6.3-0.20210813065642-21ddcc77c887 h1:ILs7Md0W/rcpuDg0dNKqUUiyCt4pjZvoQayM5/ro9kc= +github.com/kotakanbe/go-cve-dictionary v0.6.3-0.20210813065642-21ddcc77c887/go.mod h1:Ht9ESpkhbQtdVRoo/lEPZ6B8j6lVUsfRkxpfl6FlwD8= github.com/kotakanbe/go-pingscanner v0.1.0 h1:VG4/9l0i8WeToXclj7bIGoAZAu7a07Z3qmQiIfU0gT0= github.com/kotakanbe/go-pingscanner v0.1.0/go.mod h1:/761QZzuZFcfN8h/1QuawUA+pKukp3qcNj5mxJCOiAk= github.com/kotakanbe/goval-dictionary v0.3.6-0.20210625044258-9be85404d7dd h1:hnkOzwlknmNU64P5UaQzAZcyNnuSsCz/PIt/P/ZPKYg= diff --git a/gost/debian.go b/gost/debian.go index 40996a95..b007c4ed 100644 --- a/gost/debian.go +++ b/gost/debian.go @@ -141,7 +141,7 @@ func (deb Debian) detectCVEsWithFixState(r *models.ScanResult, fixStatus string) if v.CveContents == nil { v.CveContents = models.NewCveContents(cve) } else { - v.CveContents[models.DebianSecurityTracker] = cve + v.CveContents[models.DebianSecurityTracker] = append(v.CveContents[models.DebianSecurityTracker], cve) v.Confidences = models.Confidences{models.DebianSecurityTrackerMatch} } } else { diff --git a/gost/microsoft.go b/gost/microsoft.go index 6ca217bb..96b3cf3b 100644 --- a/gost/microsoft.go +++ b/gost/microsoft.go @@ -32,7 +32,7 @@ func (ms Microsoft) DetectCVEs(r *models.ScanResult, _ bool) (nCVEs int, err err if v.CveContents == nil { v.CveContents = models.CveContents{} } - v.CveContents[models.Microsoft] = *cveCont + v.CveContents[models.Microsoft] = append(v.CveContents[models.Microsoft], *cveCont) v.Mitigations = append(v.Mitigations, mitigations...) r.ScannedCves[cveID] = v } diff --git a/gost/redhat.go b/gost/redhat.go index 39b3e1b2..38afa4ba 100644 --- a/gost/redhat.go +++ b/gost/redhat.go @@ -102,7 +102,7 @@ func (red RedHat) setFixedCveToScanResult(cve *gostmodels.RedhatCVE, r *models.S if v.CveContents == nil { v.CveContents = models.NewCveContents(*cveCont) } else { - v.CveContents[models.RedHatAPI] = *cveCont + v.CveContents[models.RedHatAPI] = append(v.CveContents[models.RedHatAPI], *cveCont) } } else { v = models.VulnInfo{ @@ -122,7 +122,7 @@ func (red RedHat) setUnfixedCveToScanResult(cve *gostmodels.RedhatCVE, r *models if v.CveContents == nil { v.CveContents = models.NewCveContents(*cveCont) } else { - v.CveContents[models.RedHatAPI] = *cveCont + v.CveContents[models.RedHatAPI] = append(v.CveContents[models.RedHatAPI], *cveCont) } } else { v = models.VulnInfo{ diff --git a/gost/ubuntu.go b/gost/ubuntu.go index d36dc7da..e25c0d99 100644 --- a/gost/ubuntu.go +++ b/gost/ubuntu.go @@ -115,7 +115,7 @@ func (ubu Ubuntu) DetectCVEs(r *models.ScanResult, _ bool) (nCVEs int, err error if v.CveContents == nil { v.CveContents = models.NewCveContents(cve) } else { - v.CveContents[models.UbuntuAPI] = cve + v.CveContents[models.UbuntuAPI] = append(v.CveContents[models.UbuntuAPI], cve) } } else { v = models.VulnInfo{ diff --git a/models/cvecontents.go b/models/cvecontents.go index f69cb4d4..998977bc 100644 --- a/models/cvecontents.go +++ b/models/cvecontents.go @@ -8,13 +8,13 @@ import ( ) // CveContents has CveContent -type CveContents map[CveContentType]CveContent +type CveContents map[CveContentType][]CveContent // NewCveContents create CveContents func NewCveContents(conts ...CveContent) CveContents { m := CveContents{} for _, cont := range conts { - m[cont.Type] = cont + m[cont.Type] = append(m[cont.Type], cont) } return m } @@ -49,11 +49,13 @@ func (v CveContents) PrimarySrcURLs(lang, myFamily, cveID string) (values []CveC return } - if cont, found := v[Nvd]; found { - for _, r := range cont.References { - for _, t := range r.Tags { - if t == "Vendor Advisory" { - values = append(values, CveContentStr{Nvd, r.Link}) + if conts, found := v[Nvd]; found { + for _, cont := range conts { + for _, r := range cont.References { + for _, t := range r.Tags { + if t == "Vendor Advisory" { + values = append(values, CveContentStr{Nvd, r.Link}) + } } } } @@ -61,17 +63,23 @@ func (v CveContents) PrimarySrcURLs(lang, myFamily, cveID string) (values []CveC order := CveContentTypes{Nvd, NewCveContentType(myFamily), GitHub} for _, ctype := range order { - if cont, found := v[ctype]; found { - if cont.SourceLink == "" { - continue + if conts, found := v[ctype]; found { + for _, cont := range conts { + if cont.SourceLink == "" { + continue + } + values = append(values, CveContentStr{ctype, cont.SourceLink}) } - values = append(values, CveContentStr{ctype, cont.SourceLink}) } } if lang == "ja" { - if cont, found := v[Jvn]; found && 0 < len(cont.SourceLink) { - values = append(values, CveContentStr{Jvn, cont.SourceLink}) + if conts, found := v[Jvn]; found { + for _, cont := range conts { + if 0 < len(cont.SourceLink) { + values = append(values, CveContentStr{Jvn, cont.SourceLink}) + } + } } } @@ -86,14 +94,17 @@ func (v CveContents) PrimarySrcURLs(lang, myFamily, cveID string) (values []CveC // PatchURLs returns link of patch func (v CveContents) PatchURLs() (urls []string) { - cont, found := v[Nvd] + conts, found := v[Nvd] if !found { return } - for _, r := range cont.References { - for _, t := range r.Tags { - if t == "Patch" { - urls = append(urls, r.Link) + + for _, cont := range conts { + for _, r := range cont.References { + for _, t := range r.Tags { + if t == "Patch" { + urls = append(urls, r.Link) + } } } } @@ -130,11 +141,15 @@ func (v CveContents) Cpes(myFamily string) (values []CveContentCpes) { order = append(order, AllCveContetTypes.Except(order...)...) for _, ctype := range order { - if cont, found := v[ctype]; found && 0 < len(cont.Cpes) { - values = append(values, CveContentCpes{ - Type: ctype, - Value: cont.Cpes, - }) + if conts, found := v[ctype]; found { + for _, cont := range conts { + if 0 < len(cont.Cpes) { + values = append(values, CveContentCpes{ + Type: ctype, + Value: cont.Cpes, + }) + } + } } } return @@ -152,11 +167,15 @@ func (v CveContents) References(myFamily string) (values []CveContentRefs) { order = append(order, AllCveContetTypes.Except(order...)...) for _, ctype := range order { - if cont, found := v[ctype]; found && 0 < len(cont.References) { - values = append(values, CveContentRefs{ - Type: ctype, - Value: cont.References, - }) + if conts, found := v[ctype]; found { + for _, cont := range conts { + if 0 < len(cont.References) { + values = append(values, CveContentRefs{ + Type: ctype, + Value: cont.References, + }) + } + } } } @@ -168,17 +187,21 @@ func (v CveContents) CweIDs(myFamily string) (values []CveContentStr) { order := CveContentTypes{NewCveContentType(myFamily)} order = append(order, AllCveContetTypes.Except(order...)...) for _, ctype := range order { - if cont, found := v[ctype]; found && 0 < len(cont.CweIDs) { - for _, cweID := range cont.CweIDs { - for _, val := range values { - if val.Value == cweID { - continue + if conts, found := v[ctype]; found { + for _, cont := range conts { + if 0 < len(cont.CweIDs) { + for _, cweID := range cont.CweIDs { + for _, val := range values { + if val.Value == cweID { + continue + } + } + values = append(values, CveContentStr{ + Type: ctype, + Value: cweID, + }) } } - values = append(values, CveContentStr{ - Type: ctype, - Value: cweID, - }) } } } diff --git a/models/cvecontents_test.go b/models/cvecontents_test.go index 25b5f579..7013c11a 100644 --- a/models/cvecontents_test.go +++ b/models/cvecontents_test.go @@ -11,12 +11,12 @@ func TestExcept(t *testing.T) { out CveContents }{{ in: CveContents{ - RedHat: {Type: RedHat}, - Ubuntu: {Type: Ubuntu}, - Debian: {Type: Debian}, + RedHat: []CveContent{{Type: RedHat}}, + Ubuntu: []CveContent{{Type: Ubuntu}}, + Debian: []CveContent{{Type: Debian}}, }, out: CveContents{ - RedHat: {Type: RedHat}, + RedHat: []CveContent{{Type: RedHat}}, }, }, } @@ -44,15 +44,15 @@ func TestSourceLinks(t *testing.T) { lang: "ja", cveID: "CVE-2017-6074", cont: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, SourceLink: "https://jvn.jp/vu/JVNVU93610402/", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, SourceLink: "https://access.redhat.com/security/cve/CVE-2017-6074", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, References: []Reference{ { @@ -69,7 +69,7 @@ func TestSourceLinks(t *testing.T) { }, }, SourceLink: "https://nvd.nist.gov/vuln/detail/CVE-2017-6074", - }, + }}, }, }, out: []CveContentStr{ @@ -97,14 +97,14 @@ func TestSourceLinks(t *testing.T) { lang: "en", cveID: "CVE-2017-6074", cont: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, SourceLink: "https://jvn.jp/vu/JVNVU93610402/", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, SourceLink: "https://access.redhat.com/security/cve/CVE-2017-6074", - }, + }}, }, }, out: []CveContentStr{ diff --git a/models/library.go b/models/library.go index a2e2e5b1..7340e3e0 100644 --- a/models/library.go +++ b/models/library.go @@ -99,8 +99,8 @@ func (s LibraryScanner) getVulnDetail(tvuln types.DetectedVulnerability) (vinfo return vinfo, nil } -func getCveContents(cveID string, vul trivyDBTypes.Vulnerability) (contents map[CveContentType]CveContent) { - contents = map[CveContentType]CveContent{} +func getCveContents(cveID string, vul trivyDBTypes.Vulnerability) (contents map[CveContentType][]CveContent) { + contents = map[CveContentType][]CveContent{} refs := []Reference{} for _, refURL := range vul.References { refs = append(refs, Reference{Source: "trivy", Link: refURL}) @@ -114,7 +114,7 @@ func getCveContents(cveID string, vul trivyDBTypes.Vulnerability) (contents map[ Cvss3Severity: string(vul.Severity), References: refs, } - contents[Trivy] = content + contents[Trivy] = append(contents[Trivy], content) return contents } diff --git a/models/scanresults.go b/models/scanresults.go index 998cbd5e..9cdcc031 100644 --- a/models/scanresults.go +++ b/models/scanresults.go @@ -416,18 +416,21 @@ func (r *ScanResult) SortForJSONOutput() { return v.Mitigations[i].URL < v.Mitigations[j].URL }) for kk, vv := range v.CveContents { - sort.Slice(vv.References, func(i, j int) bool { - return vv.References[i].Link < vv.References[j].Link - }) - sort.Slice(vv.CweIDs, func(i, j int) bool { - return vv.CweIDs[i] < vv.CweIDs[j] - }) - for kkk, vvv := range vv.References { - // sort v.CveContents[].References[].Tags - sort.Slice(vvv.Tags, func(i, j int) bool { - return vvv.Tags[i] < vvv.Tags[j] + for kkk, vvv := range vv { + sort.Slice(vvv.References, func(i, j int) bool { + return vvv.References[i].Link < vvv.References[j].Link }) - vv.References[kkk] = vvv + sort.Slice(vvv.CweIDs, func(i, j int) bool { + return vvv.CweIDs[i] < vvv.CweIDs[j] + }) + for kkkk, vvvv := range vvv.References { + // sort v.CveContents[].References[].Tags + sort.Slice(vvvv.Tags, func(i, j int) bool { + return vvvv.Tags[i] < vvvv.Tags[j] + }) + vvv.References[kkkk] = vvvv + } + vv[kkk] = vvv } v.CveContents[kk] = vv } diff --git a/models/scanresults_test.go b/models/scanresults_test.go index 2fa83b57..513fe0cc 100644 --- a/models/scanresults_test.go +++ b/models/scanresults_test.go @@ -198,17 +198,17 @@ func TestScanResult_Sort(t *testing.T) { {Name: "b"}, }, CveContents: CveContents{ - "nvd": CveContent{ + "nvd": []CveContent{{ References: References{ Reference{Link: "a"}, Reference{Link: "b"}, - }, + }}, }, - "jvn": CveContent{ + "jvn": []CveContent{{ References: References{ Reference{Link: "a"}, Reference{Link: "b"}, - }, + }}, }, }, AlertDict: AlertDict{ @@ -257,17 +257,17 @@ func TestScanResult_Sort(t *testing.T) { {Name: "b"}, }, CveContents: CveContents{ - "nvd": CveContent{ + "nvd": []CveContent{{ References: References{ Reference{Link: "a"}, Reference{Link: "b"}, - }, + }}, }, - "jvn": CveContent{ + "jvn": []CveContent{{ References: References{ Reference{Link: "a"}, Reference{Link: "b"}, - }, + }}, }, }, AlertDict: AlertDict{ @@ -319,17 +319,17 @@ func TestScanResult_Sort(t *testing.T) { {Name: "a"}, }, CveContents: CveContents{ - "nvd": CveContent{ + "nvd": []CveContent{{ References: References{ Reference{Link: "b"}, Reference{Link: "a"}, - }, + }}, }, - "jvn": CveContent{ + "jvn": []CveContent{{ References: References{ Reference{Link: "b"}, Reference{Link: "a"}, - }, + }}, }, }, AlertDict: AlertDict{ @@ -378,17 +378,17 @@ func TestScanResult_Sort(t *testing.T) { {Name: "b"}, }, CveContents: CveContents{ - "nvd": CveContent{ + "nvd": []CveContent{{ References: References{ Reference{Link: "a"}, Reference{Link: "b"}, - }, + }}, }, - "jvn": CveContent{ + "jvn": []CveContent{{ References: References{ Reference{Link: "a"}, Reference{Link: "b"}, - }, + }}, }, }, AlertDict: AlertDict{ diff --git a/models/utils.go b/models/utils.go index 2d897330..b3089a33 100644 --- a/models/utils.go +++ b/models/utils.go @@ -9,112 +9,116 @@ import ( ) // ConvertJvnToModel convert JVN to CveContent -func ConvertJvnToModel(cveID string, jvn *cvedict.Jvn) *CveContent { - if jvn == nil { - return nil - } - // var cpes = []Cpe{} - // for _, c := range jvn.Cpes { - // cpes = append(cpes, Cpe{ - // FormattedString: c.FormattedString, - // URI: c.URI, - // }) - // } +func ConvertJvnToModel(cveID string, jvns []cvedict.Jvn) []CveContent { + cves := []CveContent{} + for _, jvn := range jvns { + // cpes := []Cpe{} + // for _, c := range jvn.Cpes { + // cpes = append(cpes, Cpe{ + // FormattedString: c.FormattedString, + // URI: c.URI, + // }) + // } - refs := []Reference{} - for _, r := range jvn.References { - refs = append(refs, Reference{ - Link: r.Link, - Source: r.Source, - }) - } + refs := []Reference{} + for _, r := range jvn.References { + refs = append(refs, Reference{ + Link: r.Link, + Source: r.Source, + }) + } - return &CveContent{ - Type: Jvn, - CveID: cveID, - Title: jvn.Title, - Summary: jvn.Summary, - Cvss2Score: jvn.Cvss2.BaseScore, - Cvss2Vector: jvn.Cvss2.VectorString, - Cvss2Severity: jvn.Cvss2.Severity, - Cvss3Score: jvn.Cvss3.BaseScore, - Cvss3Vector: jvn.Cvss3.VectorString, - Cvss3Severity: jvn.Cvss3.BaseSeverity, - SourceLink: jvn.JvnLink, - // Cpes: cpes, - References: refs, - Published: jvn.PublishedDate, - LastModified: jvn.LastModifiedDate, + cve := CveContent{ + Type: Jvn, + CveID: cveID, + Title: jvn.Title, + Summary: jvn.Summary, + Cvss2Score: jvn.Cvss2.BaseScore, + Cvss2Vector: jvn.Cvss2.VectorString, + Cvss2Severity: jvn.Cvss2.Severity, + Cvss3Score: jvn.Cvss3.BaseScore, + Cvss3Vector: jvn.Cvss3.VectorString, + Cvss3Severity: jvn.Cvss3.BaseSeverity, + SourceLink: jvn.JvnLink, + // Cpes: cpes, + References: refs, + Published: jvn.PublishedDate, + LastModified: jvn.LastModifiedDate, + } + cves = append(cves, cve) } + return cves } -// ConvertNvdJSONToModel convert NVD to CveContent -func ConvertNvdJSONToModel(cveID string, nvd *cvedict.NvdJSON) (*CveContent, []Exploit, []Mitigation) { - if nvd == nil { - return nil, nil, nil - } - // var cpes = []Cpe{} - // for _, c := range nvd.Cpes { - // cpes = append(cpes, Cpe{ - // FormattedString: c.FormattedString, - // URI: c.URI, - // }) - // } - +// ConvertNvdToModel convert NVD to CveContent +func ConvertNvdToModel(cveID string, nvds []cvedict.Nvd) ([]CveContent, []Exploit, []Mitigation) { + cves := []CveContent{} refs := []Reference{} exploits := []Exploit{} mitigations := []Mitigation{} - for _, r := range nvd.References { - var tags []string - if 0 < len(r.Tags) { - tags = strings.Split(r.Tags, ",") - } - refs = append(refs, Reference{ - Link: r.Link, - Source: r.Source, - Tags: tags, - }) - if strings.Contains(r.Tags, "Exploit") { - exploits = append(exploits, Exploit{ - //TODO Add const to here - // https://github.com/vulsio/go-exploitdb/blob/master/models/exploit.go#L13-L18 - ExploitType: "nvd", - URL: r.Link, + for _, nvd := range nvds { + // cpes := []Cpe{} + // for _, c := range nvd.Cpes { + // cpes = append(cpes, Cpe{ + // FormattedString: c.FormattedString, + // URI: c.URI, + // }) + // } + + for _, r := range nvd.References { + var tags []string + if 0 < len(r.Tags) { + tags = strings.Split(r.Tags, ",") + } + refs = append(refs, Reference{ + Link: r.Link, + Source: r.Source, + Tags: tags, }) + if strings.Contains(r.Tags, "Exploit") { + exploits = append(exploits, Exploit{ + //TODO Add const to here + // https://github.com/vulsio/go-exploitdb/blob/master/models/exploit.go#L13-L18 + ExploitType: "nvd", + URL: r.Link, + }) + } + if strings.Contains(r.Tags, "Mitigation") { + mitigations = append(mitigations, Mitigation{ + CveContentType: Nvd, + URL: r.Link, + }) + } } - if strings.Contains(r.Tags, "Mitigation") { - mitigations = append(mitigations, Mitigation{ - CveContentType: Nvd, - URL: r.Link, - }) + + cweIDs := []string{} + for _, cid := range nvd.Cwes { + cweIDs = append(cweIDs, cid.CweID) } - } - cweIDs := []string{} - for _, cid := range nvd.Cwes { - cweIDs = append(cweIDs, cid.CweID) - } + desc := []string{} + for _, d := range nvd.Descriptions { + desc = append(desc, d.Value) + } - desc := []string{} - for _, d := range nvd.Descriptions { - desc = append(desc, d.Value) + cve := CveContent{ + Type: Nvd, + CveID: cveID, + Summary: strings.Join(desc, "\n"), + Cvss2Score: nvd.Cvss2.BaseScore, + Cvss2Vector: nvd.Cvss2.VectorString, + Cvss2Severity: nvd.Cvss2.Severity, + Cvss3Score: nvd.Cvss3.BaseScore, + Cvss3Vector: nvd.Cvss3.VectorString, + Cvss3Severity: nvd.Cvss3.BaseSeverity, + SourceLink: "https://nvd.nist.gov/vuln/detail/" + cveID, + // Cpes: cpes, + CweIDs: cweIDs, + References: refs, + Published: nvd.PublishedDate, + LastModified: nvd.LastModifiedDate, + } + cves = append(cves, cve) } - - return &CveContent{ - Type: Nvd, - CveID: cveID, - Summary: strings.Join(desc, "\n"), - Cvss2Score: nvd.Cvss2.BaseScore, - Cvss2Vector: nvd.Cvss2.VectorString, - Cvss2Severity: nvd.Cvss2.Severity, - Cvss3Score: nvd.Cvss3.BaseScore, - Cvss3Vector: nvd.Cvss3.VectorString, - Cvss3Severity: nvd.Cvss3.BaseSeverity, - SourceLink: "https://nvd.nist.gov/vuln/detail/" + cveID, - // Cpes: cpes, - CweIDs: cweIDs, - References: refs, - Published: nvd.PublishedDate, - LastModified: nvd.LastModifiedDate, - }, exploits, mitigations + return cves, exploits, mitigations } diff --git a/models/vulninfos.go b/models/vulninfos.go index 09be6944..41952ffc 100644 --- a/models/vulninfos.go +++ b/models/vulninfos.go @@ -347,30 +347,46 @@ func (v VulnInfo) CveIDDiffFormat() string { // Titles returns title (TUI) func (v VulnInfo) Titles(lang, myFamily string) (values []CveContentStr) { if lang == "ja" { - if cont, found := v.CveContents[Jvn]; found && cont.Title != "" { - values = append(values, CveContentStr{Jvn, cont.Title}) + if conts, found := v.CveContents[Jvn]; found { + for _, cont := range conts { + if cont.Title != "" { + values = append(values, CveContentStr{Jvn, cont.Title}) + } + } } } // RedHat API has one line title. - if cont, found := v.CveContents[RedHatAPI]; found && cont.Title != "" { - values = append(values, CveContentStr{RedHatAPI, cont.Title}) + if conts, found := v.CveContents[RedHatAPI]; found { + for _, cont := range conts { + if cont.Title != "" { + values = append(values, CveContentStr{RedHatAPI, cont.Title}) + } + } } // GitHub security alerts has a title. - if cont, found := v.CveContents[GitHub]; found && cont.Title != "" { - values = append(values, CveContentStr{GitHub, cont.Title}) + if conts, found := v.CveContents[GitHub]; found { + for _, cont := range conts { + if cont.Title != "" { + values = append(values, CveContentStr{GitHub, cont.Title}) + } + } } order := CveContentTypes{Trivy, Nvd, NewCveContentType(myFamily)} order = append(order, AllCveContetTypes.Except(append(order, Jvn)...)...) for _, ctype := range order { - if cont, found := v.CveContents[ctype]; found && cont.Summary != "" { - summary := strings.Replace(cont.Summary, "\n", " ", -1) - values = append(values, CveContentStr{ - Type: ctype, - Value: summary, - }) + if conts, found := v.CveContents[ctype]; found { + for _, cont := range conts { + if cont.Summary != "" { + summary := strings.Replace(cont.Summary, "\n", " ", -1) + values = append(values, CveContentStr{ + Type: ctype, + Value: summary, + }) + } + } } } @@ -393,23 +409,31 @@ func (v VulnInfo) Titles(lang, myFamily string) (values []CveContentStr) { // Summaries returns summaries func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) { if lang == "ja" { - if cont, found := v.CveContents[Jvn]; found && cont.Summary != "" { - summary := cont.Title - summary += "\n" + strings.Replace( - strings.Replace(cont.Summary, "\n", " ", -1), "\r", " ", -1) - values = append(values, CveContentStr{Jvn, summary}) + if conts, found := v.CveContents[Jvn]; found { + for _, cont := range conts { + if cont.Summary != "" { + summary := cont.Title + summary += "\n" + strings.Replace( + strings.Replace(cont.Summary, "\n", " ", -1), "\r", " ", -1) + values = append(values, CveContentStr{Jvn, summary}) + } + } } } order := CveContentTypes{Trivy, NewCveContentType(myFamily), Nvd, GitHub} order = append(order, AllCveContetTypes.Except(append(order, Jvn)...)...) for _, ctype := range order { - if cont, found := v.CveContents[ctype]; found && cont.Summary != "" { - summary := strings.Replace(cont.Summary, "\n", " ", -1) - values = append(values, CveContentStr{ - Type: ctype, - Value: summary, - }) + if conts, found := v.CveContents[ctype]; found { + for _, cont := range conts { + if cont.Summary != "" { + summary := strings.Replace(cont.Summary, "\n", " ", -1) + values = append(values, CveContentStr{ + Type: ctype, + Value: summary, + }) + } + } } } @@ -420,11 +444,15 @@ func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) { }) } - if v, ok := v.CveContents[WpScan]; ok { - values = append(values, CveContentStr{ - Type: WpScan, - Value: v.Title, - }) + if conts, ok := v.CveContents[WpScan]; ok { + for _, cont := range conts { + if cont.Title != "" { + values = append(values, CveContentStr{ + Type: WpScan, + Value: cont.Title, + }) + } + } } if len(values) == 0 { @@ -441,20 +469,22 @@ func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) { func (v VulnInfo) Cvss2Scores() (values []CveContentCvss) { order := []CveContentType{RedHatAPI, RedHat, Nvd, Jvn} for _, ctype := range order { - if cont, found := v.CveContents[ctype]; found { - if cont.Cvss2Score == 0 && cont.Cvss2Severity == "" { - continue + if conts, found := v.CveContents[ctype]; found { + for _, cont := range conts { + if cont.Cvss2Score == 0 && cont.Cvss2Severity == "" { + continue + } + // https://nvd.nist.gov/vuln-metrics/cvss + values = append(values, CveContentCvss{ + Type: ctype, + Value: Cvss{ + Type: CVSS2, + Score: cont.Cvss2Score, + Vector: cont.Cvss2Vector, + Severity: strings.ToUpper(cont.Cvss2Severity), + }, + }) } - // https://nvd.nist.gov/vuln-metrics/cvss - values = append(values, CveContentCvss{ - Type: ctype, - Value: Cvss{ - Type: CVSS2, - Score: cont.Cvss2Score, - Vector: cont.Cvss2Vector, - Severity: strings.ToUpper(cont.Cvss2Severity), - }, - }) } } return @@ -464,34 +494,40 @@ func (v VulnInfo) Cvss2Scores() (values []CveContentCvss) { func (v VulnInfo) Cvss3Scores() (values []CveContentCvss) { order := []CveContentType{RedHatAPI, RedHat, Nvd, Jvn} for _, ctype := range order { - if cont, found := v.CveContents[ctype]; found { - if cont.Cvss3Score == 0 && cont.Cvss3Severity == "" { - continue + if conts, found := v.CveContents[ctype]; found { + for _, cont := range conts { + if cont.Cvss3Score == 0 && cont.Cvss3Severity == "" { + continue + } + // https://nvd.nist.gov/vuln-metrics/cvss + values = append(values, CveContentCvss{ + Type: ctype, + Value: Cvss{ + Type: CVSS3, + Score: cont.Cvss3Score, + Vector: cont.Cvss3Vector, + Severity: strings.ToUpper(cont.Cvss3Severity), + }, + }) } - // https://nvd.nist.gov/vuln-metrics/cvss - values = append(values, CveContentCvss{ - Type: ctype, - Value: Cvss{ - Type: CVSS3, - Score: cont.Cvss3Score, - Vector: cont.Cvss3Vector, - Severity: strings.ToUpper(cont.Cvss3Severity), - }, - }) } } for _, ctype := range []CveContentType{Debian, DebianSecurityTracker, Ubuntu, Amazon, Trivy, GitHub, WpScan} { - if cont, found := v.CveContents[ctype]; found && cont.Cvss3Severity != "" { - values = append(values, CveContentCvss{ - Type: ctype, - Value: Cvss{ - Type: CVSS3, - Score: severityToCvssScoreRoughly(cont.Cvss3Severity), - CalculatedBySeverity: true, - Severity: strings.ToUpper(cont.Cvss3Severity), - }, - }) + if conts, found := v.CveContents[ctype]; found { + for _, cont := range conts { + if cont.Cvss3Severity != "" { + values = append(values, CveContentCvss{ + Type: ctype, + Value: Cvss{ + Type: CVSS3, + Score: severityToCvssScoreRoughly(cont.Cvss3Severity), + CalculatedBySeverity: true, + Severity: strings.ToUpper(cont.Cvss3Severity), + }, + }) + } + } } } @@ -553,24 +589,28 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss { // AttackVector returns attack vector string func (v VulnInfo) AttackVector() string { - for _, cnt := range v.CveContents { - if strings.HasPrefix(cnt.Cvss2Vector, "AV:N") || - strings.Contains(cnt.Cvss3Vector, "AV:N") { - return "AV:N" - } else if strings.HasPrefix(cnt.Cvss2Vector, "AV:A") || - strings.Contains(cnt.Cvss3Vector, "AV:A") { - return "AV:A" - } else if strings.HasPrefix(cnt.Cvss2Vector, "AV:L") || - strings.Contains(cnt.Cvss3Vector, "AV:L") { - return "AV:L" - } else if strings.Contains(cnt.Cvss3Vector, "AV:P") { - // no AV:P in CVSS v2 - return "AV:P" + for _, conts := range v.CveContents { + for _, cont := range conts { + if strings.HasPrefix(cont.Cvss2Vector, "AV:N") || + strings.Contains(cont.Cvss3Vector, "AV:N") { + return "AV:N" + } else if strings.HasPrefix(cont.Cvss2Vector, "AV:A") || + strings.Contains(cont.Cvss3Vector, "AV:A") { + return "AV:A" + } else if strings.HasPrefix(cont.Cvss2Vector, "AV:L") || + strings.Contains(cont.Cvss3Vector, "AV:L") { + return "AV:L" + } else if strings.Contains(cont.Cvss3Vector, "AV:P") { + // no AV:P in CVSS v2 + return "AV:P" + } } } - if cont, found := v.CveContents[DebianSecurityTracker]; found { - if attackRange, found := cont.Optional["attack range"]; found { - return attackRange + if conts, found := v.CveContents[DebianSecurityTracker]; found { + for _, cont := range conts { + if attackRange, found := cont.Optional["attack range"]; found { + return attackRange + } } } return "" diff --git a/models/vulninfos_test.go b/models/vulninfos_test.go index 8dde057e..913d1547 100644 --- a/models/vulninfos_test.go +++ b/models/vulninfos_test.go @@ -21,19 +21,19 @@ func TestTitles(t *testing.T) { lang: "ja", cont: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Title: "Title1", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Summary: "Summary RedHat", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Summary: "Summary NVD", // Severity is NOT included in NVD - }, + }}, }, }, }, @@ -58,19 +58,19 @@ func TestTitles(t *testing.T) { lang: "en", cont: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Title: "Title1", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Summary: "Summary RedHat", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Summary: "Summary NVD", // Severity is NOT included in NVD - }, + }}, }, }, }, @@ -122,20 +122,20 @@ func TestSummaries(t *testing.T) { lang: "ja", cont: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Title: "Title JVN", Summary: "Summary JVN", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Summary: "Summary RedHat", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Summary: "Summary NVD", // Severity is NOT included in NVD - }, + }}, }, }, }, @@ -160,20 +160,20 @@ func TestSummaries(t *testing.T) { lang: "en", cont: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Title: "Title JVN", Summary: "Summary JVN", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Summary: "Summary RedHat", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Summary: "Summary NVD", // Severity is NOT included in NVD - }, + }}, }, }, }, @@ -220,32 +220,32 @@ func TestCountGroupBySeverity(t *testing.T) { "CVE-2017-0002": { CveID: "CVE-2017-0002", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss3Score: 6.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, "CVE-2017-0003": { CveID: "CVE-2017-0003", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss3Score: 2.0, - }, + }}, }, }, "CVE-2017-0004": { CveID: "CVE-2017-0004", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss3Score: 5.0, - }, + }}, }, }, "CVE-2017-0005": { @@ -254,10 +254,10 @@ func TestCountGroupBySeverity(t *testing.T) { "CVE-2017-0006": { CveID: "CVE-2017-0005", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss3Score: 10.0, - }, + }}, }, }, }, @@ -274,32 +274,32 @@ func TestCountGroupBySeverity(t *testing.T) { "CVE-2017-0002": { CveID: "CVE-2017-0002", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 1.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, "CVE-2017-0003": { CveID: "CVE-2017-0003", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 2.0, - }, + }}, }, }, "CVE-2017-0004": { CveID: "CVE-2017-0004", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 5.0, - }, + }}, }, }, "CVE-2017-0005": { @@ -308,10 +308,10 @@ func TestCountGroupBySeverity(t *testing.T) { "CVE-2017-0006": { CveID: "CVE-2017-0005", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 10.0, - }, + }}, }, }, }, @@ -346,27 +346,27 @@ func TestToSortedSlice(t *testing.T) { "CVE-2017-0002": { CveID: "CVE-2017-0002", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 6.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, "CVE-2017-0001": { CveID: "CVE-2017-0001", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 7.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 8.0, - }, + }}, }, }, }, @@ -374,27 +374,27 @@ func TestToSortedSlice(t *testing.T) { { CveID: "CVE-2017-0001", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 7.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 8.0, - }, + }}, }, }, { CveID: "CVE-2017-0002", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 6.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, }, @@ -405,23 +405,23 @@ func TestToSortedSlice(t *testing.T) { "CVE-2017-0002": { CveID: "CVE-2017-0002", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 6.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, "CVE-2017-0001": { CveID: "CVE-2017-0001", CveContents: CveContents{ - RedHat: { + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, }, @@ -429,23 +429,23 @@ func TestToSortedSlice(t *testing.T) { { CveID: "CVE-2017-0001", CveContents: CveContents{ - RedHat: { + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, { CveID: "CVE-2017-0002", CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 6.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 7.0, - }, + }}, }, }, }, @@ -456,19 +456,19 @@ func TestToSortedSlice(t *testing.T) { "CVE-2017-0002": { CveID: "CVE-2017-0002", CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "High", - }, + }}, }, }, "CVE-2017-0001": { CveID: "CVE-2017-0001", CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "Low", - }, + }}, }, }, }, @@ -476,19 +476,19 @@ func TestToSortedSlice(t *testing.T) { { CveID: "CVE-2017-0002", CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "High", - }, + }}, }, }, { CveID: "CVE-2017-0001", CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "Low", - }, + }}, }, }, }, @@ -510,31 +510,31 @@ func TestCvss2Scores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Cvss2Severity: "HIGH", Cvss2Score: 8.2, Cvss2Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss2Severity: "HIGH", Cvss2Score: 8.0, Cvss2Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 8.1, Cvss2Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", Cvss2Severity: "HIGH", - }, + }}, //v3 - RedHatAPI: { + RedHatAPI: []CveContent{{ Type: RedHatAPI, Cvss3Score: 8.1, Cvss3Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", Cvss3Severity: "HIGH", - }, + }}, }, }, out: []CveContentCvss{ @@ -590,24 +590,24 @@ func TestMaxCvss2Scores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Cvss2Severity: "HIGH", Cvss2Score: 8.2, Cvss2Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss2Severity: "HIGH", Cvss2Score: 8.0, Cvss2Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 8.1, Cvss2Vector: "AV:N/AC:L/Au:N/C:N/I:N/A:P", // Severity is NOT included in NVD - }, + }}, }, }, out: CveContentCvss{ @@ -650,18 +650,18 @@ func TestCvss3Scores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - RedHat: { + RedHat: []CveContent{{ Type: RedHat, Cvss3Severity: "HIGH", Cvss3Score: 8.0, Cvss3Vector: "AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 8.1, Cvss2Vector: "AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", Cvss2Severity: "HIGH", - }, + }}, }, }, out: []CveContentCvss{ @@ -680,10 +680,10 @@ func TestCvss3Scores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "HIGH", - }, + }}, }, }, out: []CveContentCvss{ @@ -720,12 +720,12 @@ func TestMaxCvss3Scores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - RedHat: { + RedHat: []CveContent{{ Type: RedHat, Cvss3Severity: "HIGH", Cvss3Score: 8.0, Cvss3Vector: "AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", - }, + }}, }, }, out: CveContentCvss{ @@ -768,14 +768,14 @@ func TestMaxCvssScores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Nvd: { + Nvd: []CveContent{{ Type: Nvd, Cvss3Score: 7.0, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss2Score: 8.0, - }, + }}, }, }, out: CveContentCvss{ @@ -789,10 +789,10 @@ func TestMaxCvssScores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - RedHat: { + RedHat: []CveContent{{ Type: RedHat, Cvss3Score: 8.0, - }, + }}, }, }, out: CveContentCvss{ @@ -807,10 +807,10 @@ func TestMaxCvssScores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "HIGH", - }, + }}, }, }, out: CveContentCvss{ @@ -827,15 +827,15 @@ func TestMaxCvssScores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "MEDIUM", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 7.0, Cvss2Severity: "HIGH", - }, + }}, }, }, out: CveContentCvss{ @@ -871,15 +871,15 @@ func TestMaxCvssScores(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Ubuntu: { + Ubuntu: []CveContent{{ Type: Ubuntu, Cvss3Severity: "MEDIUM", - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 4.0, Cvss2Severity: "MEDIUM", - }, + }}, }, DistroAdvisories: []DistroAdvisory{ { @@ -925,21 +925,21 @@ func TestFormatMaxCvssScore(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Cvss2Severity: "HIGH", Cvss2Score: 8.3, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss3Severity: "HIGH", Cvss3Score: 8.0, - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 8.1, // Severity is NOT included in NVD - }, + }}, }, }, out: "8.0 HIGH (redhat)", @@ -947,22 +947,22 @@ func TestFormatMaxCvssScore(t *testing.T) { { in: VulnInfo{ CveContents: CveContents{ - Jvn: { + Jvn: []CveContent{{ Type: Jvn, Cvss2Severity: "HIGH", Cvss2Score: 8.3, - }, - RedHat: { + }}, + RedHat: []CveContent{{ Type: RedHat, Cvss2Severity: "HIGH", Cvss2Score: 8.0, Cvss3Severity: "HIGH", Cvss3Score: 9.9, - }, - Nvd: { + }}, + Nvd: []CveContent{{ Type: Nvd, Cvss2Score: 8.1, - }, + }}, }, }, out: "9.9 HIGH (redhat)", diff --git a/oval/debian.go b/oval/debian.go index d461336b..5bc86d59 100644 --- a/oval/debian.go +++ b/oval/debian.go @@ -48,7 +48,7 @@ func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) { vinfo.Confidences.AppendIfMissing(models.OvalMatch) } } - cveContents[ctype] = ovalContent + cveContents[ctype] = append(cveContents[ctype], ovalContent) vinfo.CveContents = cveContents } @@ -181,9 +181,11 @@ func (o Debian) FillWithOval(r *models.ScanResult) (nCVEs int, err error) { } for _, vuln := range r.ScannedCves { - if cont, ok := vuln.CveContents[models.Debian]; ok { - cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID - vuln.CveContents[models.Debian] = cont + if conts, ok := vuln.CveContents[models.Debian]; ok { + for _, cont := range conts { + cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID + vuln.CveContents[models.Debian] = append(vuln.CveContents[models.Debian], cont) + } } } return len(relatedDefs.entries), nil @@ -498,9 +500,11 @@ func (o Ubuntu) fillWithOval(r *models.ScanResult, kernelNamesInOval []string) ( } for _, vuln := range r.ScannedCves { - if cont, ok := vuln.CveContents[models.Ubuntu]; ok { - cont.SourceLink = "http://people.ubuntu.com/~ubuntu-security/cve/" + cont.CveID - vuln.CveContents[models.Ubuntu] = cont + if conts, ok := vuln.CveContents[models.Ubuntu]; ok { + for _, cont := range conts { + cont.SourceLink = "http://people.ubuntu.com/~ubuntu-security/cve/" + cont.CveID + vuln.CveContents[models.Ubuntu] = append(vuln.CveContents[models.Ubuntu], cont) + } } } return len(relatedDefs.entries), nil diff --git a/oval/redhat.go b/oval/redhat.go index 06781df1..27358670 100644 --- a/oval/redhat.go +++ b/oval/redhat.go @@ -50,14 +50,18 @@ func (o RedHatBase) FillWithOval(r *models.ScanResult) (nCVEs int, err error) { for _, vuln := range r.ScannedCves { switch models.NewCveContentType(o.family) { case models.RedHat: - if cont, ok := vuln.CveContents[models.RedHat]; ok { - cont.SourceLink = "https://access.redhat.com/security/cve/" + cont.CveID - vuln.CveContents[models.RedHat] = cont + if conts, ok := vuln.CveContents[models.RedHat]; ok { + for _, cont := range conts { + cont.SourceLink = "https://access.redhat.com/security/cve/" + cont.CveID + vuln.CveContents[models.RedHat] = append(vuln.CveContents[models.RedHat], cont) + } } case models.Oracle: - if cont, ok := vuln.CveContents[models.Oracle]; ok { - cont.SourceLink = fmt.Sprintf("https://linux.oracle.com/cve/%s.html", cont.CveID) - vuln.CveContents[models.Oracle] = cont + if conts, ok := vuln.CveContents[models.Oracle]; ok { + for _, cont := range conts { + cont.SourceLink = fmt.Sprintf("https://linux.oracle.com/cve/%s.html", cont.CveID) + vuln.CveContents[models.Oracle] = append(vuln.CveContents[models.Oracle], cont) + } } } } @@ -113,10 +117,12 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int) } else { cveContents := vinfo.CveContents if v, ok := vinfo.CveContents[ctype]; ok { - if v.LastModified.After(ovalContent.LastModified) { - logging.Log.Debugf("%s ignored. DefID: %s ", cve.CveID, defPacks.def.DefinitionID) - } else { - logging.Log.Debugf("%s OVAL will be overwritten. DefID: %s", cve.CveID, defPacks.def.DefinitionID) + for _, vv := range v { + if vv.LastModified.After(ovalContent.LastModified) { + logging.Log.Debugf("%s ignored. DefID: %s ", cve.CveID, defPacks.def.DefinitionID) + } else { + logging.Log.Debugf("%s OVAL will be overwritten. DefID: %s", cve.CveID, defPacks.def.DefinitionID) + } } } else { logging.Log.Debugf("%s also detected by OVAL. DefID: %s", cve.CveID, defPacks.def.DefinitionID) @@ -124,7 +130,7 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int) } vinfo.Confidences.AppendIfMissing(models.OvalMatch) - cveContents[ctype] = ovalContent + cveContents[ctype] = append(cveContents[ctype], ovalContent) vinfo.CveContents = cveContents } diff --git a/oval/suse.go b/oval/suse.go index bf598061..fc0ec3ea 100644 --- a/oval/suse.go +++ b/oval/suse.go @@ -53,9 +53,11 @@ func (o SUSE) FillWithOval(r *models.ScanResult) (nCVEs int, err error) { } for _, vuln := range r.ScannedCves { - if cont, ok := vuln.CveContents[models.SUSE]; ok { - cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID - vuln.CveContents[models.SUSE] = cont + if conts, ok := vuln.CveContents[models.SUSE]; ok { + for _, cont := range conts { + cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID + vuln.CveContents[models.SUSE] = append(vuln.CveContents[models.SUSE], cont) + } } } return len(relatedDefs.entries), nil @@ -82,7 +84,7 @@ func (o SUSE) update(r *models.ScanResult, defPacks defPacks) { cveContents = models.CveContents{} } vinfo.Confidences.AppendIfMissing(models.OvalMatch) - cveContents[ctype] = ovalContent + cveContents[ctype] = append(cveContents[ctype], ovalContent) vinfo.CveContents = cveContents } diff --git a/reporter/slack.go b/reporter/slack.go index 98a3c7f9..a328622a 100644 --- a/reporter/slack.go +++ b/reporter/slack.go @@ -269,15 +269,16 @@ func (w SlackWriter) attachmentText(vinfo models.VulnInfo, cweDict map[string]mo vinfo.CveID) } - if cont, ok := vinfo.CveContents[cvss.Type]; ok { - v := fmt.Sprintf("<%s|%s> %s (<%s|%s>)", - calcURL, - fmt.Sprintf("%3.1f/%s", cvss.Value.Score, cvss.Value.Vector), - cvss.Value.Severity, - cont.SourceLink, - cvss.Type) - vectors = append(vectors, v) - + if conts, ok := vinfo.CveContents[cvss.Type]; ok { + for _, cont := range conts { + v := fmt.Sprintf("<%s|%s> %s (<%s|%s>)", + calcURL, + fmt.Sprintf("%3.1f/%s", cvss.Value.Score, cvss.Value.Vector), + cvss.Value.Severity, + cont.SourceLink, + cvss.Type) + vectors = append(vectors, v) + } } else { if 0 < len(vinfo.DistroAdvisories) { links := []string{} diff --git a/reporter/syslog.go b/reporter/syslog.go index 6bc30ba2..bb012bed 100644 --- a/reporter/syslog.go +++ b/reporter/syslog.go @@ -70,16 +70,20 @@ func (w SyslogWriter) encodeSyslog(result models.ScanResult) (messages []string) kvPairs = append(kvPairs, fmt.Sprintf(`cvss_vector_%s_v3="%s"`, cvss.Type, cvss.Value.Vector)) } - if content, ok := vinfo.CveContents[models.Nvd]; ok { - cwes := strings.Join(content.CweIDs, ",") - kvPairs = append(kvPairs, fmt.Sprintf(`cwe_ids="%s"`, cwes)) - if w.Cnf.Verbose { - kvPairs = append(kvPairs, fmt.Sprintf(`source_link="%s"`, content.SourceLink)) - kvPairs = append(kvPairs, fmt.Sprintf(`summary="%s"`, content.Summary)) + if conts, ok := vinfo.CveContents[models.Nvd]; ok { + for _, cont := range conts { + cwes := strings.Join(cont.CweIDs, ",") + kvPairs = append(kvPairs, fmt.Sprintf(`cwe_ids="%s"`, cwes)) + if w.Cnf.Verbose { + kvPairs = append(kvPairs, fmt.Sprintf(`source_link="%s"`, cont.SourceLink)) + kvPairs = append(kvPairs, fmt.Sprintf(`summary="%s"`, cont.Summary)) + } } } - if content, ok := vinfo.CveContents[models.RedHat]; ok { - kvPairs = append(kvPairs, fmt.Sprintf(`title="%s"`, content.Title)) + if conts, ok := vinfo.CveContents[models.RedHat]; ok { + for _, cont := range conts { + kvPairs = append(kvPairs, fmt.Sprintf(`title="%s"`, cont.Title)) + } } // message: key1="value1" key2="value2"... diff --git a/reporter/syslog_test.go b/reporter/syslog_test.go index f2990752..a027de98 100644 --- a/reporter/syslog_test.go +++ b/reporter/syslog_test.go @@ -33,7 +33,7 @@ func TestSyslogWriterEncodeSyslog(t *testing.T) { models.PackageFixStatus{Name: "pkg4"}, }, CveContents: models.CveContents{ - models.Nvd: models.CveContent{ + models.Nvd: []models.CveContent{{ Cvss2Score: 5.0, Cvss2Vector: "AV:L/AC:L/Au:N/C:N/I:N/A:C", Cvss2Severity: "MEDIUM", @@ -41,7 +41,7 @@ func TestSyslogWriterEncodeSyslog(t *testing.T) { Cvss3Score: 9.8, Cvss3Vector: "AV:L/AC:L/Au:N/C:N/I:N/A:C", Cvss3Severity: "HIGH", - }, + }}, }, }, }, @@ -65,13 +65,13 @@ func TestSyslogWriterEncodeSyslog(t *testing.T) { models.PackageFixStatus{Name: "pkg5"}, }, CveContents: models.CveContents{ - models.RedHat: models.CveContent{ + models.RedHat: []models.CveContent{{ Cvss3Score: 5.0, Cvss3Severity: "Medium", Cvss3Vector: "AV:L/AC:L/Au:N/C:N/I:N/A:C", CweIDs: []string{"CWE-284"}, Title: "RHSA-2017:0001: pkg5 security update (Important)", - }, + }}, }, }, }, diff --git a/reporter/util.go b/reporter/util.go index f006daf9..b60e56f4 100644 --- a/reporter/util.go +++ b/reporter/util.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "regexp" "sort" "strings" @@ -673,32 +674,36 @@ func isCveInfoUpdated(cveID string, previous, current models.ScanResult) bool { models.NewCveContentType(current.Family), } - prevLastModified := map[models.CveContentType]time.Time{} + prevLastModifieds := map[models.CveContentType][]time.Time{} preVinfo, ok := previous.ScannedCves[cveID] if !ok { return true } for _, cType := range cTypes { - if content, ok := preVinfo.CveContents[cType]; ok { - prevLastModified[cType] = content.LastModified + if conts, ok := preVinfo.CveContents[cType]; ok { + for _, cont := range conts { + prevLastModifieds[cType] = append(prevLastModifieds[cType], cont.LastModified) + } } } - curLastModified := map[models.CveContentType]time.Time{} + curLastModifieds := map[models.CveContentType][]time.Time{} curVinfo, ok := current.ScannedCves[cveID] if !ok { return true } for _, cType := range cTypes { - if content, ok := curVinfo.CveContents[cType]; ok { - curLastModified[cType] = content.LastModified + if conts, ok := curVinfo.CveContents[cType]; ok { + for _, cont := range conts { + curLastModifieds[cType] = append(curLastModifieds[cType], cont.LastModified) + } } } for _, t := range cTypes { - if !curLastModified[t].Equal(prevLastModified[t]) { + if !reflect.DeepEqual(curLastModifieds[t], prevLastModifieds[t]) { logging.Log.Debugf("%s LastModified not equal: \n%s\n%s", - cveID, curLastModified[t], prevLastModified[t]) + cveID, curLastModifieds[t], prevLastModifieds[t]) return true } } diff --git a/tui/tui.go b/tui/tui.go index db8d4d80..97699a10 100644 --- a/tui/tui.go +++ b/tui/tui.go @@ -908,9 +908,11 @@ func detailLines() (string, error) { refsMap[ref.Link] = ref } } - if cont, found := vinfo.CveContents[models.Trivy]; found { - for _, ref := range cont.References { - refsMap[ref.Link] = ref + if conts, found := vinfo.CveContents[models.Trivy]; found { + for _, cont := range conts { + for _, ref := range cont.References { + refsMap[ref.Link] = ref + } } } refs := []models.Reference{}