feat(lang-pkg): add data sources (#1625)

This commit is contained in:
Teppei Fukuda
2022-01-27 14:22:06 +02:00
committed by GitHub
parent a31ddbe971
commit 50bb938a21
26 changed files with 176 additions and 99 deletions

2
go.mod
View File

@@ -13,7 +13,7 @@ require (
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492
github.com/aquasecurity/trivy-db v0.0.0-20220119092408-3e43e9ac6def github.com/aquasecurity/trivy-db v0.0.0-20220125230746-e5eec5a98bf1
github.com/caarlos0/env/v6 v6.0.0 github.com/caarlos0/env/v6 v6.0.0
github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cheggaaa/pb/v3 v3.0.3 github.com/cheggaaa/pb/v3 v3.0.3

6
go.sum
View File

@@ -241,10 +241,8 @@ github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516 h1:moQmzbp
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516/go.mod h1:gTd97VdQ0rg8Mkiic3rPgNOQdprZ7feTAhiD5mGQjgM= github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516/go.mod h1:gTd97VdQ0rg8Mkiic3rPgNOQdprZ7feTAhiD5mGQjgM=
github.com/aquasecurity/tfsec v0.63.1 h1:KH63HTcUoab7d3PKtqFO6T8K5AY7bzLw7Kiu+EY9U64= github.com/aquasecurity/tfsec v0.63.1 h1:KH63HTcUoab7d3PKtqFO6T8K5AY7bzLw7Kiu+EY9U64=
github.com/aquasecurity/tfsec v0.63.1/go.mod h1:g5ZWmsfqW1FsCaPb9ux8Pzjcyss/WUB2XuRd5slqvnc= github.com/aquasecurity/tfsec v0.63.1/go.mod h1:g5ZWmsfqW1FsCaPb9ux8Pzjcyss/WUB2XuRd5slqvnc=
github.com/aquasecurity/trivy-db v0.0.0-20220116182821-1a83ba8d44cf h1:STzhFjoXPmE+HQzjydti5w5KNvQpUYwaH4y878jq+II= github.com/aquasecurity/trivy-db v0.0.0-20220125230746-e5eec5a98bf1 h1:mOaPyX+hVglWFk8TbLA7q01GnqVcf6yPusaQaWnDNjE=
github.com/aquasecurity/trivy-db v0.0.0-20220116182821-1a83ba8d44cf/go.mod h1:rnojVJTK+RySsfLW7xMqmQRSjQpm5fEjS+/N4kf3fcc= github.com/aquasecurity/trivy-db v0.0.0-20220125230746-e5eec5a98bf1/go.mod h1:rnojVJTK+RySsfLW7xMqmQRSjQpm5fEjS+/N4kf3fcc=
github.com/aquasecurity/trivy-db v0.0.0-20220119092408-3e43e9ac6def h1:2E1Fj1ouevZG/2ii+XgZitDf3h5fyvNeUKduHbpDZr0=
github.com/aquasecurity/trivy-db v0.0.0-20220119092408-3e43e9ac6def/go.mod h1:rnojVJTK+RySsfLW7xMqmQRSjQpm5fEjS+/N4kf3fcc=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=

View File

@@ -1,4 +1,4 @@
- bucket: GitHub Security Advisory Rubygems - bucket: GitHub Security Advisory RubyGems
pairs: pairs:
- bucket: activesupport - bucket: activesupport
pairs: pairs:

View File

@@ -94,6 +94,10 @@ func (c *ReportOption) Init(logger *zap.SugaredLogger) error {
} }
func (c *ReportOption) populateVulnTypes() error { func (c *ReportOption) populateVulnTypes() error {
if c.vulnType == "" {
return nil
}
for _, v := range strings.Split(c.vulnType, ",") { for _, v := range strings.Split(c.vulnType, ",") {
if types.NewVulnType(v) == types.VulnTypeUnknown { if types.NewVulnType(v) == types.VulnTypeUnknown {
return xerrors.Errorf("unknown vulnerability type (%s)", v) return xerrors.Errorf("unknown vulnerability type (%s)", v)
@@ -104,6 +108,10 @@ func (c *ReportOption) populateVulnTypes() error {
} }
func (c *ReportOption) populateSecurityChecks() error { func (c *ReportOption) populateSecurityChecks() error {
if c.securityChecks == "" {
return nil
}
for _, v := range strings.Split(c.securityChecks, ",") { for _, v := range strings.Split(c.securityChecks, ",") {
if types.NewSecurityCheck(v) == types.SecurityCheckUnknown { if types.NewSecurityCheck(v) == types.SecurityCheckUnknown {
return xerrors.Errorf("unknown security check (%s)", v) return xerrors.Errorf("unknown security check (%s)", v)

View File

@@ -49,6 +49,7 @@ func (s *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
PkgName: pkgName, PkgName: pkgName,
InstalledVersion: pkgVer, InstalledVersion: pkgVer,
FixedVersion: s.createFixedVersions(advisory), FixedVersion: s.createFixedVersions(advisory),
DataSource: advisory.DataSource,
} }
vulns = append(vulns, vuln) vulns = append(vulns, vuln)
} }

View File

@@ -5,20 +5,14 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
bundlerSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/bundler" bundlerSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/bundler"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
) )
// VulnSrc defines the operation on bundler vulnerability
type VulnSrc interface {
Get(pkgName string) ([]bundlerSrc.Advisory, error)
}
// Advisory implements the bundler VulnSrc // Advisory implements the bundler VulnSrc
type Advisory struct { type Advisory struct {
comparer RubyGemsComparer comparer RubyGemsComparer
vs VulnSrc vs bundlerSrc.VulnSrc
} }
// NewAdvisory is the factory method to return bundler.Advisory // NewAdvisory is the factory method to return bundler.Advisory
@@ -38,11 +32,7 @@ func (a *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
var vulns []types.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, advisory := range advisories { for _, advisory := range advisories {
adv := dbTypes.Advisory{ if !a.comparer.IsVulnerable(pkgVer, advisory) {
UnaffectedVersions: advisory.UnaffectedVersions,
PatchedVersions: advisory.PatchedVersions,
}
if !a.comparer.IsVulnerable(pkgVer, adv) {
continue continue
} }
@@ -51,6 +41,7 @@ func (a *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
PkgName: strings.TrimSpace(pkgName), PkgName: strings.TrimSpace(pkgName),
InstalledVersion: pkgVer, InstalledVersion: pkgVer,
FixedVersion: strings.Join(advisory.PatchedVersions, ", "), FixedVersion: strings.Join(advisory.PatchedVersions, ", "),
DataSource: advisory.DataSource,
} }
vulns = append(vulns, vuln) vulns = append(vulns, vuln)
} }

View File

@@ -3,12 +3,13 @@ package bundler_test
import ( import (
"testing" "testing"
"github.com/aquasecurity/trivy/pkg/detector/library/bundler"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/bundler"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
) )
@@ -30,13 +31,20 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
pkgName: "activesupport", pkgName: "activesupport",
pkgVer: "4.1.1", pkgVer: "4.1.1",
}, },
fixtures: []string{"testdata/fixtures/gem.yaml"}, fixtures: []string{
"testdata/fixtures/gem.yaml",
"testdata/fixtures/data-source.yaml",
},
want: []types.DetectedVulnerability{ want: []types.DetectedVulnerability{
{ {
PkgName: "activesupport", PkgName: "activesupport",
InstalledVersion: "4.1.1", InstalledVersion: "4.1.1",
VulnerabilityID: "CVE-2015-3226", VulnerabilityID: "CVE-2015-3226",
FixedVersion: ">= 4.2.2, ~> 4.1.11", FixedVersion: ">= 4.2.2, ~> 4.1.11",
DataSource: &dbTypes.DataSource{
Name: "Ruby Advisory Database",
URL: "https://github.com/rubysec/ruby-advisory-db",
},
}, },
}, },
}, },
@@ -72,10 +80,9 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
require.NotNil(t, err) require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr) assert.Contains(t, err.Error(), tt.wantErr)
return return
} else {
assert.NoError(t, err)
} }
assert.NoError(t, err)
assert.Equal(t, tt.want, got) assert.Equal(t, tt.want, got)
}) })
} }

