Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add syft v0.46.0 Dotnet support (#747)
  • Loading branch information
ckotzbauer committed May 13, 2022
1 parent d6196b6 commit 731abaa
Show file tree
Hide file tree
Showing 13 changed files with 263 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -38,6 +38,7 @@ A vulnerability scanner for container images and filesystems. Easily [install th
- Java (JAR, WAR, EAR, JPI, HPI)
- JavaScript (NPM, Yarn)
- Python (Egg, Wheel, Poetry, requirements.txt/setup.py files)
- Dotnet (deps.json)
- Supports Docker and OCI image formats
- Consume SBOM [attestations](https://github.com/anchore/syft#sbom-attestation).

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Expand Up @@ -9,9 +9,9 @@ require (
github.com/adrg/xdg v0.2.1
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
github.com/anchore/packageurl-go v0.1.1-0.20220314153042-1bcd40e5206b
github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7
github.com/anchore/stereoscope v0.0.0-20220406160859-c03a18a6b270
github.com/anchore/syft v0.45.1
github.com/anchore/syft v0.46.0
github.com/bmatcuk/doublestar/v2 v2.0.4
github.com/docker/docker v20.10.12+incompatible
github.com/dustin/go-humanize v1.0.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Expand Up @@ -256,12 +256,12 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE+o2gozGEBoUMpX27lsku+xrMwlmBZJtbg=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
github.com/anchore/packageurl-go v0.1.1-0.20220314153042-1bcd40e5206b h1:YJWYt/6KQXR9JR46lLHrTTYi8rcye42tKcyjREA/hvA=
github.com/anchore/packageurl-go v0.1.1-0.20220314153042-1bcd40e5206b/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7 h1:kDrYkTSM9uIxaX/P9s0F4nKYNM+hnSgLJdLpqvsaQ/g=
github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.0-20220406160859-c03a18a6b270 h1:NmxPDR6vo3xjwCL6o+tpF1vUad/BVo+WaVSwueB9W9w=
github.com/anchore/stereoscope v0.0.0-20220406160859-c03a18a6b270/go.mod h1:yoCLUZY0k/pYLNIy0L80p2Ko0PKVNXm8rHtgxp4OiSc=
github.com/anchore/syft v0.45.1 h1:94x+ROBCZbtduYf+J+yu+MMG4YREfFpTW+MnCSlpQ3c=
github.com/anchore/syft v0.45.1/go.mod h1:/vnLTaFDHPGhizPbIgAyeTPjCY9Mzz255w84vVGGkEE=
github.com/anchore/syft v0.46.0 h1:zXgLbCvQgO/ER9dJOUdjvKrZivZQtPd2q+OcXVZuoYM=
github.com/anchore/syft v0.46.0/go.mod h1:rRBTv3k0Rlr82R2TRZnfv1YpsMq9OuzU4ARarjqgCbY=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
Expand Down
2 changes: 2 additions & 0 deletions grype/db/v3/namespace.go
Expand Up @@ -91,6 +91,8 @@ func NamespacePackageNamersForLanguage(l syftPkg.Language) map[string]NamerByPac
namespaces["github:npm"] = defaultPackageNamer
case syftPkg.Python:
namespaces["github:python"] = defaultPackageNamer
case syftPkg.Dotnet:
namespaces["github:nuget"] = defaultPackageNamer
default:
namespaces[fmt.Sprintf("github:%s", l)] = defaultPackageNamer
}
Expand Down
13 changes: 13 additions & 0 deletions grype/db/v3/namespace_test.go
Expand Up @@ -312,6 +312,19 @@ func Test_NamespacesForLanguage(t *testing.T) {
"a-name",
},
},
{
language: syftPkg.Dotnet,
namerInput: &pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "a-name",
},
expectedNamespaces: []string{
"github:nuget",
},
expectedNames: []string{
"a-name",
},
},
}

