From 8e620fe8b59f32897fe4310d6de9b433a5fe30bb Mon Sep 17 00:00:00 2001 From: becitsthere Date: Tue, 12 Dec 2023 21:56:27 -0800 Subject: [PATCH] NVSHAS-8522: cross-reference severity from other feeds --- common/types.go | 3 ++- dbgen.go | 3 ++- memdb.go | 2 +- updater/fetchers/ubuntu/ubuntu.go | 4 ++-- updater/nvd/nvd.go | 27 +++++++++++++++++++++++++-- updater/updater.go | 11 +++++++++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/common/types.go b/common/types.go index bace7f2..04718a7 100644 --- a/common/types.go +++ b/common/types.go @@ -14,6 +14,7 @@ const RHELCpeMapFile = "rhel-cpe.map" type NVDMetadata struct { Description string `json:"description,omitempty"` + Severity Priority CVSSv2 CVSS CVSSv3 CVSS VulnVersions []NVDvulnerableVersion @@ -74,7 +75,7 @@ type VulFull struct { Namespace string `json:"NS"` Description string `json:"D"` Link string `json:"L"` - Severity string `json:"S"` + Severity Priority `json:"S"` CVSSv2 CVSS `json:"C2"` CVSSv3 CVSS `json:"C3"` FixedBy string `json:"FB"` diff --git a/dbgen.go b/dbgen.go index 4bb90eb..158f504 100644 --- a/dbgen.go +++ b/dbgen.go @@ -14,6 +14,7 @@ import ( utils "github.com/vul-dbgen/share" "github.com/vul-dbgen/updater" _ "github.com/vul-dbgen/updater/fetchers/alpine" + _ "github.com/vul-dbgen/updater/fetchers/amazon" _ "github.com/vul-dbgen/updater/fetchers/apps" _ "github.com/vul-dbgen/updater/fetchers/debian" @@ -37,7 +38,7 @@ func main() { version := flag.String("v", "0.90", "cve database version") dbPath := flag.String("d", "", "cve database path") - debug := flag.String("debug", "", "debug filters") + debug := flag.String("debug", "", "debug filters. -debug v=CVE-2023-1000") flag.Usage = usage flag.Parse() diff --git a/memdb.go b/memdb.go index 4749d92..aa89f68 100644 --- a/memdb.go +++ b/memdb.go @@ -55,7 +55,7 @@ func modVulToVulFull(v *common.Vulnerability) *common.VulFull { vv1.Namespace = v.Namespace vv1.Description = v.Description vv1.Link = v.Link - vv1.Severity = string(v.Severity) + vv1.Severity = v.Severity vv1.FeedRating = v.FeedRating vv1.CPEs = v.CPEs vv1.CVEs = make([]string, len(v.CVEs)) diff --git a/updater/fetchers/ubuntu/ubuntu.go b/updater/fetchers/ubuntu/ubuntu.go index f1b54ca..b6c77c8 100644 --- a/updater/fetchers/ubuntu/ubuntu.go +++ b/updater/fetchers/ubuntu/ubuntu.go @@ -304,7 +304,7 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability common.Vulnerability, priority = priority[:strings.Index(priority, " ")] } - vulnerability.Severity = ubuntuPriorityToSeverity(priority) + vulnerability.Severity = toSeverity(priority) vulnerability.FeedRating = priority continue } @@ -409,7 +409,7 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability common.Vulnerability, return } -func ubuntuPriorityToSeverity(priority string) common.Priority { +func toSeverity(priority string) common.Priority { switch priority { case "untriaged": return common.Unknown diff --git a/updater/nvd/nvd.go b/updater/nvd/nvd.go index 7170ce9..659d44d 100644 --- a/updater/nvd/nvd.go +++ b/updater/nvd/nvd.go @@ -75,7 +75,7 @@ type NvdCve struct { Source string `json:"source"` Type string `json:"type"` CvssData CvssData `json:"cvssData"` - Severity string `json:"severity"` + Severity string `json:"baseSeverity"` ExploitabilityScore float64 `json:"exploitabilityScore"` ImpactScore float64 `json:"impactScore"` ObtainAllPrivilege bool `json:"obtainAllPrivilege"` @@ -124,6 +124,7 @@ type CvssData struct { IntegrityImpact string `json:"integrityImpact"` AvailabilityImpact string `json:"availabilityImpact"` BaseScore float64 `json:"baseScore"` + BaseSeverity string `json:"baseSeverity"` } var NVD NVDMetadataFetcher @@ -247,17 +248,22 @@ func (fetcher *NVDMetadataFetcher) Load() error { meta.Description = cve.Cve.Description[0].Value } if cve.Cve.ID != "" { - //Prefer CVSS31 over CVSS30 if it exists. + // Prefer CVSS31 over CVSS30 if it exists. if len(cve.Cve.Metrics.BaseMetricV31) > 0 && cve.Cve.Metrics.BaseMetricV31[0].CvssData.BaseScore != 0 { meta.CVSSv3.Vectors = cve.Cve.Metrics.BaseMetricV31[0].CvssData.VectorString meta.CVSSv3.Score = cve.Cve.Metrics.BaseMetricV31[0].CvssData.BaseScore + meta.Severity = fetcher.toSeverity(cve.Cve.Metrics.BaseMetricV31[0].CvssData.BaseSeverity) } else if len(cve.Cve.Metrics.BaseMetricV3) > 0 && cve.Cve.Metrics.BaseMetricV3[0].CvssData.BaseScore != 0 { meta.CVSSv3.Vectors = cve.Cve.Metrics.BaseMetricV3[0].CvssData.VectorString meta.CVSSv3.Score = cve.Cve.Metrics.BaseMetricV3[0].CvssData.BaseScore + meta.Severity = fetcher.toSeverity(cve.Cve.Metrics.BaseMetricV3[0].CvssData.BaseSeverity) } if len(cve.Cve.Metrics.BaseMetricV2) > 0 && cve.Cve.Metrics.BaseMetricV2[0].CvssData.BaseScore != 0 { meta.CVSSv2.Vectors = cve.Cve.Metrics.BaseMetricV2[0].CvssData.VectorString meta.CVSSv2.Score = cve.Cve.Metrics.BaseMetricV2[0].CvssData.BaseScore + if meta.Severity == "" { + meta.Severity = fetcher.toSeverity(cve.Cve.Metrics.BaseMetricV2[0].Severity) + } } if cve.Cve.PublishedDate != "" { // Use new format, try old format if parse fails. @@ -314,6 +320,22 @@ func (fetcher *NVDMetadataFetcher) Load() error { return nil } +func (fetcher *NVDMetadataFetcher) toSeverity(s string) common.Priority { + switch s { + case "LOW": + return common.Low + case "MEDIUM": + return common.Medium + case "HIGH": + return common.High + case "CRITICAL": + return common.Critical + } + + // return empty instead of Unknown + return "" +} + func (fetcher *NVDMetadataFetcher) GetMetadata(cve string) (*common.NVDMetadata, bool) { if nvd, ok := fetcher.metadata[cve]; ok { var description string @@ -324,6 +346,7 @@ func (fetcher *NVDMetadataFetcher) GetMetadata(cve string) (*common.NVDMetadata, } return &common.NVDMetadata{ Description: description, + Severity: nvd.Severity, CVSSv3: nvd.CVSSv3, CVSSv2: nvd.CVSSv2, PublishedDate: nvd.PublishedDate, diff --git a/updater/updater.go b/updater/updater.go index e7a5cde..bdc8ad7 100644 --- a/updater/updater.go +++ b/updater/updater.go @@ -210,6 +210,9 @@ func enrichAppMeta(meta *common.NVDMetadata, v *common.AppModuleVul) { meta.CVSSv2.Score = v.Score meta.CVSSv2.Vectors = v.Vectors } + if meta.Severity == "" || meta.Severity == common.Unknown { + meta.Severity = v.Severity + } if meta.PublishedDate.IsZero() { meta.PublishedDate = v.IssuedDate } @@ -228,6 +231,9 @@ func enrichDistroMeta(meta *common.NVDMetadata, v *common.Vulnerability, cve *co if meta.CVSSv2.Score == 0 { meta.CVSSv2 = cve.CVSSv2 } + if meta.Severity == "" || meta.Severity == common.Unknown { + meta.Severity = v.Severity + } if meta.PublishedDate.IsZero() { meta.PublishedDate = v.IssuedDate } @@ -302,6 +308,7 @@ func assignMetadata(vuls []*common.Vulnerability, apps []*common.AppModuleVul) ( meta = &common.NVDMetadata{ CVSSv3: cve.CVSSv3, CVSSv2: cve.CVSSv2, + Severity: v.Severity, PublishedDate: v.IssuedDate, LastModifiedDate: v.LastModDate, } @@ -333,6 +340,7 @@ func assignMetadata(vuls []*common.Vulnerability, apps []*common.AppModuleVul) ( meta = &common.NVDMetadata{ CVSSv3: common.CVSS{Score: app.ScoreV3, Vectors: app.VectorsV3}, CVSSv2: common.CVSS{Score: app.Score, Vectors: app.Vectors}, + Severity: app.Severity, PublishedDate: app.IssuedDate, LastModifiedDate: app.LastModDate, } @@ -372,6 +380,9 @@ func assignMetadata(vuls []*common.Vulnerability, apps []*common.AppModuleVul) ( if cvss2.Score == 0 { cvss2 = meta.CVSSv2 } + if v.Severity == "" || v.Severity == common.Unknown { + v.Severity = meta.Severity + } } }