View File

@@ -0,0 +1,6 @@
- bucket: data-source
pairs:
- key: ruby-advisory-db
value:
Name: "Ruby Advisory Database"
URL: "https://github.com/rubysec/ruby-advisory-db"

View File

@@ -6,7 +6,6 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
composerSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/composer" composerSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/composer"
"github.com/aquasecurity/trivy/pkg/detector/library/comparer" "github.com/aquasecurity/trivy/pkg/detector/library/comparer"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
@@ -36,19 +35,18 @@ func (s *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
var vulns []types.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, advisory := range advisories { for _, advisory := range advisories {
var affectedVersions []string
var patchedVersions []string var patchedVersions []string
for _, branch := range advisory.Branches { for _, vulnerableRange := range advisory.VulnerableVersions {
for _, version := range branch.Versions { // e.g. ">=5, <5.3.1"
if !strings.HasPrefix(version, "<=") && strings.HasPrefix(version, "<") { for _, v := range strings.Split(vulnerableRange, ", ") {
patchedVersions = append(patchedVersions, strings.Trim(version, "<")) // e.g. "<5.3.1"
if !strings.HasPrefix(v, "<=") && strings.HasPrefix(v, "<") {
patchedVersions = append(patchedVersions, strings.Trim(v, "<"))
} }
} }
affectedVersions = append(affectedVersions, strings.Join(branch.Versions, ", "))
} }
adv := dbTypes.Advisory{VulnerableVersions: affectedVersions} if !s.comparer.IsVulnerable(pkgVer, advisory) {
if !s.comparer.IsVulnerable(pkgVer, adv) {
continue continue
} }
@@ -57,6 +55,7 @@ func (s *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
PkgName: pkgName, PkgName: pkgName,
InstalledVersion: pkgVer, InstalledVersion: pkgVer,
FixedVersion: strings.Join(patchedVersions, ", "), FixedVersion: strings.Join(patchedVersions, ", "),
DataSource: advisory.DataSource,
} }
vulns = append(vulns, vuln) vulns = append(vulns, vuln)
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/composer" "github.com/aquasecurity/trivy/pkg/detector/library/composer"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
@@ -30,13 +31,20 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
pkgName: "aws/aws-sdk-php", pkgName: "aws/aws-sdk-php",
pkgVer: "3.2.0", pkgVer: "3.2.0",
}, },
fixtures: []string{"testdata/fixtures/composer.yaml"}, fixtures: []string{
"testdata/fixtures/composer.yaml",
"testdata/fixtures/data-source.yaml",
},
want: []types.DetectedVulnerability{ want: []types.DetectedVulnerability{
{ {
PkgName: "aws/aws-sdk-php", PkgName: "aws/aws-sdk-php",
InstalledVersion: "3.2.0", InstalledVersion: "3.2.0",
VulnerabilityID: "CVE-2015-5723", VulnerabilityID: "CVE-2015-5723",
FixedVersion: "3.2.1", FixedVersion: "3.2.1",
DataSource: &dbTypes.DataSource{
Name: "PHP Security Advisories Database",
URL: "https://github.com/FriendsOfPHP/security-advisories",
},
}, },
}, },
}, },

