Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: NuGet Scanner #686

Merged
merged 11 commits into from
Dec 21, 2020
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ See [here](#continuous-integration-ci) for details.

- Detect comprehensive vulnerabilities
- OS packages (Alpine, **Red Hat Universal Base Image**, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
- **Application dependencies** (Bundler, Composer, Pipenv, Poetry, npm, yarn and Cargo)
- **Application dependencies** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo and NuGet)
- Simple
- Specify only an image name or artifact name
- See [Quick Start](#quick-start) and [Examples](#examples)
Expand Down Expand Up @@ -1701,6 +1701,8 @@ Distroless: https://github.com/GoogleContainerTools/distroless
- yarn.lock
- Rust
- Cargo.lock
- .NET
- packages.lock.json

The path of these files does not matter.

Expand Down Expand Up @@ -1732,6 +1734,8 @@ Trivy scans a tar image with the following format.
- https://github.com/advisories?query=ecosystem%3Anpm
- Rust
- https://github.com/RustSec/advisory-db
- .NET
- https://github.com/advisories?query=ecosystem%3Anuget

# Usage
Trivy has several sub commands, image, fs, repo, client and server.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
github.com/aquasecurity/go-version v0.0.0-20201115065329-578079e4ab05
github.com/aquasecurity/trivy-db v0.0.0-20201117092632-b09c30858fc2
github.com/aquasecurity/trivy-db v0.0.0-20201221070121-47d2cc0d7b58
github.com/caarlos0/env/v6 v6.0.0
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cheggaaa/pb/v3 v3.0.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ github.com/aquasecurity/go-version v0.0.0-20201115065329-578079e4ab05 h1:q0ZpFBj
github.com/aquasecurity/go-version v0.0.0-20201115065329-578079e4ab05/go.mod h1:9Beu8XsUNNfzml7WBf3QmyPToP1wm1Gj/Vc5UJKqTzU=
github.com/aquasecurity/testdocker v0.0.0-20200426142840-5f05bce6f12a h1:hsw7PpiymXP64evn/K7gsj3hWzMqLrdoeE6JkqDocVg=
github.com/aquasecurity/testdocker v0.0.0-20200426142840-5f05bce6f12a/go.mod h1:psfu0MVaiTDLpNxCoNsTeILSKY2EICBwv345f3M+Ffs=
github.com/aquasecurity/trivy-db v0.0.0-20201117092632-b09c30858fc2 h1:AXA9aW464copH1GTKv35yCwztJsqDVZWKfCtBuMpI9U=
github.com/aquasecurity/trivy-db v0.0.0-20201117092632-b09c30858fc2/go.mod h1:+3+NEz0U0NCgO87Cyk0dy3SwH7CI6J4HUeCqqPj1fvQ=
github.com/aquasecurity/trivy-db v0.0.0-20201221070121-47d2cc0d7b58 h1:TQXXGc1pi2gdRhQYZxib3xBoV64ORC7yllCndZkrf80=
github.com/aquasecurity/trivy-db v0.0.0-20201221070121-47d2cc0d7b58/go.mod h1:+3+NEz0U0NCgO87Cyk0dy3SwH7CI6J4HUeCqqPj1fvQ=
github.com/aquasecurity/vuln-list-update v0.0.0-20191016075347-3d158c2bf9a2 h1:xbdUfr2KE4THsFx9CFWtWpU91lF+YhgP46moV94nYTA=
github.com/aquasecurity/vuln-list-update v0.0.0-20191016075347-3d158c2bf9a2/go.mod h1:6NhOP0CjZJL27bZZcaHECtzWdwDDm2g6yCY0QgXEGQQ=
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
Expand Down
7 changes: 7 additions & 0 deletions pkg/detector/library/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func (d DriverFactory) NewDriver(filename string) (Driver, error) {
driver = newNpmDriver()
case "Pipfile.lock", "poetry.lock":
driver = newPipDriver()
case "packages.lock.json":
driver = newNugetDriver()
default:
return Driver{}, xerrors.New(fmt.Sprintf("unsupport filename %s", filename))
}
Expand Down Expand Up @@ -114,3 +116,8 @@ func newPipDriver() Driver {
return NewDriver(ghsa.NewAdvisory(ecosystem.Pip, c), python.NewAdvisory(),
NewAdvisory(vulnerability.Pip, c))
}

func newNugetDriver() Driver {
c := comparer.GenericComparer{}
return NewDriver(ghsa.NewAdvisory(ecosystem.Nuget, c), NewAdvisory(vulnerability.NuGet, c))
}
22 changes: 21 additions & 1 deletion pkg/detector/library/ghsa/advisory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
wantErr string
}{
{
name: "detected",
name: "composer detected",
fields: fields{
ecosystem: ghsaSrc.Composer,
comparer: comparer.GenericComparer{},
Expand All @@ -52,6 +52,26 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
},
},
},
{
name: "nuget detected",
fields: fields{
ecosystem: ghsaSrc.Nuget,
comparer: comparer.GenericComparer{},
},
args: args{
pkgName: "AWSSDK.Core",
pkgVer: "3.5.1.30",
},
fixtures: []string{"testdata/fixtures/ghsa.yaml"},
want: []types.DetectedVulnerability{
{
PkgName: "AWSSDK.Core",
InstalledVersion: "3.5.1.30",
VulnerabilityID: "CVE-2020-99999",
FixedVersion: "3.5.1.31",
},
},
},
{
name: "not detected",
fields: fields{
Expand Down
12 changes: 11 additions & 1 deletion pkg/detector/library/ghsa/testdata/fixtures/ghsa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@
- 4.4.13
VulnerableVersions:
- ">= 5.0.0, < 5.1.5"
- ">= 4.4.0, < 4.4.13"
- ">= 4.4.0, < 4.4.13"
- bucket: GitHub Security Advisory Nuget
pairs:
- bucket: "AWSSDK.Core"
pairs:
- key: CVE-2020-99999
value:
PatchedVersions:
- 3.5.1.31
VulnerableVersions:
- ">= 3.0.0, < 3.5.1.31"
1 change: 1 addition & 0 deletions pkg/scanner/local/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
_ "github.com/aquasecurity/fanal/analyzer/library/cargo"
_ "github.com/aquasecurity/fanal/analyzer/library/composer"
_ "github.com/aquasecurity/fanal/analyzer/library/npm"
_ "github.com/aquasecurity/fanal/analyzer/library/nuget"
_ "github.com/aquasecurity/fanal/analyzer/library/pipenv"
_ "github.com/aquasecurity/fanal/analyzer/library/poetry"
_ "github.com/aquasecurity/fanal/analyzer/library/yarn"
Expand Down
43 changes: 25 additions & 18 deletions pkg/vulnerability/vulnerability.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,29 +73,36 @@ func (c Client) FillInfo(vulns []types.DetectedVulnerability, reportType string)
continue
}

var source string
switch reportType {
case vulnerability.Ubuntu, vulnerability.Alpine, vulnerability.RedHat, vulnerability.RedHatOVAL, vulnerability.Debian, vulnerability.DebianOVAL, vulnerability.Fedora, vulnerability.Amazon, vulnerability.OracleOVAL, vulnerability.SuseCVRF, vulnerability.OpenSuseCVRF, vulnerability.Photon:
source = reportType
case vulnerability.CentOS: // CentOS doesn't have its own so we use RedHat
source = vulnerability.RedHat
case "npm", "yarn":
source = vulnerability.NodejsSecurityWg
case "pipenv", "poetry":
source = vulnerability.PythonSafetyDB
case "bundler":
source = vulnerability.RubySec
case "cargo":
source = vulnerability.RustSec
case "composer":
source = vulnerability.PhpSecurityAdvisories
}

source := c.detectSource(reportType)
vulns[i].Severity, vulns[i].SeveritySource = c.getVendorSeverity(&vulns[i], source)
vulns[i].PrimaryURL = c.getPrimaryURL(vulns[i].VulnerabilityID, vulns[i].References, source)
vulns[i].Vulnerability.VendorSeverity = nil // Remove VendorSeverity from Results
}
}
func (c Client) detectSource(reportType string) string {
var source string
switch reportType {
case vulnerability.Ubuntu, vulnerability.Alpine, vulnerability.RedHat, vulnerability.RedHatOVAL,
vulnerability.Debian, vulnerability.DebianOVAL, vulnerability.Fedora, vulnerability.Amazon,
vulnerability.OracleOVAL, vulnerability.SuseCVRF, vulnerability.OpenSuseCVRF, vulnerability.Photon:
source = reportType
case vulnerability.CentOS: // CentOS doesn't have its own so we use RedHat
source = vulnerability.RedHat
case "npm", "yarn":
source = vulnerability.NodejsSecurityWg
case "nuget":
source = vulnerability.GHSANuget
case "pipenv", "poetry":
source = vulnerability.PythonSafetyDB
case "bundler":
source = vulnerability.RubySec
case "cargo":
source = vulnerability.RustSec
case "composer":
source = vulnerability.PhpSecurityAdvisories
}
return source
}

func (c Client) getVendorSeverity(vuln *types.DetectedVulnerability, source string) (string, string) {
if vs, ok := vuln.VendorSeverity[source]; ok {
Expand Down