feat(report): support Amazon OVAL scanning (#824)

* feat(report): support Amazon OVAL scanning

* add distroAdvisories

* see goval/master
This commit is contained in:
Kota Kanbe
2019-06-10 23:20:39 +09:00
committed by GitHub
parent 40492ee00a
commit 269095d034
10 changed files with 244 additions and 87 deletions

View File

@@ -95,6 +95,7 @@ func (o DebianBase) convertToModel(def *ovalmodels.Definition) *models.CveConten
Title: def.Title,
Summary: def.Description,
Cvss2Severity: def.Advisory.Severity,
Cvss3Severity: def.Advisory.Severity,
References: refs,
}
}

View File

@@ -133,6 +133,9 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int)
vinfo.CveContents = cveContents
}
vinfo.DistroAdvisories.AppendIfMissing(
o.convertToDistroAdvisory(&defPacks.def))
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
for _, pack := range vinfo.AffectedPackages {
if nfy, ok := defPacks.actuallyAffectedPackNames[pack.Name]; !ok {
@@ -148,6 +151,21 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int)
return
}
func (o RedHatBase) convertToDistroAdvisory(def *ovalmodels.Definition) *models.DistroAdvisory {
advisoryID := def.Title
if o.family == config.RedHat || o.family == config.CentOS {
ss := strings.Fields(def.Title)
advisoryID = strings.TrimSuffix(ss[0], ":")
}
return &models.DistroAdvisory{
AdvisoryID: advisoryID,
Severity: def.Advisory.Severity,
Issued: def.Advisory.Issued,
Updated: def.Advisory.Updated,
Description: def.Description,
}
}
func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *models.CveContent {
for _, cve := range def.Advisory.Cves {
if cve.CveID != cveID {
@@ -171,10 +189,10 @@ func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *mo
}
sev2, sev3 := "", ""
if score2 != 0 {
if score2 == 0 {
sev2 = severity
}
if score3 != 0 {
if score3 == 0 {
sev3 = severity
}
@@ -276,3 +294,20 @@ func NewOracle() Oracle {
},
}
}
// Amazon is the interface for RedhatBase OVAL
type Amazon struct {
// Base
RedHatBase
}
// NewAmazon creates OVAL client for Amazon Linux
func NewAmazon() Amazon {
return Amazon{
RedHatBase{
Base{
family: config.Amazon,
},
},
}
}

View File

@@ -78,7 +78,8 @@ func (e *ovalResult) upsert(def ovalmodels.Definition, packName string, notFixed
type request struct {
packName string
versionRelease string
NewVersionRelease string
newVersionRelease string
arch string
binaryPackNames []string
isSrcPack bool
}
@@ -105,8 +106,9 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
reqChan <- request{
packName: pack.Name,
versionRelease: pack.FormatVer(),
NewVersionRelease: pack.FormatVer(),
newVersionRelease: pack.FormatVer(),
isSrcPack: false,
arch: pack.Arch,
}
}
for _, pack := range r.SrcPackages {
@@ -115,6 +117,7 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
binaryPackNames: pack.BinaryNames,
versionRelease: pack.Version,
isSrcPack: true,
// arch: pack.Arch,
}
}
}()
@@ -220,7 +223,8 @@ func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDef
requests = append(requests, request{
packName: pack.Name,
versionRelease: pack.FormatVer(),
NewVersionRelease: pack.FormatNewVer(),
newVersionRelease: pack.FormatNewVer(),
arch: pack.Arch,
isSrcPack: false,
})
}
@@ -234,7 +238,7 @@ func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDef
}
for _, req := range requests {
definitions, err := driver.GetByPackName(r.Release, req.packName)
definitions, err := driver.GetByPackName(r.Release, req.packName, req.arch)
if err != nil {
return relatedDefs, xerrors.Errorf("Failed to get %s OVAL info by package: %#v, err: %w", r.Family, req, err)
}
@@ -315,15 +319,15 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
// `offline` or `fast` scan mode can't get a updatable version.
// In these mode, the blow field was set empty.
// Vuls can not judge fixed or unfixed.
if req.NewVersionRelease == "" {
if req.newVersionRelease == "" {
return true, false
}
// compare version: newVer vs oval
less, err := lessThan(family, req.NewVersionRelease, ovalPack)
less, err := lessThan(family, req.newVersionRelease, ovalPack)
if err != nil {
util.Log.Debugf("Failed to parse versions: %s, NewVer: %#v, OVAL: %#v, DefID: %s",
err, req.NewVersionRelease, ovalPack, def.DefinitionID)
err, req.newVersionRelease, ovalPack, def.DefinitionID)
return false, false
}
return true, less
@@ -332,9 +336,13 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
return false, false
}
var centosVerPattern = regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.centos)?`)
var esVerPattern = regexp.MustCompile(`\.el(\d+)(?:_\d+)?`)
func lessThan(family, versionRelease string, packB ovalmodels.Package) (bool, error) {
switch family {
case config.Debian, config.Ubuntu:
case config.Debian,
config.Ubuntu:
vera, err := debver.NewVersion(versionRelease)
if err != nil {
return false, err
@@ -344,16 +352,21 @@ func lessThan(family, versionRelease string, packB ovalmodels.Package) (bool, er
return false, err
}
return vera.LessThan(verb), nil
case config.Oracle, config.SUSEEnterpriseServer, config.Alpine:
case config.Oracle,
config.SUSEEnterpriseServer,
config.Alpine,
config.Amazon:
vera := rpmver.NewVersion(versionRelease)
verb := rpmver.NewVersion(packB.Version)
return vera.LessThan(verb), nil
case config.RedHat, config.CentOS: // TODO: Suport config.Scientific
rea := regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.centos)?`)
reb := regexp.MustCompile(`\.el(\d+)(?:_\d+)?`)
vera := rpmver.NewVersion(rea.ReplaceAllString(versionRelease, ".el$1"))
verb := rpmver.NewVersion(reb.ReplaceAllString(packB.Version, ".el$1"))
case config.RedHat,
config.CentOS:
vera := rpmver.NewVersion(centosVerPattern.ReplaceAllString(versionRelease, ".el$1"))
verb := rpmver.NewVersion(esVerPattern.ReplaceAllString(packB.Version, ".el$1"))
return vera.LessThan(verb), nil
default:
util.Log.Errorf("Not implemented yet: %s", family)
}

