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(fs): add --max-file-size flag to skip the files greater than a particular size #7304

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions docs/docs/analyzers/analyzers.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add this page to docs.
Update mkdocs.yml for that.

But i am not sure about place for this page.
I think we can add this page to References.
@knqyf263 wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sounds good

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

## Analyzers
Use the following types of analyzers for the [--max-file-size] and [--file-pattern] flags
```
fedora
apk
sbom
packages-props
node-pkg
composer-vendor
rustbinary
cocoapods
redhat-content-manifest
redhat-dockerfile
pom
amazon
alma
os-release
dpkg-license
rpmqa
executable
mix-lock
gemspec
swift
debian
rocky
gobinary
centos
ubuntu
apk-repo
conda-environment
conda-pkg
bundler
alpine
oracle
rpm
dotnet-core
pipenv
license-file
redhat
ubuntu-esm
sbt-lockfile
secret
dockerfile
kubernetes
python-pkg
dpkg
cloudformation
terraformplan-json
conan-lock
jar
npm
pnpm
poetry
terraformplan-snapshot
pubspec-lock
nuget
gomod
gradle-lockfile
composer
azure-arm
helm
terraform
julia
yarn
pip
cargo
```
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ require (
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/iam v1.1.6 // indirect
cloud.google.com/go/storage v1.39.1 // indirect
cuelang.org/go v0.9.2 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,11 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e h1:GwCVItFUPxwdsEYnlUcJ6PJxOjTeFFCKOh6QWg4oAzQ=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e/go.mod h1:ApHceQLLwcOkCEXM1+DyCXTHEJhNGDpJ2kmV6axsx24=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w=
cuelang.org/go v0.8.1 h1:VFYsxIFSPY5KgSaH1jQ2GxHOrbu6Ga3kEI70yCZwnOg=
cuelang.org/go v0.8.1/go.mod h1:CoDbYolfMms4BhWUlhD+t5ORnihR7wvjcfgyO9lL5FI=
cuelang.org/go v0.9.2 h1:pfNiry2PdRBr02G/aKm5k2vhzmqbAOoaB4WurmEbWvs=
cuelang.org/go v0.9.2/go.mod h1:qpAYsLOf7gTM1YdEg6cxh553uZ4q9ZDWlPbtZr9q1Wk=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
Expand Down
12 changes: 12 additions & 0 deletions magefiles/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
package main

import (
"bytes"
"os"

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/spf13/cobra/doc"

"github.com/aquasecurity/trivy/pkg/commands"
Expand All @@ -26,4 +28,14 @@ func main() {
if err := doc.GenMarkdownTree(cmd, "./docs/docs/references/configuration/cli"); err != nil {
log.Fatal("Fatal error", log.Err(err))
}

buf := bytes.NewBuffer([]byte(`
## Analyzers
Use the following types of analyzers for the [--max-file-size] and [--file-pattern] flags`))
buf.WriteString("\n```\n")
for _, t := range analyzer.AllAnalyzerTypes() {
buf.WriteString(string(t) + "\n")
}
buf.WriteString("```")
os.WriteFile("./docs/docs/analyzers/analyzers.md", buf.Bytes(), 0644)
}
2 changes: 2 additions & 0 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ func (r *runner) initScannerConfig(opts flag.Options) (ScannerConfig, types.Scan
ScanRemovedPackages: opts.ScanRemovedPkgs, // this is valid only for 'image' subcommand
LicenseCategories: opts.LicenseCategories,
FilePatterns: opts.FilePatterns,
MaxFileSize: opts.MaxFileSize,
IncludeDevDeps: opts.IncludeDevDeps,
}

Expand Down Expand Up @@ -585,6 +586,7 @@ func (r *runner) initScannerConfig(opts flag.Options) (ScannerConfig, types.Scan
DisabledAnalyzers: disabledAnalyzers(opts),
DisabledHandlers: disabledHandlers,
FilePatterns: opts.FilePatterns,
MaxFileSize: opts.MaxFileSize,
Parallel: opts.Parallel,
Offline: opts.OfflineScan,
NoProgress: opts.NoProgress || opts.Quiet,
Expand Down
25 changes: 24 additions & 1 deletion pkg/fanal/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type AnalyzerOptions struct {
Group Group
Parallel int
FilePatterns []string
MaxFileSize map[Type]int64
DisabledAnalyzers []Type
DetectionPriority types.DetectionPriority
MisconfScannerOption misconf.ScannerOption
Expand Down Expand Up @@ -74,13 +75,19 @@ type analyzer interface {
Version() int
Analyze(ctx context.Context, input AnalysisInput) (*AnalysisResult, error)
Required(filePath string, info os.FileInfo) bool
Description() string
Copy link
Contributor

@nikpivkin nikpivkin Aug 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not used anywhere. I think the point is that the description should return a human-readable description of the analyser and be used in generating documentation.

/cc @knqyf263

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we can do it in another PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @knqyf263
Let's move adding of this function to another PR.

}

type PostAnalyzer interface {
Type() Type
Version() int
PostAnalyze(ctx context.Context, input PostAnalysisInput) (*AnalysisResult, error)
Required(filePath string, info os.FileInfo) bool
Description() string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

}

func AllAnalyzerTypes() []Type {
return append(lo.Keys(analyzers), lo.Keys(postAnalyzers)...)
}

////////////////////
Expand Down Expand Up @@ -125,6 +132,7 @@ type AnalyzerGroup struct {
analyzers []analyzer
postAnalyzers []PostAnalyzer
filePatterns map[Type][]*regexp.Regexp
fileSizes map[Type]int64
detectionPriority types.DetectionPriority
}

Expand Down Expand Up @@ -323,8 +331,10 @@ func NewAnalyzerGroup(opts AnalyzerOptions) (AnalyzerGroup, error) {
group := AnalyzerGroup{
logger: log.WithPrefix("analyzer"),
filePatterns: make(map[Type][]*regexp.Regexp),
fileSizes: opts.MaxFileSize,
detectionPriority: opts.DetectionPriority,
}

for _, p := range opts.FilePatterns {
// e.g. "dockerfile:my_dockerfile_*"
s := strings.SplitN(p, separator, 2)
Expand Down Expand Up @@ -404,12 +414,14 @@ func (ag AnalyzerGroup) AnalyzeFile(ctx context.Context, wg *sync.WaitGroup, lim

// filepath extracted from tar file doesn't have the prefix "/"
cleanPath := strings.TrimLeft(filePath, "/")

for _, a := range ag.analyzers {
// Skip disabled analyzers
if slices.Contains(disabled, a.Type()) {
continue
}
if !ag.fileSizeMatch(a.Type(), info) {
continue
}

if !ag.filePatternMatch(a.Type(), cleanPath) && !a.Required(cleanPath, info) {
continue
Expand Down Expand Up @@ -457,6 +469,9 @@ func (ag AnalyzerGroup) RequiredPostAnalyzers(filePath string, info os.FileInfo)
}
var postAnalyzerTypes []Type
for _, a := range ag.postAnalyzers {
if !ag.fileSizeMatch(a.Type(), info) {
continue
}
if ag.filePatternMatch(a.Type(), filePath) || a.Required(filePath, info) {
postAnalyzerTypes = append(postAnalyzerTypes, a.Type())
}
Expand Down Expand Up @@ -523,3 +538,11 @@ func (ag AnalyzerGroup) filePatternMatch(analyzerType Type, filePath string) boo
}
return false
}

func (ag AnalyzerGroup) fileSizeMatch(analyzerType Type, fileInfo os.FileInfo) bool {
maxSize, ok := ag.fileSizes[analyzerType]
if !ok {
return true
}
return fileInfo.Size() <= maxSize
}
19 changes: 19 additions & 0 deletions pkg/fanal/analyzer/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ func TestAnalyzerGroup_AnalyzeFile(t *testing.T) {
testFilePath string
disabledAnalyzers []analyzer.Type
filePatterns []string
maxFileSize map[analyzer.Type]int64
}
tests := []struct {
name string
Expand All @@ -315,6 +316,17 @@ func TestAnalyzerGroup_AnalyzeFile(t *testing.T) {
},
},
},
{
name: "happy path with max file size os analyzer",
args: args{
filePath: "/etc/alpine-release",
testFilePath: "testdata/etc/alpine-release",
maxFileSize: map[analyzer.Type]int64{
analyzer.TypeAlpine: 1,
},
},
want: &analyzer.AnalysisResult{},
},
{
name: "happy path with disabled os analyzer",
args: args{
Expand Down Expand Up @@ -514,11 +526,18 @@ func TestAnalyzerGroup_AnalyzeFile(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var wg sync.WaitGroup
var maxFileSize map[analyzer.Type]int64
limit := semaphore.NewWeighted(3)

got := new(analyzer.AnalysisResult)
if tt.args.maxFileSize != nil {
maxFileSize = tt.args.maxFileSize
} else {
maxFileSize = map[analyzer.Type]int64{}
}
Comment on lines +533 to +537
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if tt.args.maxFileSize != nil {
maxFileSize = tt.args.maxFileSize
} else {
maxFileSize = map[analyzer.Type]int64{}
}
maxFileSize := map[analyzer.Type]int64{}
if tt.args.maxFileSize != nil {
maxFileSize = tt.args.maxFileSize
}

a, err := analyzer.NewAnalyzerGroup(analyzer.AnalyzerOptions{
FilePatterns: tt.args.filePatterns,
MaxFileSize: maxFileSize,
DisabledAnalyzers: tt.args.disabledAnalyzers,
})
if err != nil && tt.wantErr != "" {
Expand Down
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/buildinfo/content_manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,7 @@ func (a contentManifestAnalyzer) Type() analyzer.Type {
func (a contentManifestAnalyzer) Version() int {
return contentManifestAnalyzerVersion
}

func (a contentManifestAnalyzer) Description() string {
return string(analyzer.TypeRedHatContentManifestType)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/buildinfo/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ func (a dockerfileAnalyzer) Version() int {
return dockerfileAnalyzerVersion
}

func (a dockerfileAnalyzer) Description() string {
return string(analyzer.TypeRedHatDockerfileType)
}

// parseVersion parses version from a file name
func parseVersion(nvr string) string {
releaseIndex := strings.LastIndex(nvr, "-")
Expand Down
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/azurearm/azurearm.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ func newAzureARMConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnal
func (a *azureARMConfigAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return filepath.Ext(filePath) == ".json"
}

func (a *azureARMConfigAnalyzer) Description() string {
return string(analyzer.TypeAzureARM)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/cloudformation/cloudformation.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ func newCloudFormationConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.Po
}
return &cloudFormationConfigAnalyzer{Analyzer: a}, nil
}

func (c cloudFormationConfigAnalyzer) Description() string {
return string(analyzer.TypeCloudFormation)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ func (a *Analyzer) Type() analyzer.Type {
func (a *Analyzer) Version() int {
return a.version
}

func (a *Analyzer) Description() string {
return string(a.typ)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/dockerfile/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ func (a *dockerConfigAnalyzer) Required(filePath string, _ os.FileInfo) bool {

return false
}

func (a *dockerConfigAnalyzer) Description() string {
return string(analyzer.TypeDockerfile)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ func (*helmConfigAnalyzer) Required(filePath string, info os.FileInfo) bool {

return false
}

func (*helmConfigAnalyzer) Description() string {
return string(analyzer.TypeHelm)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ func newKubernetesConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAn
}
return &kubernetesConfigAnalyzer{Analyzer: a}, nil
}

func (k kubernetesConfigAnalyzer) Description() string {
return string(analyzer.TypeKubernetes)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ func newTerraformConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAna
func (*terraformConfigAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return detection.IsTerraformFile(filePath)
}

func (*terraformConfigAnalyzer) Description() string {
return string(analyzer.TypeTerraform)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/config/terraformplan/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ func newTerraformPlanJSONConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer
func (*terraformPlanConfigAnalyzer) Required(filePath string, _ os.FileInfo) bool {
return slices.Contains(requiredExts, filepath.Ext(filePath))
}

func (*terraformPlanConfigAnalyzer) Description() string {
return string(analyzer.TypeTerraformPlanJSON)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ func newTerraformPlanSnapshotConfigAnalyzer(opts analyzer.AnalyzerOptions) (anal
func (*terraformPlanConfigAnalyzer) Required(filePath string, fi os.FileInfo) bool {
return filepath.Ext(filePath) == ".tfplan" || filepath.Base(filePath) == "tfplan"
}

func (*terraformPlanConfigAnalyzer) Description() string {
return string(analyzer.TypeTerraformPlanSnapshot)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/executable/executable.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ func (a executableAnalyzer) Type() analyzer.Type {
func (a executableAnalyzer) Version() int {
return version
}

func (a executableAnalyzer) Description() string {
return string(analyzer.TypeExecutable)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/language/c/conan/conan.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,7 @@ func (a conanLockAnalyzer) Type() analyzer.Type {
func (a conanLockAnalyzer) Version() int {
return version
}

func (a conanLockAnalyzer) Description() string {
return string(analyzer.TypeConanLock)
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,7 @@ func (a environmentAnalyzer) Type() analyzer.Type {
func (a environmentAnalyzer) Version() int {
return version
}

func (a environmentAnalyzer) Description() string {
return string(analyzer.TypeCondaEnv)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/language/conda/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ func (a metaAnalyzer) Type() analyzer.Type {
func (a metaAnalyzer) Version() int {
return version
}

func (a metaAnalyzer) Description() string {
return string(analyzer.TypeCondaPkg)
}
4 changes: 4 additions & 0 deletions pkg/fanal/analyzer/language/dart/pub/pubspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,7 @@ func (a pubSpecLockAnalyzer) Type() analyzer.Type {
func (a pubSpecLockAnalyzer) Version() int {
return version
}

func (a pubSpecLockAnalyzer) Description() string {
return string(analyzer.TypePubSpecLock)
}
Loading