From 2236b0a5c9a094bde2b7979417b9538cb944e726 Mon Sep 17 00:00:00 2001 From: Sida Chen Date: Thu, 18 Oct 2018 14:52:50 -0400 Subject: [PATCH] updater: Add vulnsrc affected feature type Each vulnerability source has a specific type of feature that it affects We assume the following: * Alpine: Binary Package * Debian: Source Package * Ubuntu: Source Package * Oracle OVAL: Binary Package * RHEL OVAL: Binary Package --- ext/vulnsrc/alpine/alpine.go | 4 ++++ ext/vulnsrc/debian/debian.go | 2 ++ ext/vulnsrc/debian/debian_test.go | 5 +++++ ext/vulnsrc/oracle/oracle.go | 2 ++ ext/vulnsrc/oracle/oracle_test.go | 5 +++++ ext/vulnsrc/rhel/rhel.go | 2 ++ ext/vulnsrc/rhel/rhel_test.go | 5 +++++ ext/vulnsrc/ubuntu/ubuntu.go | 8 +++++--- ext/vulnsrc/ubuntu/ubuntu_test.go | 3 +++ updater.go | 2 +- updater_test.go | 9 ++++++--- 11 files changed, 40 insertions(+), 7 deletions(-) diff --git a/ext/vulnsrc/alpine/alpine.go b/ext/vulnsrc/alpine/alpine.go index a12e358b..890ffc26 100644 --- a/ext/vulnsrc/alpine/alpine.go +++ b/ext/vulnsrc/alpine/alpine.go @@ -37,6 +37,9 @@ const ( secdbGitURL = "https://github.com/alpinelinux/alpine-secdb" updaterFlag = "alpine-secdbUpdater" nvdURLPrefix = "https://cve.mitre.org/cgi-bin/cvename.cgi?name=" + // affected type indicates if the affected feature hint is for binary or + // source package. + affectedType = database.AffectBinaryPackage ) func init() { @@ -226,6 +229,7 @@ func parseYAML(r io.Reader) (vulns []database.VulnerabilityWithAffected, err err } vuln.Affected = []database.AffectedFeature{ { + AffectedType: affectedType, FeatureName: pkg.Name, AffectedVersion: version, FixedInVersion: fixedInVersion, diff --git a/ext/vulnsrc/debian/debian.go b/ext/vulnsrc/debian/debian.go index 31154dfb..2d265f8a 100644 --- a/ext/vulnsrc/debian/debian.go +++ b/ext/vulnsrc/debian/debian.go @@ -38,6 +38,7 @@ const ( url = "https://security-tracker.debian.org/tracker/data/json" cveURLPrefix = "https://security-tracker.debian.org/tracker" updaterFlag = "debianUpdater" + affectedType = database.AffectSourcePackage ) type jsonData map[string]map[string]jsonVuln @@ -227,6 +228,7 @@ func parseDebianJSON(data *jsonData) (vulnerabilities []database.VulnerabilityWi // Create and add the feature version. pkg := database.AffectedFeature{ + AffectedType: affectedType, FeatureName: pkgName, AffectedVersion: version, FixedInVersion: fixedInVersion, diff --git a/ext/vulnsrc/debian/debian_test.go b/ext/vulnsrc/debian/debian_test.go index 3a6f9ace..e304e028 100644 --- a/ext/vulnsrc/debian/debian_test.go +++ b/ext/vulnsrc/debian/debian_test.go @@ -41,6 +41,7 @@ func TestDebianParser(t *testing.T) { expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "debian:8", VersionFormat: dpkg.ParserName, @@ -49,6 +50,7 @@ func TestDebianParser(t *testing.T) { AffectedVersion: versionfmt.MaxVersion, }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "debian:unstable", VersionFormat: dpkg.ParserName, @@ -69,6 +71,7 @@ func TestDebianParser(t *testing.T) { expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "debian:8", VersionFormat: dpkg.ParserName, @@ -78,6 +81,7 @@ func TestDebianParser(t *testing.T) { AffectedVersion: "0.7.0", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "debian:unstable", VersionFormat: dpkg.ParserName, @@ -87,6 +91,7 @@ func TestDebianParser(t *testing.T) { AffectedVersion: "0.7.0", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "debian:8", VersionFormat: dpkg.ParserName, diff --git a/ext/vulnsrc/oracle/oracle.go b/ext/vulnsrc/oracle/oracle.go index 16df151b..b5ab5e96 100644 --- a/ext/vulnsrc/oracle/oracle.go +++ b/ext/vulnsrc/oracle/oracle.go @@ -41,6 +41,7 @@ const ( ovalURI = "https://linux.oracle.com/oval/" elsaFilePrefix = "com.oracle.elsa-" updaterFlag = "oracleUpdater" + affectedType = database.AffectBinaryPackage ) var ( @@ -345,6 +346,7 @@ func toFeatures(criteria criteria) []database.AffectedFeature { } else if strings.Contains(c.Comment, " is earlier than ") { const prefixLen = len(" is earlier than ") featureVersion.FeatureName = strings.TrimSpace(c.Comment[:strings.Index(c.Comment, " is earlier than ")]) + featureVersion.AffectedType = affectedType version := c.Comment[strings.Index(c.Comment, " is earlier than ")+prefixLen:] err := versionfmt.Valid(rpm.ParserName, version) if err != nil { diff --git a/ext/vulnsrc/oracle/oracle_test.go b/ext/vulnsrc/oracle/oracle_test.go index a9348d48..0af8d02a 100644 --- a/ext/vulnsrc/oracle/oracle_test.go +++ b/ext/vulnsrc/oracle/oracle_test.go @@ -42,6 +42,7 @@ func TestOracleParser(t *testing.T) { expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "oracle:7", VersionFormat: rpm.ParserName, @@ -51,6 +52,7 @@ func TestOracleParser(t *testing.T) { AffectedVersion: "0:3.1.1-7.el7_1", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "oracle:7", VersionFormat: rpm.ParserName, @@ -60,6 +62,7 @@ func TestOracleParser(t *testing.T) { AffectedVersion: "0:3.1.1-7.el7_1", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "oracle:7", VersionFormat: rpm.ParserName, @@ -86,6 +89,7 @@ func TestOracleParser(t *testing.T) { assert.Equal(t, ` [38.1.0-1.0.1.el7_1] - Add firefox-oracle-default-prefs.js and remove the corresponding Red Hat file [38.1.0-1] - Update to 38.1.0 ESR [38.0.1-2] - Fixed rhbz#1222807 by removing preun section `, vulnerabilities[0].Description) expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "oracle:6", VersionFormat: rpm.ParserName, @@ -95,6 +99,7 @@ func TestOracleParser(t *testing.T) { AffectedVersion: "0:38.1.0-1.0.1.el6_6", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "oracle:7", VersionFormat: rpm.ParserName, diff --git a/ext/vulnsrc/rhel/rhel.go b/ext/vulnsrc/rhel/rhel.go index b35f5639..79bfb7cc 100644 --- a/ext/vulnsrc/rhel/rhel.go +++ b/ext/vulnsrc/rhel/rhel.go @@ -43,6 +43,7 @@ const ( ovalURI = "https://www.redhat.com/security/data/oval/" rhsaFilePrefix = "com.redhat.rhsa-" updaterFlag = "rhelUpdater" + affectedType = database.AffectBinaryPackage ) var ( @@ -341,6 +342,7 @@ func toFeatures(criteria criteria) []database.AffectedFeature { } else if strings.Contains(c.Comment, " is earlier than ") { const prefixLen = len(" is earlier than ") featureVersion.FeatureName = strings.TrimSpace(c.Comment[:strings.Index(c.Comment, " is earlier than ")]) + featureVersion.AffectedType = affectedType version := c.Comment[strings.Index(c.Comment, " is earlier than ")+prefixLen:] err := versionfmt.Valid(rpm.ParserName, version) if err != nil { diff --git a/ext/vulnsrc/rhel/rhel_test.go b/ext/vulnsrc/rhel/rhel_test.go index 5ac3e108..41f9a778 100644 --- a/ext/vulnsrc/rhel/rhel_test.go +++ b/ext/vulnsrc/rhel/rhel_test.go @@ -46,6 +46,7 @@ func TestRHELParserMultipleCVE(t *testing.T) { database.MediumSeverity, database.MediumSeverity} expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "centos:6", VersionFormat: rpm.ParserName, @@ -55,6 +56,7 @@ func TestRHELParserMultipleCVE(t *testing.T) { AffectedVersion: "0:38.1.0-1.el6_6", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "centos:7", VersionFormat: rpm.ParserName, @@ -94,6 +96,7 @@ func TestRHELParserOneCVE(t *testing.T) { expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "centos:7", VersionFormat: rpm.ParserName, @@ -103,6 +106,7 @@ func TestRHELParserOneCVE(t *testing.T) { FixedInVersion: "0:3.1.1-7.el7_1", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "centos:7", VersionFormat: rpm.ParserName, @@ -112,6 +116,7 @@ func TestRHELParserOneCVE(t *testing.T) { FixedInVersion: "0:3.1.1-7.el7_1", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "centos:7", VersionFormat: rpm.ParserName, diff --git a/ext/vulnsrc/ubuntu/ubuntu.go b/ext/vulnsrc/ubuntu/ubuntu.go index ba3a9ac5..4dd79226 100644 --- a/ext/vulnsrc/ubuntu/ubuntu.go +++ b/ext/vulnsrc/ubuntu/ubuntu.go @@ -35,9 +35,10 @@ import ( ) const ( - trackerURI = "https://git.launchpad.net/ubuntu-cve-tracker" - updaterFlag = "ubuntuUpdater" - cveURL = "http://people.ubuntu.com/~ubuntu-security/cve/%s" + trackerURI = "https://git.launchpad.net/ubuntu-cve-tracker" + updaterFlag = "ubuntuUpdater" + cveURL = "http://people.ubuntu.com/~ubuntu-security/cve/%s" + affectedType = database.AffectSourcePackage ) var ( @@ -334,6 +335,7 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability database.Vulnerability // Create and add the new package. featureVersion := database.AffectedFeature{ + AffectedType: affectedType, Namespace: database.Namespace{ Name: releaseName, VersionFormat: dpkg.ParserName, diff --git a/ext/vulnsrc/ubuntu/ubuntu_test.go b/ext/vulnsrc/ubuntu/ubuntu_test.go index a4bd8afd..7e593859 100644 --- a/ext/vulnsrc/ubuntu/ubuntu_test.go +++ b/ext/vulnsrc/ubuntu/ubuntu_test.go @@ -46,6 +46,7 @@ func TestUbuntuParser(t *testing.T) { expectedFeatures := []database.AffectedFeature{ { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "ubuntu:14.04", VersionFormat: dpkg.ParserName, @@ -54,6 +55,7 @@ func TestUbuntuParser(t *testing.T) { AffectedVersion: versionfmt.MaxVersion, }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "ubuntu:15.04", VersionFormat: dpkg.ParserName, @@ -63,6 +65,7 @@ func TestUbuntuParser(t *testing.T) { AffectedVersion: "0.4-3", }, { + AffectedType: affectedType, Namespace: database.Namespace{ Name: "ubuntu:15.10", VersionFormat: dpkg.ParserName, diff --git a/updater.go b/updater.go index 567db2c2..bd092a9b 100644 --- a/updater.go +++ b/updater.go @@ -425,7 +425,7 @@ func doVulnerabilitiesNamespacing(vulnerabilities []database.VulnerabilityWithAf for _, fv := range namespacedFeatures { // validate vulnerabilities, throw out the invalid vulnerabilities - if fv.AffectedVersion == "" || fv.FeatureName == "" || fv.Namespace.Name == "" || fv.Namespace.VersionFormat == "" { + if fv.AffectedType == "" || fv.AffectedVersion == "" || fv.FeatureName == "" || fv.Namespace.Name == "" || fv.Namespace.VersionFormat == "" { log.WithFields(log.Fields{ "Name": fv.FeatureName, "Affected Version": fv.AffectedVersion, diff --git a/updater_test.go b/updater_test.go index c1a623d9..93ad2ecd 100644 --- a/updater_test.go +++ b/updater_test.go @@ -183,6 +183,7 @@ func newmockUpdaterDatastore() *mockUpdaterDatastore { func TestDoVulnerabilitiesNamespacing(t *testing.T) { fv1 := database.AffectedFeature{ + AffectedType: database.AffectSourcePackage, Namespace: database.Namespace{Name: "Namespace1"}, FeatureName: "Feature1", FixedInVersion: "0.1", @@ -190,6 +191,7 @@ func TestDoVulnerabilitiesNamespacing(t *testing.T) { } fv2 := database.AffectedFeature{ + AffectedType: database.AffectSourcePackage, Namespace: database.Namespace{Name: "Namespace2"}, FeatureName: "Feature1", FixedInVersion: "0.2", @@ -197,7 +199,7 @@ func TestDoVulnerabilitiesNamespacing(t *testing.T) { } fv3 := database.AffectedFeature{ - + AffectedType: database.AffectSourcePackage, Namespace: database.Namespace{Name: "Namespace2"}, FeatureName: "Feature2", FixedInVersion: "0.3", @@ -235,8 +237,9 @@ func TestCreatVulnerabilityNotification(t *testing.T) { VersionFormat: vf1, } af1 := database.AffectedFeature{ - Namespace: ns1, - FeatureName: "feature 1", + AffectedType: database.AffectSourcePackage, + Namespace: ns1, + FeatureName: "feature 1", } v1 := database.VulnerabilityWithAffected{