Files
trivy/pkg/detector/library/driver.go
rahul2393 6eebed33b2 improve ruby comparison version check. (#552)
* Implemented ruby comparison version check.

* Added semver package to validate and check version

* Added more tests

* Replaced go-version with semver

* Removing go-version from dependency

* Added check for ruby gem version format

* Updated semver model and patch rewrite process

* Refactoring
2020-07-19 18:03:56 +03:00

113 lines
3.1 KiB
Go

package library
import (
"fmt"
"github.com/Masterminds/semver/v3"
"github.com/aquasecurity/fanal/analyzer/library"
ecosystem "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa"
"github.com/aquasecurity/trivy/pkg/detector/library/bundler"
"github.com/aquasecurity/trivy/pkg/detector/library/cargo"
"github.com/aquasecurity/trivy/pkg/detector/library/composer"
"github.com/aquasecurity/trivy/pkg/detector/library/ghsa"
"github.com/aquasecurity/trivy/pkg/detector/library/node"
"github.com/aquasecurity/trivy/pkg/detector/library/python"
"github.com/aquasecurity/trivy/pkg/types"
"golang.org/x/xerrors"
)
type Factory interface {
NewDriver(filename string) (Driver, error)
}
type advisory interface {
DetectVulnerabilities(string, *semver.Version) ([]types.DetectedVulnerability, error)
}
type DriverFactory struct{}
func (d DriverFactory) NewDriver(filename string) (Driver, error) {
// TODO: use DI
var driver Driver
switch filename {
case "Gemfile.lock":
driver = NewBundlerDriver()
case "Cargo.lock":
driver = NewCargoDriver()
case "composer.lock":
driver = NewComposerDriver()
case "package-lock.json":
driver = NewNpmDriver()
case "yarn.lock":
driver = NewYarnDriver()
case "Pipfile.lock":
driver = NewPipenvDriver()
case "poetry.lock":
driver = NewPoetryDriver()
default:
return Driver{}, xerrors.New(fmt.Sprintf("unsupport filename %s", filename))
}
return driver, nil
}
type Driver struct {
pkgManager string
advisories []advisory
}
func NewDriver(p string, advisories ...advisory) Driver {
return Driver{pkgManager: p, advisories: advisories}
}
func (driver *Driver) Detect(pkgName string, pkgVer *semver.Version) ([]types.DetectedVulnerability, error) {
var detectedVulnerabilities []types.DetectedVulnerability
uniqVulnIdMap := make(map[string]struct{})
for _, d := range driver.advisories {
vulns, err := d.DetectVulnerabilities(pkgName, pkgVer)
if err != nil {
return nil, xerrors.Errorf("failed to detect vulnerabilities: %w", err)
}
for _, vuln := range vulns {
if _, ok := uniqVulnIdMap[vuln.VulnerabilityID]; ok {
continue
}
uniqVulnIdMap[vuln.VulnerabilityID] = struct{}{}
detectedVulnerabilities = append(detectedVulnerabilities, vuln)
}
}
return detectedVulnerabilities, nil
}
func NewBundlerDriver() Driver {
return NewDriver(library.Bundler, ghsa.NewAdvisory(ecosystem.Rubygems), bundler.NewAdvisory())
}
func NewComposerDriver() Driver {
return NewDriver(library.Composer, ghsa.NewAdvisory(ecosystem.Composer), composer.NewAdvisory())
}
func NewCargoDriver() Driver {
return NewDriver(library.Cargo, cargo.NewAdvisory())
}
func NewNpmDriver() Driver {
return NewDriver(library.Npm, ghsa.NewAdvisory(ecosystem.Npm), node.NewAdvisory())
}
func NewYarnDriver() Driver {
return NewDriver(library.Yarn, ghsa.NewAdvisory(ecosystem.Npm), node.NewAdvisory())
}
func NewPipenvDriver() Driver {
return NewDriver(library.Pipenv, ghsa.NewAdvisory(ecosystem.Pip), python.NewAdvisory())
}
func NewPoetryDriver() Driver {
return NewDriver(library.Poetry, ghsa.NewAdvisory(ecosystem.Pip), python.NewAdvisory())
}
func (d *Driver) Type() string {
return d.pkgManager
}