From f5c3b7c620221f1aaf4ddc3dc5454031b303ee10 Mon Sep 17 00:00:00 2001 From: AMF Date: Sun, 10 Jul 2022 13:24:33 +0600 Subject: [PATCH 1/6] initial From 3d1f7fa236d3d339f6999b70692facd5f0542325 Mon Sep 17 00:00:00 2001 From: AMF Date: Sun, 10 Jul 2022 13:35:58 +0600 Subject: [PATCH 2/6] replcace code --- pkg/fanal/analyzer/all/import.go | 1 + pkg/fanal/analyzer/const.go | 3 +- .../analyzer/language/dotnet/deps/deps.go | 49 +++++++++++++++++++ pkg/fanal/types/const.go | 1 + 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 pkg/fanal/analyzer/language/dotnet/deps/deps.go diff --git a/pkg/fanal/analyzer/all/import.go b/pkg/fanal/analyzer/all/import.go index fa36fb6c144e..27a8d442f216 100644 --- a/pkg/fanal/analyzer/all/import.go +++ b/pkg/fanal/analyzer/all/import.go @@ -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" diff --git a/pkg/fanal/analyzer/const.go b/pkg/fanal/analyzer/const.go index 0f33598c439d..3476210d5d25 100644 --- a/pkg/fanal/analyzer/const.go +++ b/pkg/fanal/analyzer/const.go @@ -56,7 +56,8 @@ const ( TypePnpm Type = "pnpm" // .NET - TypeNuget Type = "nuget" + TypeNuget Type = "nuget" + TypeDotNetDeps Type = "dotnet-deps" // Python TypePythonPkg Type = "python-pkg" diff --git a/pkg/fanal/analyzer/language/dotnet/deps/deps.go b/pkg/fanal/analyzer/language/dotnet/deps/deps.go new file mode 100644 index 000000000000..dabb338fd592 --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/deps/deps.go @@ -0,0 +1,49 @@ +package deps + +import ( + "context" + "os" + "strings" + + "golang.org/x/xerrors" + + "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) { + // Set the default parser + parser := core_deps.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 +} diff --git a/pkg/fanal/types/const.go b/pkg/fanal/types/const.go index 1c1592872523..bfd61826af76 100644 --- a/pkg/fanal/types/const.go +++ b/pkg/fanal/types/const.go @@ -13,6 +13,7 @@ const ( Composer = "composer" Npm = "npm" NuGet = "nuget" + DotNetCore = "dotnet-core" Pip = "pip" Pipenv = "pipenv" Poetry = "poetry" From 28098b2882048c6ebcf2a9baeac7ceb772883f8b Mon Sep 17 00:00:00 2001 From: AMF Date: Sun, 10 Jul 2022 13:46:57 +0600 Subject: [PATCH 3/6] add DotNetCore driver --- pkg/detector/library/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/detector/library/driver.go b/pkg/detector/library/driver.go index 03826fbb40f9..561b83d22e83 100644 --- a/pkg/detector/library/driver.go +++ b/pkg/detector/library/driver.go @@ -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: From e27ae81ce5c9fe58b84a65a800f774cc90cc9550 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Mon, 11 Jul 2022 11:50:58 +0600 Subject: [PATCH 4/6] test: add tests for DotNetCore --- .../language/dotnet/deps/deps_test.go | 94 +++++++++++++++++++ .../deps/testdata/datacollector.deps.json | 21 +++++ .../language/dotnet/deps/testdata/invalid.txt | 1 + 3 files changed, 116 insertions(+) create mode 100644 pkg/fanal/analyzer/language/dotnet/deps/deps_test.go create mode 100644 pkg/fanal/analyzer/language/dotnet/deps/testdata/datacollector.deps.json create mode 100644 pkg/fanal/analyzer/language/dotnet/deps/testdata/invalid.txt diff --git a/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go b/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go new file mode 100644 index 000000000000..8f63195c2344 --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go @@ -0,0 +1,94 @@ +package deps + +import ( + "context" + "os" + "testing" + + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" + "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +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) + }) + } +} diff --git a/pkg/fanal/analyzer/language/dotnet/deps/testdata/datacollector.deps.json b/pkg/fanal/analyzer/language/dotnet/deps/testdata/datacollector.deps.json new file mode 100644 index 000000000000..08699fee4a7a --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/deps/testdata/datacollector.deps.json @@ -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": "" + } + } +} \ No newline at end of file diff --git a/pkg/fanal/analyzer/language/dotnet/deps/testdata/invalid.txt b/pkg/fanal/analyzer/language/dotnet/deps/testdata/invalid.txt new file mode 100644 index 000000000000..9daeafb9864c --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/deps/testdata/invalid.txt @@ -0,0 +1 @@ +test From 067cb79065f26ef3b33da33d1a36b81a9a17590e Mon Sep 17 00:00:00 2001 From: knqyf263 Date: Mon, 11 Jul 2022 10:37:56 +0300 Subject: [PATCH 5/6] refactor: tweaks --- pkg/fanal/analyzer/language/dotnet/deps/deps.go | 6 ++---- pkg/fanal/analyzer/language/dotnet/deps/deps_test.go | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pkg/fanal/analyzer/language/dotnet/deps/deps.go b/pkg/fanal/analyzer/language/dotnet/deps/deps.go index dabb338fd592..4fb4a6260cb3 100644 --- a/pkg/fanal/analyzer/language/dotnet/deps/deps.go +++ b/pkg/fanal/analyzer/language/dotnet/deps/deps.go @@ -7,7 +7,7 @@ import ( "golang.org/x/xerrors" - "github.com/aquasecurity/go-dep-parser/pkg/dotnet/core_deps" + 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" @@ -25,9 +25,7 @@ const ( type depsLibraryAnalyzer struct{} func (a depsLibraryAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) { - // Set the default parser - parser := core_deps.NewParser() - + 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) diff --git a/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go b/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go index 8f63195c2344..5b70810f93bb 100644 --- a/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go +++ b/pkg/fanal/analyzer/language/dotnet/deps/deps_test.go @@ -5,10 +5,11 @@ import ( "os" "testing" - "github.com/aquasecurity/trivy/pkg/fanal/analyzer" - "github.com/aquasecurity/trivy/pkg/fanal/types" "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) { From 591022492631f4b7fc7e1d110fc9f1e124e71275 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Mon, 11 Jul 2022 14:33:16 +0600 Subject: [PATCH 6/6] docs: add .deps.json in docs --- docs/docs/vulnerability/detection/language.md | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/docs/docs/vulnerability/detection/language.md b/docs/docs/vulnerability/detection/language.md index 45bd39d12c17..bcfcfe8f26fd 100644 --- a/docs/docs/vulnerability/detection/language.md +++ b/docs/docs/vulnerability/detection/language.md @@ -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.