View File

@@ -281,7 +281,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "1.0.0-0",
NewVersionRelease: "1.0.0-2",
newVersionRelease: "1.0.0-2",
},
},
affected: true,
@@ -313,7 +313,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "1.0.0-0",
NewVersionRelease: "1.0.0-3",
newVersionRelease: "1.0.0-3",
},
},
affected: true,
@@ -340,7 +340,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.7",
NewVersionRelease: "",
newVersionRelease: "",
},
},
affected: true,
@@ -367,7 +367,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.7",
newVersionRelease: "0:1.2.3-45.el6_7.7",
},
},
affected: true,
@@ -446,7 +446,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.7",
newVersionRelease: "0:1.2.3-45.el6_7.7",
},
},
affected: true,
@@ -473,7 +473,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.8",
newVersionRelease: "0:1.2.3-45.el6_7.8",
},
},
affected: true,
@@ -499,7 +499,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.9",
newVersionRelease: "0:1.2.3-45.el6_7.9",
},
},
affected: true,
@@ -578,7 +578,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.7",
NewVersionRelease: "",
newVersionRelease: "",
},
},
affected: true,
@@ -657,7 +657,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.6",
NewVersionRelease: "0:1.2.3-45.el6.centos.7",
newVersionRelease: "0:1.2.3-45.el6.centos.7",
},
},
affected: true,
@@ -684,7 +684,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.6",
NewVersionRelease: "0:1.2.3-45.el6.centos.8",
newVersionRelease: "0:1.2.3-45.el6.centos.8",
},
},
affected: true,
@@ -711,7 +711,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.6",
NewVersionRelease: "0:1.2.3-45.el6.centos.9",
newVersionRelease: "0:1.2.3-45.el6.centos.9",
},
},
affected: true,
@@ -865,7 +865,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.sl6.6",
NewVersionRelease: "0:1.2.3-45.sl6.7",
newVersionRelease: "0:1.2.3-45.sl6.7",
},
},
affected: true,
@@ -891,7 +891,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.sl6.6",
NewVersionRelease: "0:1.2.3-45.sl6.8",
newVersionRelease: "0:1.2.3-45.sl6.8",
},
},
affected: true,
@@ -917,7 +917,7 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.sl6.6",
NewVersionRelease: "0:1.2.3-45.sl6.9",
newVersionRelease: "0:1.2.3-45.sl6.9",
},
},
affected: true,
@@ -989,7 +989,7 @@ func TestIsOvalDefAffected(t *testing.T) {
req: request{
packName: "kernel",
versionRelease: "3.0.0",
NewVersionRelease: "3.2.0",
newVersionRelease: "3.2.0",
},
kernel: models.Kernel{
Release: "3.0.0",
@@ -1013,7 +1013,7 @@ func TestIsOvalDefAffected(t *testing.T) {
req: request{
packName: "kernel",
versionRelease: "3.0.0",
NewVersionRelease: "3.2.0",
newVersionRelease: "3.2.0",
},
kernel: models.Kernel{
Release: "3.0.0",