diff --git a/ext/vulnsrc/rhel/rhel.go b/ext/vulnsrc/rhel/rhel.go
index 481beabf..b35f5639 100644
--- a/ext/vulnsrc/rhel/rhel.go
+++ b/ext/vulnsrc/rhel/rhel.go
@@ -65,11 +65,20 @@ type definition struct {
Description string `xml:"metadata>description"`
References []reference `xml:"metadata>reference"`
Criteria criteria `xml:"criteria"`
+ Severity string `xml:"metadata>advisory>severity"`
+ Cves []cve `xml:"metadata>advisory>cve"`
}
type reference struct {
Source string `xml:"source,attr"`
URI string `xml:"ref_url,attr"`
+ ID string `xml:"ref_id,attr"`
+}
+
+type cve struct {
+ Impact string `xml:"impact,attr"`
+ Href string `xml:"href,attr"`
+ ID string `xml:",chardata"`
}
type criteria struct {
@@ -196,18 +205,37 @@ func parseRHSA(ovalReader io.Reader) (vulnerabilities []database.VulnerabilityWi
for _, definition := range ov.Definitions {
pkgs := toFeatures(definition.Criteria)
if len(pkgs) > 0 {
+
+ // Init vulnerability
vulnerability := database.VulnerabilityWithAffected{
Vulnerability: database.Vulnerability{
- Name: name(definition),
- Link: link(definition),
- Severity: severity(definition),
+ Name: rhsaName(definition),
+ Link: rhsaLink(definition),
+ Severity: severity(definition.Severity),
Description: description(definition),
},
}
for _, p := range pkgs {
vulnerability.Affected = append(vulnerability.Affected, p)
}
- vulnerabilities = append(vulnerabilities, vulnerability)
+
+ // Only RHSA is present
+ if len(definition.References) == 1 {
+ vulnerabilities = append(vulnerabilities, vulnerability)
+ continue
+ }
+
+ // Create one vulnerability by CVE
+ for _, currentCve := range definition.Cves {
+ vulnerability.Name = currentCve.ID
+ vulnerability.Link = currentCve.Href
+ if currentCve.Impact != "" {
+ vulnerability.Severity = severity(currentCve.Impact)
+ } else {
+ vulnerability.Severity = severity(definition.Severity)
+ }
+ vulnerabilities = append(vulnerabilities, vulnerability)
+ }
}
}
@@ -358,23 +386,8 @@ func description(def definition) (desc string) {
return
}
-func name(def definition) string {
- return strings.TrimSpace(def.Title[:strings.Index(def.Title, ": ")])
-}
-
-func link(def definition) (link string) {
- for _, reference := range def.References {
- if reference.Source == "RHSA" {
- link = reference.URI
- break
- }
- }
-
- return
-}
-
-func severity(def definition) database.Severity {
- switch strings.TrimSpace(def.Title[strings.LastIndex(def.Title, "(")+1 : len(def.Title)-1]) {
+func severity(sev string) database.Severity {
+ switch strings.Title(sev) {
case "Low":
return database.LowSeverity
case "Moderate":
@@ -384,7 +397,18 @@ func severity(def definition) database.Severity {
case "Critical":
return database.CriticalSeverity
default:
- log.Warningf("could not determine vulnerability severity from: %s.", def.Title)
+ log.Warningf("could not determine vulnerability severity from: %s.", sev)
return database.UnknownSeverity
}
}
+
+func rhsaName(def definition) string {
+ return strings.TrimSpace(def.Title[:strings.Index(def.Title, ": ")])
+}
+
+func rhsaLink(def definition) (link string) {
+ if len(def.References) > 0 {
+ link = def.References[0].URI
+ }
+ return
+}
diff --git a/ext/vulnsrc/rhel/rhel_test.go b/ext/vulnsrc/rhel/rhel_test.go
index e91ec502..5ac3e108 100644
--- a/ext/vulnsrc/rhel/rhel_test.go
+++ b/ext/vulnsrc/rhel/rhel_test.go
@@ -15,6 +15,7 @@
package rhel
import (
+ "fmt"
"os"
"path/filepath"
"runtime"
@@ -25,7 +26,60 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestRHELParser(t *testing.T) {
+func TestRHELParserMultipleCVE(t *testing.T) {
+ _, filename, _, _ := runtime.Caller(0)
+ path := filepath.Join(filepath.Dir(filename))
+
+ // Test parsing testdata/fetcher_rhel_test.2.xml
+ testFile, _ := os.Open(path + "/testdata/fetcher_rhel_test.2.xml")
+ vulnerabilities, err := parseRHSA(testFile)
+
+ // Expected
+ expectedCve := []string{"CVE-2015-2722", "CVE-2015-2724", "CVE-2015-2725", "CVE-2015-2727", "CVE-2015-2728",
+ "CVE-2015-2729", "CVE-2015-2731", "CVE-2015-2733", "CVE-2015-2734", "CVE-2015-2735", "CVE-2015-2736",
+ "CVE-2015-2737", "CVE-2015-2738", "CVE-2015-2739", "CVE-2015-2740", "CVE-2015-2741", "CVE-2015-2743",
+ }
+ expectedSeverity := []database.Severity{database.CriticalSeverity, database.HighSeverity, database.HighSeverity,
+ database.MediumSeverity, database.MediumSeverity, database.MediumSeverity, database.CriticalSeverity,
+ database.CriticalSeverity, database.CriticalSeverity, database.CriticalSeverity, database.CriticalSeverity,
+ database.CriticalSeverity, database.CriticalSeverity, database.CriticalSeverity, database.CriticalSeverity,
+ database.MediumSeverity, database.MediumSeverity}
+ expectedFeatures := []database.AffectedFeature{
+ {
+ Namespace: database.Namespace{
+ Name: "centos:6",
+ VersionFormat: rpm.ParserName,
+ },
+ FeatureName: "firefox",
+ FixedInVersion: "0:38.1.0-1.el6_6",
+ AffectedVersion: "0:38.1.0-1.el6_6",
+ },
+ {
+ Namespace: database.Namespace{
+ Name: "centos:7",
+ VersionFormat: rpm.ParserName,
+ },
+ FeatureName: "firefox",
+ FixedInVersion: "0:38.1.0-1.el7_1",
+ AffectedVersion: "0:38.1.0-1.el7_1",
+ },
+ }
+
+ if assert.Nil(t, err) && assert.Len(t, vulnerabilities, len(expectedCve)) {
+
+ for i, vulnerability := range vulnerabilities {
+ assert.Equal(t, expectedCve[i], vulnerability.Name)
+ assert.Equal(t, fmt.Sprintf("https://access.redhat.com/security/cve/%s", expectedCve[i]), vulnerability.Link)
+ assert.Equal(t, expectedSeverity[i], vulnerability.Severity)
+ assert.Equal(t, `Mozilla Firefox is an open source web browser. XULRunner provides the XUL Runtime environment for Mozilla Firefox. Several flaws were found in the processing of malformed web content. A web page containing malicious content could cause Firefox to crash or, potentially, execute arbitrary code with the privileges of the user running Firefox.`, vulnerability.Description)
+
+ for _, expectedFeature := range expectedFeatures {
+ assert.Contains(t, vulnerability.Affected, expectedFeature)
+ }
+ }
+ }
+}
+func TestRHELParserOneCVE(t *testing.T) {
_, filename, _, _ := runtime.Caller(0)
path := filepath.Join(filepath.Dir(filename))
@@ -33,8 +87,8 @@ func TestRHELParser(t *testing.T) {
testFile, _ := os.Open(path + "/testdata/fetcher_rhel_test.1.xml")
vulnerabilities, err := parseRHSA(testFile)
if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
- assert.Equal(t, "RHSA-2015:1193", vulnerabilities[0].Name)
- assert.Equal(t, "https://rhn.redhat.com/errata/RHSA-2015-1193.html", vulnerabilities[0].Link)
+ assert.Equal(t, "CVE-2015-0252", vulnerabilities[0].Name)
+ assert.Equal(t, "https://access.redhat.com/security/cve/CVE-2015-0252", vulnerabilities[0].Link)
assert.Equal(t, database.MediumSeverity, vulnerabilities[0].Severity)
assert.Equal(t, `Xerces-C is a validating XML parser written in a portable subset of C++. A flaw was found in the way the Xerces-C XML parser processed certain XML documents. A remote attacker could provide specially crafted XML input that, when parsed by an application using Xerces-C, would cause that application to crash.`, vulnerabilities[0].Description)
@@ -72,39 +126,4 @@ func TestRHELParser(t *testing.T) {
assert.Contains(t, vulnerabilities[0].Affected, expectedFeature)
}
}
-
- // Test parsing testdata/fetcher_rhel_test.2.xml
- testFile, _ = os.Open(path + "/testdata/fetcher_rhel_test.2.xml")
- vulnerabilities, err = parseRHSA(testFile)
- if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
- assert.Equal(t, "RHSA-2015:1207", vulnerabilities[0].Name)
- assert.Equal(t, "https://rhn.redhat.com/errata/RHSA-2015-1207.html", vulnerabilities[0].Link)
- assert.Equal(t, database.CriticalSeverity, vulnerabilities[0].Severity)
- assert.Equal(t, `Mozilla Firefox is an open source web browser. XULRunner provides the XUL Runtime environment for Mozilla Firefox. Several flaws were found in the processing of malformed web content. A web page containing malicious content could cause Firefox to crash or, potentially, execute arbitrary code with the privileges of the user running Firefox.`, vulnerabilities[0].Description)
-
- expectedFeatures := []database.AffectedFeature{
- {
- Namespace: database.Namespace{
- Name: "centos:6",
- VersionFormat: rpm.ParserName,
- },
- FeatureName: "firefox",
- FixedInVersion: "0:38.1.0-1.el6_6",
- AffectedVersion: "0:38.1.0-1.el6_6",
- },
- {
- Namespace: database.Namespace{
- Name: "centos:7",
- VersionFormat: rpm.ParserName,
- },
- FeatureName: "firefox",
- FixedInVersion: "0:38.1.0-1.el7_1",
- AffectedVersion: "0:38.1.0-1.el7_1",
- },
- }
-
- for _, expectedFeature := range expectedFeatures {
- assert.Contains(t, vulnerabilities[0].Affected, expectedFeature)
- }
- }
}
diff --git a/ext/vulnsrc/rhel/testdata/fetcher_rhel_test.2.xml b/ext/vulnsrc/rhel/testdata/fetcher_rhel_test.2.xml
index 32f5aa5d..ed1816be 100644
--- a/ext/vulnsrc/rhel/testdata/fetcher_rhel_test.2.xml
+++ b/ext/vulnsrc/rhel/testdata/fetcher_rhel_test.2.xml
@@ -50,23 +50,23 @@ Firefox.
Copyright 2015 Red Hat, Inc.
- CVE-2015-2722
- CVE-2015-2724
- CVE-2015-2725
- CVE-2015-2727
- CVE-2015-2728
- CVE-2015-2729
- CVE-2015-2731
- CVE-2015-2733
- CVE-2015-2734
- CVE-2015-2735
- CVE-2015-2736
- CVE-2015-2737
- CVE-2015-2738
- CVE-2015-2739
- CVE-2015-2740
- CVE-2015-2741
- CVE-2015-2743
+ CVE-2015-2722
+ CVE-2015-2724
+ CVE-2015-2725
+ CVE-2015-2727
+ CVE-2015-2728
+ CVE-2015-2729
+ CVE-2015-2731
+ CVE-2015-2733
+ CVE-2015-2734
+ CVE-2015-2735
+ CVE-2015-2736
+ CVE-2015-2737
+ CVE-2015-2738
+ CVE-2015-2739
+ CVE-2015-2740
+ CVE-2015-2741
+ CVE-2015-2743
CVE-2015-2724 CVE-2015-2725 Mozilla: Miscellaneous memory safety hazards (rv:31.8 / rv:38.1) (MFSA 2015-59)
CVE-2015-2727 Mozilla: Local files or privileged URLs in pages can be opened into new tabs (MFSA 2015-60)
CVE-2015-2728 Mozilla: Type confusion in Indexed Database Manager (MFSA 2015-61)