fix(misconf): move disabled checks filtering after analyzer scan (#9002)

Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
This commit is contained in:
Nikita Pivkin
2025-06-17 11:39:27 +06:00
committed by GitHub
parent 64aea25e2a
commit a58c36de12
6 changed files with 31 additions and 135 deletions

View File

@@ -14,21 +14,17 @@ import (
"github.com/aquasecurity/trivy/pkg/fanal/image"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/iac/detection"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/mapfs"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/set"
"github.com/aquasecurity/trivy/pkg/version/doc"
)
var disabledChecks = []misconf.DisabledCheck{
{
ID: "DS007", Scanner: string(analyzer.TypeHistoryDockerfile),
Reason: "See " + doc.URL("docs/target/container_image", "disabled-checks"),
},
{
ID: "DS016", Scanner: string(analyzer.TypeHistoryDockerfile),
Reason: "See " + doc.URL("docs/target/container_image", "disabled-checks"),
},
}
var (
disabledChecks = set.New("AVD-DS-0007", "AVD-DS-0016")
reason = "See " + doc.URL("docs/target/container_image", "disabled-checks")
)
const analyzerVersion = 1
@@ -41,7 +37,6 @@ type historyAnalyzer struct {
}
func newHistoryAnalyzer(opts analyzer.ConfigAnalyzerOptions) (analyzer.ConfigAnalyzer, error) {
opts.MisconfScannerOption.DisabledChecks = append(opts.MisconfScannerOption.DisabledChecks, disabledChecks...)
s, err := misconf.NewScanner(detection.FileTypeDockerfile, opts.MisconfScannerOption)
if err != nil {
return nil, xerrors.Errorf("misconfiguration scanner error: %w", err)
@@ -72,8 +67,10 @@ func (a *historyAnalyzer) Analyze(ctx context.Context, input analyzer.ConfigAnal
return nil, nil
}
misconfig := misconfs[0]
misconfig.Failures = filterDisabledChecks(misconfig.Failures)
return &analyzer.ConfigAnalysisResult{
Misconfiguration: &misconfs[0],
Misconfiguration: &misconfig,
}, nil
}
@@ -174,3 +171,16 @@ func (a *historyAnalyzer) Type() analyzer.Type {
func (a *historyAnalyzer) Version() int {
return analyzerVersion
}
func filterDisabledChecks(results types.MisconfResults) types.MisconfResults {
var filtered types.MisconfResults
for _, r := range results {
if disabledChecks.Contains(r.AVDID) {
log.WithPrefix("image history analyzer").Info("Skip disabled check",
log.String("ID", r.AVDID), log.String("reason", reason))
continue
}
filtered = append(filtered, r)
}
return filtered
}

View File

@@ -378,11 +378,6 @@ func (s *Scanner) isModuleApplicable(module *ast.Module, metadata *StaticMetadat
return false
}
// ignore disabled built-in checks
if IsBuiltinNamespace(getModuleNamespace(module)) && s.disabledCheckIDs.Contains(metadata.ID) {
return false
}
if len(metadata.InputOptions.Selectors) == 0 && !metadata.Library {
s.logger.Warn(
"Module has no input selectors - it will be loaded for all inputs",

View File

@@ -106,15 +106,6 @@ func WithCustomSchemas(schemas map[string][]byte) options.ScannerOption {
}
}
// WithDisabledCheckIDs disables checks by their ID (ID field in metadata)
func WithDisabledCheckIDs(ids ...string) options.ScannerOption {
return func(s options.ConfigurableScanner) {
if ss, ok := s.(*Scanner); ok {
ss.disabledCheckIDs.Append(ids...)
}
}
}
func WithIncludeDeprecatedChecks(include bool) options.ScannerOption {
return func(s options.ConfigurableScanner) {
if ss, ok := s.(*Scanner); ok {

View File

@@ -67,8 +67,6 @@ type Scanner struct {
embeddedLibs map[string]*ast.Module
embeddedChecks map[string]*ast.Module
customSchemas map[string][]byte
disabledCheckIDs set.Set[string]
}
func (s *Scanner) trace(heading string, input any) {
@@ -94,14 +92,13 @@ func NewScanner(opts ...options.ScannerOption) *Scanner {
LoadAndRegister()
s := &Scanner{
regoErrorLimit: ast.CompileErrorLimitDefault,
ruleNamespaces: builtinNamespaces.Clone(),
runtimeValues: addRuntimeValues(),
logger: log.WithPrefix("rego"),
customSchemas: make(map[string][]byte),
disabledCheckIDs: set.New[string](),
moduleMetadata: make(map[string]*StaticMetadata),
trivyVersion: app.Version(),
regoErrorLimit: ast.CompileErrorLimitDefault,
ruleNamespaces: builtinNamespaces.Clone(),
runtimeValues: addRuntimeValues(),
logger: log.WithPrefix("rego"),
customSchemas: make(map[string][]byte),
moduleMetadata: make(map[string]*StaticMetadata),
trivyVersion: app.Version(),
}
for _, opt := range opts {

View File

@@ -1107,86 +1107,3 @@ deny {
})
}
}
func Test_RegoScanner_WithDisabledCheckIDs(t *testing.T) {
check := `# METADATA
# custom:
# id: TEST-001
# avd_id: AVD-TEST-001
# severity: LOW
# provider: aws
# service: s3
# short_code: test
package builtin.test
deny {
true
}
`
tests := []struct {
name string
disabledChecks []string
inputCheck string
expected bool
}{
{
name: "no disabled checks",
expected: true,
inputCheck: check,
},
{
name: "disable check by ID",
disabledChecks: []string{"TEST-001"},
inputCheck: check,
},
{
name: "disabling a non-existent check",
disabledChecks: []string{"FOO"},
expected: true,
inputCheck: check,
},
{
name: "one of the identifiers does not exist",
disabledChecks: []string{"FOO", "TEST-001"},
inputCheck: check,
},
{
name: "do not disable user checks with builtin IDs",
inputCheck: `# METADATA
# custom:
# id: TEST-001
# avd_id: AVD-TEST-001
# severity: LOW
# provider: aws
# service: s3
# short_code: test
package user.test
deny {
true
}
`,
disabledChecks: []string{"TEST-001"},
expected: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
scanner := rego.NewScanner(
rego.WithPolicyReader(strings.NewReader(tt.inputCheck)),
rego.WithDisabledCheckIDs(tt.disabledChecks...),
rego.WithPolicyNamespaces("user"),
)
require.NoError(t, scanner.LoadPolicies(nil))
results, err := scanner.ScanInput(t.Context(), types.SourceYAML, rego.Input{})
require.NoError(t, err)
require.Equal(t, tt.expected, len(results.GetFailed()) > 0)
})
}
}

View File

@@ -52,12 +52,6 @@ var enablediacTypes = map[detection.FileType]types.ConfigType{
detection.FileTypeYAML: types.YAML,
}
type DisabledCheck struct {
ID string
Scanner string // For logging
Reason string // For logging
}
type ScannerOption struct {
Trace bool
Namespaces []string
@@ -82,9 +76,8 @@ type ScannerOption struct {
FilePatterns []string
ConfigFileSchemas []*ConfigFileSchema
DisabledChecks []DisabledCheck
SkipFiles []string
SkipDirs []string
SkipFiles []string
SkipDirs []string
RegoScanner *rego.Scanner
}
@@ -236,17 +229,10 @@ func InitRegoScanner(opt ScannerOption) (*rego.Scanner, error) {
}
func initRegoOptions(opt ScannerOption) ([]options.ScannerOption, error) {
disabledCheckIDs := lo.Map(opt.DisabledChecks, func(check DisabledCheck, _ int) string {
log.Info("Check disabled", log.Prefix(log.PrefixMisconfiguration), log.String("ID", check.ID),
log.String("scanner", check.Scanner), log.String("reason", check.Reason))
return check.ID
})
opts := []options.ScannerOption{
rego.WithEmbeddedPolicies(!opt.DisableEmbeddedPolicies),
rego.WithEmbeddedLibraries(!opt.DisableEmbeddedLibraries),
rego.WithIncludeDeprecatedChecks(opt.IncludeDeprecatedChecks),
rego.WithDisabledCheckIDs(disabledCheckIDs...),
rego.WithTrivyVersion(app.Version()),
}