View File

@@ -4,25 +4,13 @@
pairs: pairs:
- key: CVE-2015-5723 - key: CVE-2015-5723
value: value:
Branches: VulnerableVersions:
3.x: - ">=3.0.0, <3.2.1"
Versions:
- ">=3.0.0"
- "<3.2.1"
- bucket: "composer://guzzlehttp/guzzle" - bucket: "composer://guzzlehttp/guzzle"
pairs: pairs:
- key: CVE-2016-5385 - key: CVE-2016-5385
value: value:
Branches: VulnerableVersions:
4.x: - ">=4.0.0rc2, <4.2.4"
Versions: - ">=5, <5.3.1"
- ">=4.0.0rc2" - ">=6, <6.2.1"
- "<4.2.4"
5.3:
Versions:
- ">=5"
- "<5.3.1"
master:
Versions:
- ">=6"
- "<6.2.1"

View File

@@ -0,0 +1,6 @@
- bucket: data-source
pairs:
- key: php-security-advisories
value:
Name: "PHP Security Advisories Database"
URL: "https://github.com/FriendsOfPHP/security-advisories"

View File

@@ -4,4 +4,4 @@
pairs: pairs:
- key: CVE-2015-5723 - key: CVE-2015-5723
value: value:
Branches: invalid VulnerableVersions: invalid

