Skip to content

Commit

Permalink
feat(dotnet): add support for .Net core .deps.json files (#2487)
Browse files Browse the repository at this point in the history
Co-authored-by: DmitriyLewen <[email protected]>
Co-authored-by: knqyf263 <[email protected]>
  • Loading branch information
3 people authored Jul 11, 2022
1 parent 56265a9 commit a6685b1
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 22 deletions.
41 changes: 21 additions & 20 deletions docs/docs/vulnerability/detection/language.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@

`Trivy` automatically detects the following files in the container and scans vulnerabilities in the application dependencies.

| Language | File | Image[^8] | Rootfs[^9] | Filesystem[^10] | Repository[^11] | Dev dependencies |
| -------- | ------------------------ | :-------: | :--------: | :-------------: | :-------------: | ---------------- |
| Ruby | Gemfile.lock | - | - ||| included |
| | gemspec ||| - | - | included |
| Python | Pipfile.lock | - | - ||| excluded |
| | poetry.lock | - | - ||| included |
| | requirements.txt | - | - ||| included |
| | egg package[^1] ||| - | - | excluded |
| | wheel package[^2] ||| - | - | excluded |
| PHP | composer.lock ||||| excluded |
| Node.js | package-lock.json | - | - ||| excluded |
| | yarn.lock | - | - ||| included |
| | pnpm-lock.yaml | - | - ||| excluded |
| | package.json ||| - | - | excluded |
| .NET | packages.lock.json ||||| included |
| | packages.config ||||| excluded |
| Java | JAR/WAR/PAR/EAR[^3][^4] ||| - | - | included |
| | pom.xml[^5] | - | - ||| excluded |
| Language | File | Image[^8] | Rootfs[^9] | Filesystem[^10] | Repository[^11] | Dev dependencies |
| -------- |-------------------------| :-------: | :--------: | :-------------: | :-------------: | ---------------- |
| Ruby | Gemfile.lock | - | - ||| included |
| | gemspec ||| - | - | included |
| Python | Pipfile.lock | - | - ||| excluded |
| | poetry.lock | - | - ||| included |
| | requirements.txt | - | - ||| included |
| | egg package[^1] ||| - | - | excluded |
| | wheel package[^2] ||| - | - | excluded |
| PHP | composer.lock ||||| excluded |
| Node.js | package-lock.json | - | - ||| excluded |
| | yarn.lock | - | - ||| included |
| | pnpm-lock.yaml | - | - ||| excluded |
| | package.json ||| - | - | excluded |
| .NET | packages.lock.json ||||| included |
| | packages.config ||||| excluded |
| | .deps.json ||||| excluded |
| Java | JAR/WAR/PAR/EAR[^3][^4] ||| - | - | included |
| | pom.xml[^5] | - | - ||| excluded |
| Go | Binaries built by Go[^6] ||| - | - | excluded |
| | go.mod[^7] | - | - ||| included |
| Rust | Cargo.lock ||||| included |
| | go.mod[^7] | - | - ||| included |
| Rust | Cargo.lock ||||| included |

The path of these files does not matter.

Expand Down
2 changes: 1 addition & 1 deletion pkg/detector/library/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func NewDriver(libType string) (Driver, error) {
case ftypes.Npm, ftypes.Yarn, ftypes.Pnpm, ftypes.NodePkg, ftypes.JavaScript:
ecosystem = vulnerability.Npm
comparer = npm.Comparer{}
case ftypes.NuGet:
case ftypes.NuGet, ftypes.DotNetCore:
ecosystem = vulnerability.NuGet
comparer = compare.GenericComparer{}
case ftypes.Pipenv, ftypes.Poetry, ftypes.Pip, ftypes.PythonPkg:
Expand Down
1 change: 1 addition & 0 deletions pkg/fanal/analyzer/all/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package all
import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/buildinfo"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/command/apk"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/deps"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/mod"
Expand Down
3 changes: 2 additions & 1 deletion pkg/fanal/analyzer/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ const (
TypePnpm Type = "pnpm"

// .NET
TypeNuget Type = "nuget"
TypeNuget Type = "nuget"
TypeDotNetDeps Type = "dotnet-deps"

// Python
TypePythonPkg Type = "python-pkg"
Expand Down
47 changes: 47 additions & 0 deletions pkg/fanal/analyzer/language/dotnet/deps/deps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package deps

import (
"context"
"os"
"strings"

"golang.org/x/xerrors"

core "github.com/aquasecurity/go-dep-parser/pkg/dotnet/core_deps"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
"github.com/aquasecurity/trivy/pkg/fanal/types"
)

func init() {
analyzer.RegisterAnalyzer(&depsLibraryAnalyzer{})
}

const (
version = 1
depsExtension = ".deps.json"
)

type depsLibraryAnalyzer struct{}

func (a depsLibraryAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
parser := core.NewParser()
res, err := language.Analyze(types.DotNetCore, input.FilePath, input.Content, parser)
if err != nil {
return nil, xerrors.Errorf(".Net Core dependencies analysis error: %w", err)
}

return res, nil
}

func (a depsLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return strings.HasSuffix(filePath, depsExtension)
}

func (a depsLibraryAnalyzer) Type() analyzer.Type {
return analyzer.TypeDotNetDeps
}

func (a depsLibraryAnalyzer) Version() int {
return version
}
95 changes: 95 additions & 0 deletions pkg/fanal/analyzer/language/dotnet/deps/deps_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package deps

import (
"context"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/types"
)

func Test_depsLibraryAnalyzer_Analyze(t *testing.T) {
tests := []struct {
name string
inputFile string
want *analyzer.AnalysisResult
wantErr string
}{
{
name: "happy path",
inputFile: "testdata/datacollector.deps.json",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
Type: types.DotNetCore,
FilePath: "testdata/datacollector.deps.json",
Libraries: []types.Package{
{
Name: "Newtonsoft.Json",
Version: "9.0.1",
},
},
},
},
},
},
{
name: "sad path",
inputFile: "testdata/invalid.txt",
wantErr: ".Net Core dependencies analysis error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f, err := os.Open(tt.inputFile)
require.NoError(t, err)
defer f.Close()

a := depsLibraryAnalyzer{}
ctx := context.Background()
got, err := a.Analyze(ctx, analyzer.AnalysisInput{
FilePath: tt.inputFile,
Content: f,
})

if tt.wantErr != "" {
require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr)
return
}

assert.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}

func Test_depsLibraryAnalyzer_Required(t *testing.T) {
tests := []struct {
name string
filePath string
want bool
}{
{
name: "config",
filePath: "test/datacollector.deps.json",
want: true,
},
{
name: "zip",
filePath: "test.zip",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := depsLibraryAnalyzer{}
got := a.Required(tt.filePath, nil)
assert.Equal(t, tt.want, got)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v2.1",
"signature": ""
},
"compilationOptions": {},
"libraries": {
"Newtonsoft.Json/9.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==",
"path": "newtonsoft.json/9.0.1",
"hashPath": "newtonsoft.json.9.0.1.nupkg.sha512"
},
"Microsoft.VisualStudio.TestPlatform.Common/17.2.0-release-20220408-11": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
1 change: 1 addition & 0 deletions pkg/fanal/types/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
Composer = "composer"
Npm = "npm"
NuGet = "nuget"
DotNetCore = "dotnet-core"
Pip = "pip"
Pipenv = "pipenv"
Poetry = "poetry"
Expand Down

0 comments on commit a6685b1

Please sign in to comment.