observedLanguages := strset.New()
Expand Down
2 changes: 2 additions & 0 deletions grype/match/matcher_type.go
Expand Up @@ -9,6 +9,7 @@ const (
RpmDBMatcher MatcherType = "rpmdb-matcher"
JavaMatcher MatcherType = "java-matcher"
PythonMatcher MatcherType = "python-matcher"
DotnetMatcher MatcherType = "dotnet-matcher"
JavascriptMatcher MatcherType = "javascript-matcher"
MsrcMatcher MatcherType = "msrc-matcher"
)
Expand All @@ -20,6 +21,7 @@ var AllMatcherTypes = []MatcherType{
RpmDBMatcher,
JavaMatcher,
PythonMatcher,
DotnetMatcher,
JavascriptMatcher,
MsrcMatcher,
}
Expand Down
25 changes: 25 additions & 0 deletions grype/matcher/dotnet/matcher.go
@@ -0,0 +1,25 @@
package dotnet

import (
"github.com/anchore/grype/grype/distro"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/search"
"github.com/anchore/grype/grype/vulnerability"
syftPkg "github.com/anchore/syft/syft/pkg"
)

type Matcher struct {
}

func (m *Matcher) PackageTypes() []syftPkg.Type {
return []syftPkg.Type{syftPkg.DotnetPkg}
}

func (m *Matcher) Type() match.MatcherType {
return match.DotnetMatcher
}

func (m *Matcher) Match(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
return search.ByCriteria(store, d, p, m.Type(), search.CommonCriteria...)
}
2 changes: 2 additions & 0 deletions grype/matcher/matchers.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/anchore/grype/grype/event"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/matcher/apk"
"github.com/anchore/grype/grype/matcher/dotnet"
"github.com/anchore/grype/grype/matcher/dpkg"
"github.com/anchore/grype/grype/matcher/java"
"github.com/anchore/grype/grype/matcher/javascript"
Expand Down Expand Up @@ -39,6 +40,7 @@ func NewDefaultMatchers(mc Config) []Matcher {
&dpkg.Matcher{},
&ruby.Matcher{},
&python.Matcher{},
&dotnet.Matcher{},
&rpmdb.Matcher{},
java.NewJavaMatcher(mc.Java),
&javascript.Matcher{},
Expand Down
13 changes: 13 additions & 0 deletions grype/pkg/package_test.go
Expand Up @@ -261,6 +261,19 @@ func TestNew(t *testing.T) {
},
},
},
{
name: "dotnet-metadata",
syftPkg: syftPkg.Package{
MetadataType: syftPkg.DotnetDepsMetadataType,
Metadata: syftPkg.DotnetDepsMetadata{
Name: "a",
Version: "a",
Path: "a",
Sha512: "a",
HashPath: "a",
},
},
},
}

// capture each observed metadata type, we should see all of them relate to what syft provides by the end of testing
Expand Down
1 change: 1 addition & 0 deletions test/integration/compare_sbom_input_vs_lib_test.go
Expand Up @@ -51,6 +51,7 @@ func TestCompareSBOMInputToLibResults(t *testing.T) {
string(syftPkg.RustPkg),
string(syftPkg.KbPkg),
string(syftPkg.DartPubPkg),
string(syftPkg.DotnetPkg),
string(syftPkg.PhpComposerPkg),
string(syftPkg.JenkinsPluginPkg), // package type cannot be inferred for all formats
)
Expand Down
9 changes: 9 additions & 0 deletions test/integration/db_mock_test.go
Expand Up @@ -90,6 +90,15 @@ func newMockDbStore() *mockStore {
},
},
},
"github:nuget": {
"AWSSDK.Core": []grypeDB.Vulnerability{
{
ID: "CVE-dotnet-sample",
VersionConstraint: ">= 3.7.0.0, < 3.7.12.0",
VersionFormat: "dotnet",
},
},
},
"debian:8": {
"apt-dev": []grypeDB.Vulnerability{
{
Expand Down
36 changes: 36 additions & 0 deletions test/integration/match_by_image_test.go
Expand Up @@ -120,6 +120,41 @@ func addPythonMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Ca
})
}

func addDotnetMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Catalog, theStore *mockStore, theResult *match.Matches) {
packages := catalog.PackagesByPath("/dotnet/TestLibrary.deps.json")
if len(packages) != 1 {
for _, p := range packages {
t.Logf("Dotnet Package: %s %+v", p.ID(), p)
}

t.Fatalf("problem with upstream syft cataloger (dotnet)")
}
thePkg := pkg.New(packages[0])
theVuln := theStore.backend["github:nuget"][thePkg.Name][0]
vulnObj, err := vulnerability.NewVulnerability(theVuln)
if err != nil {
t.Fatalf("failed to create vuln obj: %+v", err)
}
theResult.Add(match.Match{

Vulnerability: *vulnObj,
Package: thePkg,
Details: []match.Detail{
{
Type: match.ExactDirectMatch,
Confidence: 1.0,
SearchedBy: map[string]interface{}{
"language": "dotnet",
},
Found: map[string]interface{}{
"constraint": ">= 3.7.0.0, < 3.7.12.0 (dotnet)",
},
Matcher: match.DotnetMatcher,
},
},
})
}

func addRubyMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Catalog, theStore *mockStore, theResult *match.Matches) {
packages := catalog.PackagesByPath("/ruby/specifications/bundler.gemspec")
if len(packages) != 1 {
Expand Down Expand Up @@ -320,6 +355,7 @@ func TestMatchByImage(t *testing.T) {
addJavaMatches(t, theSource, catalog, theStore, &expectedMatches)
addDpkgMatches(t, theSource, catalog, theStore, &expectedMatches)
addJavascriptMatches(t, theSource, catalog, theStore, &expectedMatches)
addDotnetMatches(t, theSource, catalog, theStore, &expectedMatches)
return expectedMatches
},
},
Expand Down
@@ -0,0 +1,153 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"TestLibrary/1.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "6.0.0",
"Microsoft.Extensions.Logging": "6.0.0",
"Newtonsoft.Json": "13.0.1",
"Serilog": "2.10.0",
"Serilog.Sinks.Console": "4.0.1",
"TestCommon": "1.0.0"
},
"runtime": {
"TestLibrary.dll": {}
}
},
"AWSSDK.Core/3.7.10.6": {
"runtime": {
"lib/netcoreapp3.1/AWSSDK.Core.dll": {
"assemblyVersion": "3.3.0.0",
"fileVersion": "3.7.10.6"
}
}
},
"Microsoft.Extensions.DependencyInjection/6.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
},
"runtime": {
"lib/net6.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/6.0.0": {
"runtime": {
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Logging/6.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "6.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
"Microsoft.Extensions.Logging.Abstractions": "6.0.0",
"Microsoft.Extensions.Options": "6.0.0",
"System.Diagnostics.DiagnosticSource": "6.0.0"
},
"runtime": {
"lib/netstandard2.1/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/6.0.0": {
"runtime": {
"lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Options/6.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
"Microsoft.Extensions.Primitives": "6.0.0"
},
"runtime": {
"lib/netstandard2.1/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.Extensions.Primitives/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
},
"runtime": {
"lib/net6.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Newtonsoft.Json/13.0.1": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.1.25517"
}
}
},
"Serilog/2.10.0": {
"runtime": {
"lib/netstandard2.1/Serilog.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.10.0.0"
}
}
},
"Serilog.Sinks.Console/4.0.1": {
"dependencies": {
"Serilog": "2.10.0"
},
"runtime": {
"lib/net5.0/Serilog.Sinks.Console.dll": {
"assemblyVersion": "4.0.1.0",
"fileVersion": "4.0.1.0"
}
}
},
"System.Diagnostics.DiagnosticSource/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {},
"TestCommon/1.0.0": {
"dependencies": {
"AWSSDK.Core": "3.7.10.6"
},
"runtime": {
"TestCommon.dll": {}
}
}
}
},
"libraries": {
"TestLibrary/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"AWSSDK.Core/3.7.10.6": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kHBB+QmosVaG6DpngXQ8OlLVVNMzltNITfsRr68Z90qO7dSqJ2EHNd8dtBU1u3AQQLqqFHOY0lfmbpexeH6Pew==",
"path": "awssdk.core/3.7.10.6",
"hashPath": "awssdk.core.3.7.10.6.nupkg.sha512"
}
}
}

0 comments on commit 731abaa

Please sign in to comment.