refactor(ospkg_scanner): use trivy-db

This commit is contained in:
knqyf263
2019-10-28 11:48:11 +02:00
parent 2921c25c62
commit e5fc57af0e
7 changed files with 117 additions and 78 deletions

View File

@@ -4,13 +4,15 @@ import (
"strings" "strings"
"time" "time"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/vulnsrc/alpine"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
version "github.com/knqyf263/go-rpm-version" version "github.com/knqyf263/go-rpm-version"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/alpine"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/types"
) )
var ( var (
@@ -37,13 +39,17 @@ var (
} }
) )
type Scanner struct{} type Scanner struct {
vs dbTypes.VulnSrc
func NewScanner() *Scanner {
return &Scanner{}
} }
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability.DetectedVulnerability, error) { func NewScanner() *Scanner {
return &Scanner{
vs: alpine.NewVulnSrc(),
}
}
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, error) {
log.Logger.Info("Detecting Alpine vulnerabilities...") log.Logger.Info("Detecting Alpine vulnerabilities...")
if strings.Count(osVer, ".") > 1 { if strings.Count(osVer, ".") > 1 {
osVer = osVer[:strings.LastIndex(osVer, ".")] osVer = osVer[:strings.LastIndex(osVer, ".")]
@@ -51,9 +57,9 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
log.Logger.Debugf("alpine: os version: %s", osVer) log.Logger.Debugf("alpine: os version: %s", osVer)
log.Logger.Debugf("alpine: the number of packages: %d", len(pkgs)) log.Logger.Debugf("alpine: the number of packages: %d", len(pkgs))
var vulns []vulnerability.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, pkg := range pkgs { for _, pkg := range pkgs {
advisories, err := alpine.Get(osVer, pkg.Name) advisories, err := s.vs.Get(osVer, pkg.Name)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get alpine advisories: %w", err) return nil, xerrors.Errorf("failed to get alpine advisories: %w", err)
} }
@@ -64,7 +70,7 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
for _, adv := range advisories { for _, adv := range advisories {
fixedVersion := version.NewVersion(adv.FixedVersion) fixedVersion := version.NewVersion(adv.FixedVersion)
if installedVersion.LessThan(fixedVersion) { if installedVersion.LessThan(fixedVersion) {
vuln := vulnerability.DetectedVulnerability{ vuln := types.DetectedVulnerability{
VulnerabilityID: adv.VulnerabilityID, VulnerabilityID: adv.VulnerabilityID,
PkgName: pkg.Name, PkgName: pkg.Name,
InstalledVersion: installed, InstalledVersion: installed,

View File

@@ -5,19 +5,20 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/vulnsrc/amazon"
version "github.com/knqyf263/go-deb-version" version "github.com/knqyf263/go-deb-version"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/amazon"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils" "github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/types"
) )
type Scanner struct { type Scanner struct {
l *zap.SugaredLogger l *zap.SugaredLogger
ac amazon.Operations ac dbTypes.VulnSrc
} }
func NewScanner() *Scanner { func NewScanner() *Scanner {
@@ -27,7 +28,7 @@ func NewScanner() *Scanner {
} }
} }
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability.DetectedVulnerability, error) { func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, error) {
log.Logger.Info("Detecting Amazon Linux vulnerabilities...") log.Logger.Info("Detecting Amazon Linux vulnerabilities...")
osVer = strings.Fields(osVer)[0] osVer = strings.Fields(osVer)[0]
@@ -37,7 +38,7 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
log.Logger.Debugf("amazon: os version: %s", osVer) log.Logger.Debugf("amazon: os version: %s", osVer)
log.Logger.Debugf("amazon: the number of packages: %d", len(pkgs)) log.Logger.Debugf("amazon: the number of packages: %d", len(pkgs))
var vulns []vulnerability.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, pkg := range pkgs { for _, pkg := range pkgs {
advisories, err := s.ac.Get(osVer, pkg.Name) advisories, err := s.ac.Get(osVer, pkg.Name)
if err != nil { if err != nil {
@@ -63,7 +64,7 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
} }
if installedVersion.LessThan(fixedVersion) { if installedVersion.LessThan(fixedVersion) {
vuln := vulnerability.DetectedVulnerability{ vuln := types.DetectedVulnerability{
VulnerabilityID: adv.VulnerabilityID, VulnerabilityID: adv.VulnerabilityID,
PkgName: pkg.Name, PkgName: pkg.Name,
InstalledVersion: installed, InstalledVersion: installed,

View File

@@ -4,34 +4,34 @@ import (
"errors" "errors"
"testing" "testing"
"github.com/stretchr/testify/assert"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest/observer" "go.uber.org/zap/zaptest/observer"
"github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/fanal/analyzer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/types"
"github.com/stretchr/testify/assert"
) )
type MockAmazonConfig struct { type MockAmazonConfig struct {
update func(string, map[string]struct{}) error update func(string) error
get func(string, string) ([]vulnerability.Advisory, error) get func(string, string) ([]dbTypes.Advisory, error)
} }
func (mac MockAmazonConfig) Update(a string, b map[string]struct{}) error { func (mac MockAmazonConfig) Update(a string) error {
if mac.update != nil { if mac.update != nil {
return mac.update(a, b) return mac.update(a)
} }
return nil return nil
} }
func (mac MockAmazonConfig) Get(a string, b string) ([]vulnerability.Advisory, error) { func (mac MockAmazonConfig) Get(a string, b string) ([]dbTypes.Advisory, error) {
if mac.get != nil { if mac.get != nil {
return mac.get(a, b) return mac.get(a, b)
} }
return []vulnerability.Advisory{}, nil return []dbTypes.Advisory{}, nil
} }
func TestScanner_Detect(t *testing.T) { func TestScanner_Detect(t *testing.T) {
@@ -41,8 +41,8 @@ func TestScanner_Detect(t *testing.T) {
s := &Scanner{ s := &Scanner{
l: log.Logger, l: log.Logger,
ac: MockAmazonConfig{ ac: MockAmazonConfig{
get: func(s string, s2 string) (advisories []vulnerability.Advisory, e error) { get: func(s string, s2 string) (advisories []dbTypes.Advisory, e error) {
return []vulnerability.Advisory{ return []dbTypes.Advisory{
{ {
VulnerabilityID: "123", VulnerabilityID: "123",
FixedVersion: "3.0.0", FixedVersion: "3.0.0",
@@ -65,7 +65,7 @@ func TestScanner_Detect(t *testing.T) {
}, },
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []vulnerability.DetectedVulnerability{ assert.Equal(t, []types.DetectedVulnerability{
{ {
VulnerabilityID: "123", VulnerabilityID: "123",
PkgName: "testpkg", PkgName: "testpkg",
@@ -84,7 +84,7 @@ func TestScanner_Detect(t *testing.T) {
s := &Scanner{ s := &Scanner{
l: log.Logger, l: log.Logger,
ac: MockAmazonConfig{ ac: MockAmazonConfig{
get: func(s string, s2 string) (advisories []vulnerability.Advisory, e error) { get: func(s string, s2 string) (advisories []dbTypes.Advisory, e error) {
return nil, errors.New("failed to fetch advisories") return nil, errors.New("failed to fetch advisories")
}, },
}, },
@@ -104,8 +104,8 @@ func TestScanner_Detect(t *testing.T) {
s := &Scanner{ s := &Scanner{
l: log.Logger, l: log.Logger,
ac: MockAmazonConfig{ ac: MockAmazonConfig{
get: func(s string, s2 string) (advisories []vulnerability.Advisory, e error) { get: func(s string, s2 string) (advisories []dbTypes.Advisory, e error) {
return []vulnerability.Advisory{ return []dbTypes.Advisory{
{ {
VulnerabilityID: "123", VulnerabilityID: "123",
FixedVersion: "3.0.0", FixedVersion: "3.0.0",
@@ -122,7 +122,7 @@ func TestScanner_Detect(t *testing.T) {
}, },
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []vulnerability.DetectedVulnerability(nil), vuls) assert.Equal(t, []types.DetectedVulnerability(nil), vuls)
loggedMessages := getAllLoggedLogs(recorder) loggedMessages := getAllLoggedLogs(recorder)
assert.Contains(t, loggedMessages, "failed to parse Amazon Linux installed package version: upstream_version must start with digit") assert.Contains(t, loggedMessages, "failed to parse Amazon Linux installed package version: upstream_version must start with digit")
}) })
@@ -133,8 +133,8 @@ func TestScanner_Detect(t *testing.T) {
s := &Scanner{ s := &Scanner{
l: log.Logger, l: log.Logger,
ac: MockAmazonConfig{ ac: MockAmazonConfig{
get: func(s string, s2 string) (advisories []vulnerability.Advisory, e error) { get: func(s string, s2 string) (advisories []dbTypes.Advisory, e error) {
return []vulnerability.Advisory{ return []dbTypes.Advisory{
{ {
VulnerabilityID: "123", VulnerabilityID: "123",
FixedVersion: "thisisbadversioning", FixedVersion: "thisisbadversioning",
@@ -151,7 +151,7 @@ func TestScanner_Detect(t *testing.T) {
}, },
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []vulnerability.DetectedVulnerability(nil), vuls) assert.Equal(t, []types.DetectedVulnerability(nil), vuls)
loggedMessages := getAllLoggedLogs(recorder) loggedMessages := getAllLoggedLogs(recorder)
assert.Contains(t, loggedMessages, "failed to parse Amazon Linux package version: upstream_version must start with digit") assert.Contains(t, loggedMessages, "failed to parse Amazon Linux package version: upstream_version must start with digit")
}) })

View File

@@ -4,15 +4,17 @@ import (
"strings" "strings"
"time" "time"
"github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/debian"
debianoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/debian-oval"
version "github.com/knqyf263/go-deb-version" version "github.com/knqyf263/go-deb-version"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils" "github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/vulnsrc/debian" "github.com/aquasecurity/trivy/pkg/types"
debianoval "github.com/aquasecurity/trivy/pkg/vulnsrc/debian-oval"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
) )
var ( var (
@@ -38,13 +40,19 @@ var (
} }
) )
type Scanner struct{} type Scanner struct {
ovalVs dbTypes.VulnSrc
func NewScanner() *Scanner { vs dbTypes.VulnSrc
return &Scanner{}
} }
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability.DetectedVulnerability, error) { func NewScanner() *Scanner {
return &Scanner{
ovalVs: debianoval.NewVulnSrc(),
vs: debian.NewVulnSrc(),
}
}
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, error) {
log.Logger.Info("Detecting Debian vulnerabilities...") log.Logger.Info("Detecting Debian vulnerabilities...")
if strings.Count(osVer, ".") > 0 { if strings.Count(osVer, ".") > 0 {
@@ -53,9 +61,9 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
log.Logger.Debugf("debian: os version: %s", osVer) log.Logger.Debugf("debian: os version: %s", osVer)
log.Logger.Debugf("debian: the number of packages: %d", len(pkgs)) log.Logger.Debugf("debian: the number of packages: %d", len(pkgs))
var vulns []vulnerability.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, pkg := range pkgs { for _, pkg := range pkgs {
advisories, err := debianoval.Get(osVer, pkg.SrcName) advisories, err := s.ovalVs.Get(osVer, pkg.SrcName)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get debian OVAL: %w", err) return nil, xerrors.Errorf("failed to get debian OVAL: %w", err)
} }
@@ -75,7 +83,7 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
} }
if installedVersion.LessThan(fixedVersion) { if installedVersion.LessThan(fixedVersion) {
vuln := vulnerability.DetectedVulnerability{ vuln := types.DetectedVulnerability{
VulnerabilityID: adv.VulnerabilityID, VulnerabilityID: adv.VulnerabilityID,
PkgName: pkg.Name, PkgName: pkg.Name,
InstalledVersion: installed, InstalledVersion: installed,
@@ -84,12 +92,12 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
vulns = append(vulns, vuln) vulns = append(vulns, vuln)
} }
} }
advisories, err = debian.Get(osVer, pkg.SrcName) advisories, err = s.vs.Get(osVer, pkg.SrcName)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get debian advisory: %w", err) return nil, xerrors.Errorf("failed to get debian advisory: %w", err)
} }
for _, adv := range advisories { for _, adv := range advisories {
vuln := vulnerability.DetectedVulnerability{ vuln := types.DetectedVulnerability{
VulnerabilityID: adv.VulnerabilityID, VulnerabilityID: adv.VulnerabilityID,
PkgName: pkg.Name, PkgName: pkg.Name,
InstalledVersion: installed, InstalledVersion: installed,

View File

@@ -4,14 +4,17 @@ import (
"strings" "strings"
"time" "time"
"github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/redhat"
"github.com/aquasecurity/fanal/analyzer/os"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/vulnsrc/redhat"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
version "github.com/knqyf263/go-rpm-version" version "github.com/knqyf263/go-rpm-version"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/os"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/types"
) )
var ( var (
@@ -34,13 +37,17 @@ var (
} }
) )
type Scanner struct{} type Scanner struct {
vs dbTypes.VulnSrc
func NewScanner() *Scanner {
return &Scanner{}
} }
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability.DetectedVulnerability, error) { func NewScanner() *Scanner {
return &Scanner{
vs: redhat.NewVulnSrc(),
}
}
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, error) {
log.Logger.Info("Detecting RHEL/CentOS vulnerabilities...") log.Logger.Info("Detecting RHEL/CentOS vulnerabilities...")
if strings.Count(osVer, ".") > 0 { if strings.Count(osVer, ".") > 0 {
osVer = osVer[:strings.Index(osVer, ".")] osVer = osVer[:strings.Index(osVer, ".")]
@@ -48,9 +55,9 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
log.Logger.Debugf("redhat: os version: %s", osVer) log.Logger.Debugf("redhat: os version: %s", osVer)
log.Logger.Debugf("redhat: the number of packages: %d", len(pkgs)) log.Logger.Debugf("redhat: the number of packages: %d", len(pkgs))
var vulns []vulnerability.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, pkg := range pkgs { for _, pkg := range pkgs {
advisories, err := redhat.Get(osVer, pkg.SrcName) advisories, err := s.vs.Get(osVer, pkg.SrcName)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err) return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
} }
@@ -60,7 +67,7 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
for _, adv := range advisories { for _, adv := range advisories {
fixedVersion := version.NewVersion(adv.FixedVersion) fixedVersion := version.NewVersion(adv.FixedVersion)
vuln := vulnerability.DetectedVulnerability{ vuln := types.DetectedVulnerability{
VulnerabilityID: adv.VulnerabilityID, VulnerabilityID: adv.VulnerabilityID,
PkgName: pkg.Name, PkgName: pkg.Name,
InstalledVersion: installed, InstalledVersion: installed,

View File

@@ -3,14 +3,16 @@ package ubuntu
import ( import (
"time" "time"
"github.com/aquasecurity/trivy/pkg/scanner/utils" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ubuntu"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
version "github.com/knqyf263/go-deb-version" version "github.com/knqyf263/go-deb-version"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/fanal/analyzer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/vulnsrc/ubuntu" "github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/types"
) )
var ( var (
@@ -49,20 +51,24 @@ var (
} }
) )
type Scanner struct{} type Scanner struct {
vs dbTypes.VulnSrc
func NewScanner() *Scanner {
return &Scanner{}
} }
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability.DetectedVulnerability, error) { func NewScanner() *Scanner {
return &Scanner{
vs: ubuntu.NewVulnSrc(),
}
}
func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, error) {
log.Logger.Info("Detecting Ubuntu vulnerabilities...") log.Logger.Info("Detecting Ubuntu vulnerabilities...")
log.Logger.Debugf("ubuntu: os version: %s", osVer) log.Logger.Debugf("ubuntu: os version: %s", osVer)
log.Logger.Debugf("ubuntu: the number of packages: %d", len(pkgs)) log.Logger.Debugf("ubuntu: the number of packages: %d", len(pkgs))
var vulns []vulnerability.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, pkg := range pkgs { for _, pkg := range pkgs {
advisories, err := ubuntu.Get(osVer, pkg.SrcName) advisories, err := s.vs.Get(osVer, pkg.SrcName)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get Ubuntu advisories: %w", err) return nil, xerrors.Errorf("failed to get Ubuntu advisories: %w", err)
} }
@@ -75,7 +81,7 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]vulnerability
} }
for _, adv := range advisories { for _, adv := range advisories {
vuln := vulnerability.DetectedVulnerability{ vuln := types.DetectedVulnerability{
VulnerabilityID: adv.VulnerabilityID, VulnerabilityID: adv.VulnerabilityID,
PkgName: pkg.Name, PkgName: pkg.Name,
InstalledVersion: installed, InstalledVersion: installed,

View File

@@ -1 +1,12 @@
package types package types
import "github.com/aquasecurity/trivy-db/pkg/types"
type DetectedVulnerability struct {
VulnerabilityID string `json:",omitempty"`
PkgName string `json:",omitempty"`
InstalledVersion string `json:",omitempty"`
FixedVersion string `json:",omitempty"`
types.Vulnerability
}