From c3192f061d7e84eaf38df8df7c879dc00b4ca137 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Tue, 18 Jun 2024 12:41:29 +0700 Subject: [PATCH] fix(misconf): handle source prefix to ignore (#6945) Signed-off-by: nikpivkin --- pkg/iac/ignore/parse.go | 4 +- pkg/iac/ignore/rule_test.go | 4 +- .../scanners/cloudformation/parser/parser.go | 2 +- pkg/iac/scanners/terraform/ignore_test.go | 57 +++++++++++++++++++ pkg/iac/scanners/terraform/parser/parser.go | 1 + 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/pkg/iac/ignore/parse.go b/pkg/iac/ignore/parse.go index 88984890754..8a7a940c6b5 100644 --- a/pkg/iac/ignore/parse.go +++ b/pkg/iac/ignore/parse.go @@ -19,11 +19,11 @@ type RuleSectionParser interface { } // Parse parses the configuration file and returns the Rules -func Parse(src, path string, parsers ...RuleSectionParser) Rules { +func Parse(src, path, sourcePrefix string, parsers ...RuleSectionParser) Rules { var rules Rules for i, line := range strings.Split(src, "\n") { line = strings.TrimSpace(line) - rng := types.NewRange(path, i+1, i+1, "", nil) + rng := types.NewRange(path, i+1, i+1, sourcePrefix, nil) lineIgnores := parseLine(line, rng, parsers) for _, lineIgnore := range lineIgnores { rules = append(rules, lineIgnore) diff --git a/pkg/iac/ignore/rule_test.go b/pkg/iac/ignore/rule_test.go index 7cd4d382a41..619d251eb75 100644 --- a/pkg/iac/ignore/rule_test.go +++ b/pkg/iac/ignore/rule_test.go @@ -239,7 +239,7 @@ test #trivy:ignore:rule-4 for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - rules := ignore.Parse(tt.src, filename) + rules := ignore.Parse(tt.src, "", filename) got := rules.Ignore(tt.args.metadata, tt.args.ids, nil) assert.Equal(t, tt.shouldIgnore, got) }) @@ -329,7 +329,7 @@ func TestRules_IgnoreWithCustomIgnorer(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - rules := ignore.Parse(tt.src, filename, tt.parser) + rules := ignore.Parse(tt.src, filename, "", tt.parser) got := rules.Ignore(tt.args.metadata, tt.args.ids, tt.args.ignorers) assert.Equal(t, tt.shouldIgnore, got) }) diff --git a/pkg/iac/scanners/cloudformation/parser/parser.go b/pkg/iac/scanners/cloudformation/parser/parser.go index 65bf1440432..5aa760e1988 100644 --- a/pkg/iac/scanners/cloudformation/parser/parser.go +++ b/pkg/iac/scanners/cloudformation/parser/parser.go @@ -171,7 +171,7 @@ func (p *Parser) ParseFile(ctx context.Context, fsys fs.FS, path string) (fctx * if err := yaml.Unmarshal(content, fctx); err != nil { return nil, NewErrInvalidContent(path, err) } - fctx.Ignores = ignore.Parse(string(content), path) + fctx.Ignores = ignore.Parse(string(content), path, "") case JsonSourceFormat: if err := jfather.Unmarshal(content, fctx); err != nil { return nil, NewErrInvalidContent(path, err) diff --git a/pkg/iac/scanners/terraform/ignore_test.go b/pkg/iac/scanners/terraform/ignore_test.go index 3b0a83428a5..6183469d529 100644 --- a/pkg/iac/scanners/terraform/ignore_test.go +++ b/pkg/iac/scanners/terraform/ignore_test.go @@ -1,15 +1,19 @@ package terraform import ( + "context" "fmt" "strings" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/aquasecurity/trivy/internal/testutil" "github.com/aquasecurity/trivy/pkg/iac/providers" "github.com/aquasecurity/trivy/pkg/iac/rules" "github.com/aquasecurity/trivy/pkg/iac/scan" + "github.com/aquasecurity/trivy/pkg/iac/scanners/options" "github.com/aquasecurity/trivy/pkg/iac/severity" "github.com/aquasecurity/trivy/pkg/iac/terraform" ) @@ -748,3 +752,56 @@ func Test_IgnoreInlineByAVDID(t *testing.T) { } } } + +func TestIgnoreRemoteTerraformResource(t *testing.T) { + + fsys := testutil.CreateFS(t, map[string]string{ + "main.tf": `module "bucket" { + source = "git::https://github.com/test/bucket" +}`, + ".terraform/modules/modules.json": `{ + "Modules": [ + { "Key": "", "Source": "", "Dir": "." }, + { + "Key": "bucket", + "Source": "git::https://github.com/test/bucket", + "Dir": ".terraform/modules/bucket" + } + ] +} +`, + ".terraform/modules/bucket/main.tf": ` +# trivy:ignore:test-0001 +resource "aws_s3_bucket" "test" { + bucket = "" +} +`, + }) + + check := `# METADATA +# title: Test +# custom: +# id: test-0001 +# avdid: test-0001 + +package user.test0001 + +deny[res] { + bucket := input.aws.s3.buckets[_] + bucket.name.value == "" + res := result.new("Empty bucket name!", bucket) +}` + + localScanner := New( + options.ScannerWithEmbeddedPolicies(false), + options.ScannerWithEmbeddedLibraries(true), + options.ScannerWithRegoOnly(true), + options.ScannerWithPolicyNamespaces("user"), + options.ScannerWithPolicyReader(strings.NewReader(check)), + ScannerWithDownloadsAllowed(false), + ScannerWithSkipCachedModules(true), + ) + results, err := localScanner.ScanFS(context.TODO(), fsys, ".") + require.NoError(t, err) + assert.Empty(t, results.GetFailed()) +} diff --git a/pkg/iac/scanners/terraform/parser/parser.go b/pkg/iac/scanners/terraform/parser/parser.go index 049be0e02c1..aec5ce0c31d 100644 --- a/pkg/iac/scanners/terraform/parser/parser.go +++ b/pkg/iac/scanners/terraform/parser/parser.go @@ -301,6 +301,7 @@ func (p *Parser) readBlocks(files []sourceFile) (terraform.Blocks, ignore.Rules, fileIgnores := ignore.Parse( string(file.file.Bytes), file.path, + p.moduleSource, &ignore.StringMatchParser{ SectionKey: "ws", },