Skip to content

Commit

Permalink
feat(misconf): Add support for --include-deprecated-checks (#6671)
Browse files Browse the repository at this point in the history
  • Loading branch information
simar7 committed May 14, 2024
1 parent 087630f commit 490ddd3
Show file tree
Hide file tree
Showing 25 changed files with 171 additions and 40 deletions.
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ trivy aws [flags]
-h, --help help for aws
--ignore-policy string specify the Rego file path to evaluate each vulnerability
--ignorefile string specify .trivyignore file (default ".trivyignore")
--include-deprecated-checks include deprecated checks
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
--list-all-pkgs enabling the option will output all packages regardless of vulnerability
--max-cache-age duration The maximum age of the cloud cache. Cached data will be required from the cloud provider if it is older than this. (default 24h0m0s)
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ trivy config [flags] DIR
-h, --help help for config
--ignore-policy string specify the Rego file path to evaluate each vulnerability
--ignorefile string specify .trivyignore file (default ".trivyignore")
--include-deprecated-checks include deprecated checks
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
--k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0)
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_filesystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ trivy filesystem [flags] PATH
--ignore-unfixed display only fixed vulnerabilities
--ignored-licenses strings specify a list of license to ignore
--ignorefile string specify .trivyignore file (default ".trivyignore")
--include-deprecated-checks include deprecated checks
--include-dev-deps include development dependencies in the report (supported: npm, yarn)
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
--java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db:1")
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ trivy image [flags] IMAGE_NAME
--ignorefile string specify .trivyignore file (default ".trivyignore")
--image-config-scanners strings comma-separated list of what security issues to detect on container image configurations (misconfig,secret)
--image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
--include-deprecated-checks include deprecated checks
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
--input string input file path instead of image name
--java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db:1")
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ trivy kubernetes [flags] [CONTEXT]
--ignore-unfixed display only fixed vulnerabilities
--ignorefile string specify .trivyignore file (default ".trivyignore")
--image-src strings image source(s) to use, in priority order (docker,containerd,podman,remote) (default [docker,containerd,podman,remote])
--include-deprecated-checks include deprecated checks
--include-kinds strings indicate the kinds included in scanning (example: node)
--include-namespaces strings indicate the namespaces included in scanning (example: kube-system)
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--ignore-unfixed display only fixed vulnerabilities
--ignored-licenses strings specify a list of license to ignore
--ignorefile string specify .trivyignore file (default ".trivyignore")
--include-deprecated-checks include deprecated checks
--include-dev-deps include development dependencies in the report (supported: npm, yarn)
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
--java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db:1")
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_rootfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ trivy rootfs [flags] ROOTDIR
--ignore-unfixed display only fixed vulnerabilities
--ignored-licenses strings specify a list of license to ignore
--ignorefile string specify .trivyignore file (default ".trivyignore")
--include-deprecated-checks include deprecated checks
--include-non-failures include successes and exceptions, available with '--scanners misconfig'
--java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db:1")
--license-confidence-level float specify license classifier's confidence level (default 0.9)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ require (
github.com/aquasecurity/table v1.8.0
github.com/aquasecurity/testdocker v0.0.0-20240419073403-90bd43849334
github.com/aquasecurity/tml v0.6.1
github.com/aquasecurity/trivy-aws v0.8.0
github.com/aquasecurity/trivy-aws v0.8.1-0.20240511051125-4393910b056b
github.com/aquasecurity/trivy-checks v0.10.5-0.20240430045208-6cc735de6b9e
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,8 @@ github.com/aquasecurity/testdocker v0.0.0-20240419073403-90bd43849334 h1:MgvbLyL
github.com/aquasecurity/testdocker v0.0.0-20240419073403-90bd43849334/go.mod h1:TKXn7bPfMM52ETP4sjjwkTKCZ18CqCs+I/vtFePSdBc=
github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo=
github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
github.com/aquasecurity/trivy-aws v0.8.0 h1:4ij8MiZ2sJUH+vWpSeoGVhPr109ZBcNp7LNLfPuv5Cw=
github.com/aquasecurity/trivy-aws v0.8.0/go.mod h1:Pb9xqOuTKMHVgjsnjvudjqZh3nmzdFqFVfRkXnoIZBM=
github.com/aquasecurity/trivy-aws v0.8.1-0.20240511051125-4393910b056b h1:mBMM6+kLTPaqSxNLO51rL6HiCKL1ElV5RXM+BEAK8fg=
github.com/aquasecurity/trivy-aws v0.8.1-0.20240511051125-4393910b056b/go.mod h1:z638DsULU5CCIk8QZqcj8u2D5IIRzvjq4jI1VDQGda4=
github.com/aquasecurity/trivy-checks v0.10.5-0.20240430045208-6cc735de6b9e h1:s0P4VeCqb7tWw06/L1cZ5/42AWy6VZFuLZ96THPJmmM=
github.com/aquasecurity/trivy-checks v0.10.5-0.20240430045208-6cc735de6b9e/go.mod h1:UIFQxYlKcL7EGhNVicFmZ6XxZ2UpFZU7bNKEv/Y/6XM=
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTUAkbGqpzt9nJsO24RAdfG+ZSiLFj0G2jO8c=
Expand Down
1 change: 1 addition & 0 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
K8sVersion: opts.K8sVersion,
DisableEmbeddedPolicies: disableEmbedded,
DisableEmbeddedLibraries: disableEmbedded,
IncludeDeprecatedChecks: opts.IncludeDeprecatedChecks,
TfExcludeDownloaded: opts.TfExcludeDownloaded,
}
}
Expand Down
50 changes: 30 additions & 20 deletions pkg/flag/rego_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ package flag
// config-policy: "custom-policy/policy"
// policy-namespaces: "user"
var (
IncludeDeprecatedChecksFlag = Flag[bool]{
Name: "include-deprecated-checks",
ConfigName: "rego.include-deprecated-checks",
Usage: "include deprecated checks",
}
SkipCheckUpdateFlag = Flag[bool]{
Name: "skip-check-update",
ConfigName: "rego.skip-check-update",
Expand Down Expand Up @@ -53,28 +58,31 @@ var (

// RegoFlagGroup composes common printer flag structs used for commands providing misconfinguration scanning.
type RegoFlagGroup struct {
SkipCheckUpdate *Flag[bool]
Trace *Flag[bool]
CheckPaths *Flag[[]string]
DataPaths *Flag[[]string]
CheckNamespaces *Flag[[]string]
IncludeDeprecatedChecks *Flag[bool]
SkipCheckUpdate *Flag[bool]
Trace *Flag[bool]
CheckPaths *Flag[[]string]
DataPaths *Flag[[]string]
CheckNamespaces *Flag[[]string]
}

type RegoOptions struct {
SkipCheckUpdate bool
Trace bool
CheckPaths []string
DataPaths []string
CheckNamespaces []string
IncludeDeprecatedChecks bool
SkipCheckUpdate bool
Trace bool
CheckPaths []string
DataPaths []string
CheckNamespaces []string
}

func NewRegoFlagGroup() *RegoFlagGroup {
return &RegoFlagGroup{
SkipCheckUpdate: SkipCheckUpdateFlag.Clone(),
Trace: TraceFlag.Clone(),
CheckPaths: ConfigCheckFlag.Clone(),
DataPaths: ConfigDataFlag.Clone(),
CheckNamespaces: CheckNamespaceFlag.Clone(),
IncludeDeprecatedChecks: IncludeDeprecatedChecksFlag.Clone(),
SkipCheckUpdate: SkipCheckUpdateFlag.Clone(),
Trace: TraceFlag.Clone(),
CheckPaths: ConfigCheckFlag.Clone(),
DataPaths: ConfigDataFlag.Clone(),
CheckNamespaces: CheckNamespaceFlag.Clone(),
}
}

Expand All @@ -84,6 +92,7 @@ func (f *RegoFlagGroup) Name() string {

func (f *RegoFlagGroup) Flags() []Flagger {
return []Flagger{
f.IncludeDeprecatedChecks,
f.SkipCheckUpdate,
f.Trace,
f.CheckPaths,
Expand All @@ -98,10 +107,11 @@ func (f *RegoFlagGroup) ToOptions() (RegoOptions, error) {
}

return RegoOptions{
SkipCheckUpdate: f.SkipCheckUpdate.Value(),
Trace: f.Trace.Value(),
CheckPaths: f.CheckPaths.Value(),
DataPaths: f.DataPaths.Value(),
CheckNamespaces: f.CheckNamespaces.Value(),
IncludeDeprecatedChecks: f.IncludeDeprecatedChecks.Value(),
SkipCheckUpdate: f.SkipCheckUpdate.Value(),
Trace: f.Trace.Value(),
CheckPaths: f.CheckPaths.Value(),
DataPaths: f.DataPaths.Value(),
CheckNamespaces: f.CheckNamespaces.Value(),
}, nil
}
43 changes: 26 additions & 17 deletions pkg/iac/rego/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,33 @@ import (
var _ options.ConfigurableScanner = (*Scanner)(nil)

type Scanner struct {
ruleNamespaces map[string]struct{}
policies map[string]*ast.Module
store storage.Store
dataDirs []string
runtimeValues *ast.Term
compiler *ast.Compiler
regoErrorLimit int
debug debug.Logger
traceWriter io.Writer
tracePerResult bool
retriever *MetadataRetriever
policyFS fs.FS
dataFS fs.FS
frameworks []framework.Framework
spec string
inputSchema interface{} // unmarshalled into this from a json schema document
sourceType types.Source
ruleNamespaces map[string]struct{}
policies map[string]*ast.Module
store storage.Store
dataDirs []string
runtimeValues *ast.Term
compiler *ast.Compiler
regoErrorLimit int
debug debug.Logger
traceWriter io.Writer
tracePerResult bool
retriever *MetadataRetriever
policyFS fs.FS
dataFS fs.FS
frameworks []framework.Framework
spec string
inputSchema interface{} // unmarshalled into this from a json schema document
sourceType types.Source
includeDeprecatedChecks bool

embeddedLibs map[string]*ast.Module
embeddedChecks map[string]*ast.Module
}

func (s *Scanner) SetIncludeDeprecatedChecks(b bool) {
s.includeDeprecatedChecks = b
}

func (s *Scanner) SetUseEmbeddedLibraries(b bool) {
// handled externally
}
Expand Down Expand Up @@ -248,6 +253,10 @@ func (s *Scanner) ScanInput(ctx context.Context, inputs ...Input) (scan.Results,
continue
}

if !s.includeDeprecatedChecks && staticMeta.Deprecated {
continue // skip deprecated checks
}

if isPolicyWithSubtype(s.sourceType) {
// skip if check isn't relevant to what is being scanned
if !isPolicyApplicable(staticMeta, inputs...) {
Expand Down
75 changes: 75 additions & 0 deletions pkg/iac/rego/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1011,3 +1011,78 @@ deny {
assert.Contains(t, buf.String(),
`Error occurred while applying rule "deny" from check "checks/bad.rego"`)
}

func Test_RegoScanning_WithDeprecatedCheck(t *testing.T) {
var testCases = []struct {
name string
policy string
expectedResults int
}{
{
name: "happy path check is deprecated",
policy: `# METADATA
# title: i am a deprecated check
# description: i am a description
# related_resources:
# - https://google.com
# custom:
# id: EG123
# avd_id: AVD-EG-0123
# severity: LOW
# recommended_action: have a cup of tea
# deprecated: true
package defsec.test
deny {
input.text
}
`,
expectedResults: 0,
},
{
name: "happy path check is not deprecated",
policy: `# METADATA
# title: i am a deprecated check
# description: i am a description
# related_resources:
# - https://google.com
# custom:
# id: EG123
# avd_id: AVD-EG-0123
# severity: LOW
# recommended_action: have a cup of tea
package defsec.test
deny {
input.text
}
`,
expectedResults: 1,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
srcFS := CreateFS(t, map[string]string{
"policies/test.rego": tc.policy,
})

scanner := NewScanner(types.SourceJSON)
require.NoError(
t,
scanner.LoadPolicies(false, false, srcFS, []string{"policies"}, nil),
)

results, err := scanner.ScanInput(context.TODO(), Input{
Path: "/evil.lol",
Contents: map[string]interface{}{
"text": "test",
},
})
require.NoError(t, err)
require.Len(t, results, tc.expectedResults, tc.name)
})
}
}
2 changes: 2 additions & 0 deletions pkg/iac/scanners/azure/arm/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type Scanner struct { // nolint: gocritic
sync.Mutex
}

func (s *Scanner) SetIncludeDeprecatedChecks(b bool) {}

func (s *Scanner) SetSpec(spec string) {
s.spec = spec
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/iac/scanners/cloudformation/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type Scanner struct { // nolint: gocritic
sync.Mutex
}

func (s *Scanner) SetIncludeDeprecatedChecks(bool) {}

func (s *Scanner) addParserOptions(opt options.ParserOption) {
s.parserOptions = append(s.parserOptions, opt)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/iac/scanners/dockerfile/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type Scanner struct { // nolint: gocritic
loadEmbeddedPolicies bool
}

func (s *Scanner) SetIncludeDeprecatedChecks(bool) {}

func (s *Scanner) SetSpec(spec string) {
s.spec = spec
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/iac/scanners/helm/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type Scanner struct {
mu sync.Mutex
}

func (s *Scanner) SetIncludeDeprecatedChecks(bool) {}

func (s *Scanner) SetSpec(spec string) {
s.spec = spec
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/iac/scanners/json/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type Scanner struct { // nolint: gocritic
loadEmbeddedLibraries bool
}

func (s *Scanner) SetIncludeDeprecatedChecks(bool) {}

func (s *Scanner) SetRegoOnly(bool) {
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/iac/scanners/kubernetes/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type Scanner struct { // nolint: gocritic
loadEmbeddedLibraries bool
}

func (s *Scanner) SetIncludeDeprecatedChecks(bool) {}

func (s *Scanner) SetSpec(spec string) {
s.spec = spec
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/iac/scanners/options/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ConfigurableScanner interface {
SetRegoOnly(regoOnly bool)
SetRegoErrorLimit(limit int)
SetUseEmbeddedLibraries(bool)
SetIncludeDeprecatedChecks(bool)
}

type ScannerOption func(s ConfigurableScanner)
Expand Down Expand Up @@ -65,6 +66,12 @@ func ScannerWithEmbeddedLibraries(enabled bool) ScannerOption {
}
}

func ScannerWithIncludeDeprecatedChecks(enabled bool) ScannerOption {
return func(s ConfigurableScanner) {
s.SetIncludeDeprecatedChecks(enabled)
}
}

// ScannerWithTrace specifies an io.Writer for trace logs (mainly rego tracing) - if not set, they are discarded
func ScannerWithTrace(w io.Writer) ScannerOption {
return func(s ConfigurableScanner) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/iac/scanners/terraform/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type Scanner struct { // nolint: gocritic
loadEmbeddedPolicies bool
}

func (s *Scanner) SetIncludeDeprecatedChecks(b bool) {}

func (s *Scanner) SetSpec(spec string) {
s.spec = spec
}
Expand Down

0 comments on commit 490ddd3

Please sign in to comment.