View File

@@ -87,7 +87,7 @@ func (d *Driver) Type() string {
func newRubyGemsDriver() Driver { func newRubyGemsDriver() Driver {
c := bundler.RubyGemsComparer{} c := bundler.RubyGemsComparer{}
return Aggregate(vulnerability.RubyGems, NewAdvisory(vulnerability.RubyGems, c), bundler.NewAdvisory(), ghsa.NewAdvisory(ecosystem.Rubygems, c)) return Aggregate(vulnerability.RubyGems, NewAdvisory(vulnerability.RubyGems, c), bundler.NewAdvisory(), ghsa.NewAdvisory(ecosystem.RubyGems, c))
} }
func newComposerDriver() Driver { func newComposerDriver() Driver {

View File

@@ -8,6 +8,7 @@ import (
ftypes "github.com/aquasecurity/fanal/types" ftypes "github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library" "github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
@@ -27,9 +28,12 @@ func TestDriver_Detect(t *testing.T) {
wantErr string wantErr string
}{ }{
{ {
name: "happy path", name: "happy path",
fixtures: []string{"testdata/fixtures/php.yaml"}, fixtures: []string{
libType: ftypes.Composer, "testdata/fixtures/php.yaml",
"testdata/fixtures/data-source.yaml",
},
libType: ftypes.Composer,
args: args{ args: args{
pkgName: "symfony/symfony", pkgName: "symfony/symfony",
pkgVer: "4.2.6", pkgVer: "4.2.6",
@@ -40,6 +44,10 @@ func TestDriver_Detect(t *testing.T) {
PkgName: "symfony/symfony", PkgName: "symfony/symfony",
InstalledVersion: "4.2.6", InstalledVersion: "4.2.6",
FixedVersion: "4.2.7", FixedVersion: "4.2.7",
DataSource: &dbTypes.DataSource{
Name: "GitLab Advisory Database Community",
URL: "https://gitlab.com/gitlab-org/advisories-community",
},
}, },
}, },
}, },
@@ -61,9 +69,12 @@ func TestDriver_Detect(t *testing.T) {
}, },
}, },
{ {
name: "no patched versions in the advisory", name: "no patched versions in the advisory",
fixtures: []string{"testdata/fixtures/php.yaml"}, fixtures: []string{
libType: ftypes.Composer, "testdata/fixtures/php.yaml",
"testdata/fixtures/data-source.yaml",
},
libType: ftypes.Composer,
args: args{ args: args{
pkgName: "symfony/symfony", pkgName: "symfony/symfony",
pkgVer: "4.4.6", pkgVer: "4.4.6",
@@ -74,13 +85,20 @@ func TestDriver_Detect(t *testing.T) {
PkgName: "symfony/symfony", PkgName: "symfony/symfony",
InstalledVersion: "4.4.6", InstalledVersion: "4.4.6",
FixedVersion: "4.4.7", FixedVersion: "4.4.7",
DataSource: &dbTypes.DataSource{
Name: "PHP Security Advisories Database",
URL: "https://github.com/FriendsOfPHP/security-advisories",
},
}, },
}, },
}, },
{ {
name: "no vulnerable versions in the advisory", name: "no vulnerable versions in the advisory",
fixtures: []string{"testdata/fixtures/ruby.yaml"}, fixtures: []string{
libType: ftypes.Bundler, "testdata/fixtures/ruby.yaml",
"testdata/fixtures/data-source.yaml",
},
libType: ftypes.Bundler,
args: args{ args: args{
pkgName: "activesupport", pkgName: "activesupport",
pkgVer: "4.1.1", pkgVer: "4.1.1",
@@ -91,6 +109,10 @@ func TestDriver_Detect(t *testing.T) {
PkgName: "activesupport", PkgName: "activesupport",
InstalledVersion: "4.1.1", InstalledVersion: "4.1.1",
FixedVersion: ">= 4.2.2, ~> 4.1.11", FixedVersion: ">= 4.2.2, ~> 4.1.11",
DataSource: &dbTypes.DataSource{
Name: "Ruby Advisory Database",
URL: "https://github.com/rubysec/ruby-advisory-db",
},
}, },
}, },
}, },

