Skip to content

Commit

Permalink
feat(misconf): Support --skip-* for all included modules
Browse files Browse the repository at this point in the history
  • Loading branch information
simar7 committed Sep 24, 2024
1 parent dbd2dd6 commit 5f726d7
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 2 deletions.
2 changes: 2 additions & 0 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -659,5 +659,7 @@ func initMisconfScannerOption(opts flag.Options) (misconf.ScannerOption, error)
TfExcludeDownloaded: opts.TfExcludeDownloaded,
FilePatterns: opts.FilePatterns,
ConfigFileSchemas: configSchemas,
SkipFiles: opts.SkipFiles,
SkipDirs: opts.SkipDirs,
}, nil
}
2 changes: 0 additions & 2 deletions pkg/fanal/walker/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/samber/lo"

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

const defaultSizeThreshold = int64(100) << 20 // 200MB
Expand Down Expand Up @@ -44,7 +43,6 @@ func SkipPath(path string, skipPaths []string) bool {
if err != nil {
return false // return early if bad pattern
} else if match {
log.Debug("Skipping path", log.String("path", path))
return true
}
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/iac/scanners/terraform/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,19 @@ func ScannerWithConfigsFileSystem(fsys fs.FS) options.ScannerOption {
}
}
}

func ScannerWithSkipFiles(files []string) options.ScannerOption {
return func(s options.ConfigurableScanner) {
if tf, ok := s.(ConfigurableTerraformScanner); ok {
tf.AddParserOptions(parser.OptionWithSkipFiles(files))
}
}
}

func ScannerWithSkipDirs(dirs []string) options.ScannerOption {
return func(s options.ConfigurableScanner) {
if tf, ok := s.(ConfigurableTerraformScanner); ok {
tf.AddParserOptions(parser.OptionWithSkipDirs(dirs))
}
}
}
12 changes: 12 additions & 0 deletions pkg/iac/scanners/terraform/parser/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,15 @@ func OptionWithConfigsFS(fsys fs.FS) Option {
p.configsFS = fsys
}
}

func OptionWithSkipFiles(files []string) Option {
return func(p *Parser) {
p.skipPaths = files
}
}

func OptionWithSkipDirs(dirs []string) Option {
return func(p *Parser) {
p.skipPaths = dirs
}
}
31 changes: 31 additions & 0 deletions pkg/iac/scanners/terraform/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"sort"
"strings"

"github.com/bmatcuk/doublestar/v4"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclparse"
"github.com/samber/lo"
"github.com/zclconf/go-cty/cty"

"github.com/aquasecurity/trivy/pkg/iac/ignore"
Expand Down Expand Up @@ -47,6 +49,7 @@ type Parser struct {
skipCachedModules bool
fsMap map[string]fs.FS
configsFS fs.FS
skipPaths []string
}

// New creates a new Parser
Expand All @@ -62,6 +65,7 @@ func New(moduleFS fs.FS, moduleSource string, opts ...Option) *Parser {
configsFS: moduleFS,
logger: log.WithPrefix("terraform parser").With("module", "root"),
tfvars: make(map[string]cty.Value),
skipPaths: []string{},
}

for _, option := range opts {
Expand All @@ -78,6 +82,7 @@ func (p *Parser) newModuleParser(moduleFS fs.FS, moduleSource, modulePath, modul
mp.moduleName = moduleName
mp.logger = log.WithPrefix("terraform parser").With("module", moduleName)
mp.projectRoot = p.projectRoot
mp.skipPaths = p.skipPaths
p.children = append(p.children, mp)
for _, option := range p.options {
option(mp)
Expand Down Expand Up @@ -155,6 +160,10 @@ func (p *Parser) ParseFS(ctx context.Context, dir string) error {
if info.IsDir() {
continue
}
if SkipPath(realPath, CleanSkipPaths(p.skipPaths)) {
p.logger.Debug("Skipping path based on input glob", log.FilePath(realPath), log.Any("glob", p.skipPaths))
continue
}
paths = append(paths, realPath)
}
sort.Strings(paths)
Expand Down Expand Up @@ -358,3 +367,25 @@ func (s *paramParser) Parse(str string) bool {
func (s *paramParser) Param() any {
return s.params
}

func CleanSkipPaths(skipPaths []string) []string {
return lo.Map(skipPaths, func(skipPath string, index int) string {
skipPath = filepath.ToSlash(filepath.Clean(skipPath))
return strings.TrimLeft(skipPath, "/")
})
}

func SkipPath(path string, skipPaths []string) bool {
path = strings.TrimLeft(path, "/")

// skip files
for _, pattern := range skipPaths {
match, err := doublestar.Match(pattern, path)
if err != nil {
return false // return early if bad pattern
} else if match {
return true
}
}
return false
}
75 changes: 75 additions & 0 deletions pkg/iac/scanners/terraform/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1118,3 +1118,78 @@ func TestSkipDeprecatedGoChecks(t *testing.T) {
require.Len(t, results, 1)
})
}

func TestSkipDir(t *testing.T) {
fs := testutil.CreateFS(t, map[string]string{
"deployments/main.tf": `
module "use_bad_configuration" {
source = "../modules"
}
module "use_bad_configuration_2" {
source = "../modules/modules2"
}
`,
"modules/misconfig.tf": `data "aws_iam_policy_document" "bad" {
statement {
actions = [
"apigateway:*",
]
resources = [
"*",
]
}
}
resource "aws_iam_policy" "bad_configuration" {
name_prefix = local.setup_role_name
policy = data.aws_iam_policy_document.bad.json
}
`,
"modules/modules2/misconfig.tf": `data "aws_iam_policy_document" "bad" {
statement {
actions = [
"apigateway:*",
]
resources = [
"*",
]
}
}
resource "aws_iam_policy" "bad_configuration" {
name_prefix = local.setup_role_name
policy = data.aws_iam_policy_document.bad.json
}
`,
})

t.Run("use skip-dir option", func(t *testing.T) {
scanner := New(
options.ScannerWithIncludeDeprecatedChecks(true),
ScannerWithSkipDirs([]string{"**/modules/**"}),
ScannerWithAllDirectories(true),
)

results, err := scanner.ScanFS(context.TODO(), fs, "deployments")
require.NoError(t, err)

assert.Len(t, results, 0)
})

t.Run("use skip-files option", func(t *testing.T) {
scanner := New(
options.ScannerWithIncludeDeprecatedChecks(true),
ScannerWithSkipFiles([]string{"**/modules/**/*.tf"}),
ScannerWithAllDirectories(true),
)

results, err := scanner.ScanFS(context.TODO(), fs, "deployments")
require.NoError(t, err)

assert.Len(t, results, 0)
})

}
4 changes: 4 additions & 0 deletions pkg/misconf/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ type ScannerOption struct {

FilePatterns []string
ConfigFileSchemas []*ConfigFileSchema
SkipFiles []string
SkipDirs []string
}

func (o *ScannerOption) Sort() {
Expand Down Expand Up @@ -294,6 +296,8 @@ func addTFOpts(opts []options.ScannerOption, scannerOption ScannerOption) ([]opt
opts = append(opts,
terraform.ScannerWithAllDirectories(true),
terraform.ScannerWithSkipDownloaded(scannerOption.TfExcludeDownloaded),
terraform.ScannerWithSkipFiles(scannerOption.SkipFiles),
terraform.ScannerWithSkipDirs(scannerOption.SkipDirs),
)

return opts, nil
Expand Down

0 comments on commit 5f726d7

Please sign in to comment.