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
This commit is contained in:
MaineK00n
2021-08-13 18:00:55 +09:00
committed by GitHub
parent d65421cf46
commit 96c3592db1
28 changed files with 740 additions and 647 deletions

View File

@@ -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,
})
}
}
}

View File

@@ -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{

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{

View File

@@ -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
}

View File

@@ -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 ""

View File

@@ -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)",