View File

@@ -5,20 +5,14 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa"
"github.com/aquasecurity/trivy/pkg/detector/library/comparer" "github.com/aquasecurity/trivy/pkg/detector/library/comparer"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
) )
// VulnSrc defines the operations on vulnerability source
type VulnSrc interface {
Get(pkgName string) ([]ghsa.Advisory, error)
}
// Advisory implements VulnSrc // Advisory implements VulnSrc
type Advisory struct { type Advisory struct {
vs VulnSrc vs ghsa.VulnSrc
comparer comparer.Comparer comparer comparer.Comparer
} }
@@ -39,8 +33,7 @@ func (s *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
var vulns []types.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, advisory := range advisories { for _, advisory := range advisories {
adv := dbTypes.Advisory{VulnerableVersions: advisory.VulnerableVersions} if !s.comparer.IsVulnerable(pkgVer, advisory) {
if !s.comparer.IsVulnerable(pkgVer, adv) {
continue continue
} }
@@ -49,6 +42,7 @@ func (s *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
PkgName: pkgName, PkgName: pkgName,
InstalledVersion: pkgVer, InstalledVersion: pkgVer,
FixedVersion: strings.Join(advisory.PatchedVersions, ", "), FixedVersion: strings.Join(advisory.PatchedVersions, ", "),
DataSource: advisory.DataSource,
} }
vulns = append(vulns, vuln) vulns = append(vulns, vuln)
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
ghsaSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa" ghsaSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa"
"github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/comparer" "github.com/aquasecurity/trivy/pkg/detector/library/comparer"
@@ -41,13 +42,20 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
pkgName: "symfony/symfony", pkgName: "symfony/symfony",
pkgVer: "5.1.5-alpha", pkgVer: "5.1.5-alpha",
}, },
fixtures: []string{"testdata/fixtures/ghsa.yaml"}, fixtures: []string{
"testdata/fixtures/ghsa.yaml",
"testdata/fixtures/data-source.yaml",
},
want: []types.DetectedVulnerability{ want: []types.DetectedVulnerability{
{ {
PkgName: "symfony/symfony", PkgName: "symfony/symfony",
InstalledVersion: "5.1.5-alpha", InstalledVersion: "5.1.5-alpha",
VulnerabilityID: "CVE-2020-15094", VulnerabilityID: "CVE-2020-15094",
FixedVersion: "5.1.5, 4.4.13", FixedVersion: "5.1.5, 4.4.13",
DataSource: &dbTypes.DataSource{
Name: "GitHub Security Advisory Composer",
URL: "https://github.com/advisories?query=type%%3Areviewed+ecosystem%%3Acomposer",
},
}, },
}, },
}, },
@@ -61,13 +69,20 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
pkgName: "AWSSDK.Core", pkgName: "AWSSDK.Core",
pkgVer: "3.5.1.30", pkgVer: "3.5.1.30",
}, },
fixtures: []string{"testdata/fixtures/ghsa.yaml"}, fixtures: []string{
"testdata/fixtures/ghsa.yaml",
"testdata/fixtures/data-source.yaml",
},
want: []types.DetectedVulnerability{ want: []types.DetectedVulnerability{
{ {
PkgName: "AWSSDK.Core", PkgName: "AWSSDK.Core",
InstalledVersion: "3.5.1.30", InstalledVersion: "3.5.1.30",
VulnerabilityID: "CVE-2020-99999", VulnerabilityID: "CVE-2020-99999",
FixedVersion: "3.5.1.31", FixedVersion: "3.5.1.31",
DataSource: &dbTypes.DataSource{
Name: "GitHub Security Advisory Nuget",
URL: "https://github.com/advisories?query=type%%3Areviewed+ecosystem%%3Anuget",
},
}, },
}, },
}, },

View File

@@ -0,0 +1,10 @@
- bucket: data-source
pairs:
- key: GitHub Security Advisory Composer
value:
Name: "GitHub Security Advisory Composer"
URL: "https://github.com/advisories?query=type%%3Areviewed+ecosystem%%3Acomposer"
- key: GitHub Security Advisory Nuget
value:
Name: "GitHub Security Advisory Nuget"
URL: "https://github.com/advisories?query=type%%3Areviewed+ecosystem%%3Anuget"

View File

@@ -5,7 +5,6 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/node" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/node"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
) )
@@ -33,8 +32,7 @@ func (a *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
var vulns []types.DetectedVulnerability var vulns []types.DetectedVulnerability
for _, advisory := range advisories { for _, advisory := range advisories {
adv := convertToGenericAdvisory(advisory) if !a.comparer.IsVulnerable(pkgVer, advisory) {
if !a.comparer.IsVulnerable(pkgVer, adv) {
continue continue
} }
@@ -43,30 +41,16 @@ func (a *Advisory) DetectVulnerabilities(pkgName, pkgVer string) ([]types.Detect
PkgName: pkgName, PkgName: pkgName,
InstalledVersion: pkgVer, InstalledVersion: pkgVer,
FixedVersion: createFixedVersions(advisory.PatchedVersions), FixedVersion: createFixedVersions(advisory.PatchedVersions),
DataSource: advisory.DataSource,
} }
vulns = append(vulns, vuln) vulns = append(vulns, vuln)
} }
return vulns, nil return vulns, nil
} }
func convertToGenericAdvisory(advisory node.Advisory) dbTypes.Advisory { func createFixedVersions(patchedVersions []string) string {
var vulnerable, patched []string
if advisory.VulnerableVersions != "" {
vulnerable = strings.Split(advisory.VulnerableVersions, "||")
}
if advisory.PatchedVersions != "" {
patched = strings.Split(advisory.PatchedVersions, "||")
}
return dbTypes.Advisory{
VulnerableVersions: vulnerable,
PatchedVersions: patched,
}
}
func createFixedVersions(patchedVersions string) string {
var fixedVersions []string var fixedVersions []string
for _, s := range strings.Split(patchedVersions, "||") { for _, s := range patchedVersions {
fixedVersions = append(fixedVersions, strings.TrimSpace(s)) fixedVersions = append(fixedVersions, strings.TrimSpace(s))
} }
return strings.Join(fixedVersions, ", ") return strings.Join(fixedVersions, ", ")

View File

@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/npm" "github.com/aquasecurity/trivy/pkg/detector/library/npm"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
@@ -30,13 +31,20 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
pkgName: "electron", pkgName: "electron",
pkgVer: "2.0.17", pkgVer: "2.0.17",
}, },
fixtures: []string{"testdata/fixtures/npm.yaml"}, fixtures: []string{
"testdata/fixtures/npm.yaml",
"testdata/fixtures/data-source.yaml",
},
want: []types.DetectedVulnerability{ want: []types.DetectedVulnerability{
{ {
PkgName: "electron", PkgName: "electron",
InstalledVersion: "2.0.17", InstalledVersion: "2.0.17",
VulnerabilityID: "CVE-2019-5786", VulnerabilityID: "CVE-2019-5786",
FixedVersion: "^2.0.18, ^3.0.16, ^3.1.6, ^4.0.8, ^5.0.0-beta.5", FixedVersion: "^2.0.18, ^3.0.16, ^3.1.6, ^4.0.8, ^5.0.0-beta.5",
DataSource: &dbTypes.DataSource{
Name: "Node.js Ecosystem Security Working Group",
URL: "https://github.com/nodejs/security-wg",
},
}, },
}, },
}, },
@@ -79,10 +87,9 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
require.NotNil(t, err) require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr) assert.Contains(t, err.Error(), tt.wantErr)
return return
} else {
assert.NoError(t, err)
} }
assert.NoError(t, err)
assert.Equal(t, tt.want, got) assert.Equal(t, tt.want, got)
}) })
} }

View File

@@ -0,0 +1,6 @@
- bucket: data-source
pairs:
- key: nodejs-security-wg
value:
Name: "Node.js Ecosystem Security Working Group"
URL: "https://github.com/nodejs/security-wg"

View File

@@ -4,5 +4,15 @@
pairs: pairs:
- key: CVE-2019-5786 - key: CVE-2019-5786
value: value:
PatchedVersions: "^2.0.18 || ^3.0.16 || ^3.1.6 || ^4.0.8 || ^5.0.0-beta.5" PatchedVersions:
VulnerableVersions: "<2.0.18 || <3.0.16 || <3.1.6 || <4.0.8 || <5.0.0-beta.5" - "^2.0.18"
- "^3.0.16"
- "^3.1.6"
- "^4.0.8"
- "^5.0.0-beta.5"
VulnerableVersions:
- "<2.0.18"
- "<3.0.16"
- "<3.1.6"
- "<4.0.8"
- "<5.0.0-beta.5"

View File

@@ -0,0 +1,14 @@
- bucket: data-source
pairs:
- key: composer::GitLab Advisory Database Community
value:
Name: "GitLab Advisory Database Community"
URL: "https://gitlab.com/gitlab-org/advisories-community"
- key: composer::php-security-advisories
value:
Name: "PHP Security Advisories Database"
URL: "https://github.com/FriendsOfPHP/security-advisories"
- key: rubygems::ruby-advisory-db
value:
Name: "Ruby Advisory Database"
URL: "https://github.com/rubysec/ruby-advisory-db"

View File

@@ -1,4 +1,4 @@
- bucket: "composer::GitHub Security Advisory Composer" - bucket: "composer::GitLab Advisory Database Community"
pairs: pairs:
- bucket: symfony/symfony - bucket: symfony/symfony
pairs: pairs:

View File

@@ -1,4 +1,4 @@
- bucket: "GitHub Security Advisory Rubygems" - bucket: "GitHub Security Advisory RubyGems"
pairs: pairs:
- bucket: rails - bucket: rails
pairs: pairs:

View File

@@ -17,6 +17,9 @@ type DetectedVulnerability struct {
SeveritySource string `json:",omitempty"` SeveritySource string `json:",omitempty"`
PrimaryURL string `json:",omitempty"` PrimaryURL string `json:",omitempty"`
// DataSource holds where the advisory comes from
DataSource *types.DataSource `json:",omitempty"`
// Custom is for extensibility and not supposed to be used in OSS // Custom is for extensibility and not supposed to be used in OSS
Custom interface{} `json:",omitempty"` Custom interface{} `json:",omitempty"`