Skip to content

Commit 9ef05fc

Browse files
authored
feat(misconf): ignore duplicate checks (#7317)
Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
1 parent bfdf5cf commit 9ef05fc

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

pkg/iac/rego/embed.go

+23-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package rego
22

33
import (
44
"context"
5+
"fmt"
56
"io/fs"
67
"path/filepath"
78
"strings"
@@ -10,6 +11,7 @@ import (
1011

1112
checks "github.com/aquasecurity/trivy-checks"
1213
"github.com/aquasecurity/trivy/pkg/iac/rules"
14+
"github.com/aquasecurity/trivy/pkg/log"
1315
)
1416

1517
func init() {
@@ -47,17 +49,34 @@ func RegisterRegoRules(modules map[string]*ast.Module) {
4749
}
4850

4951
retriever := NewMetadataRetriever(compiler)
52+
regoCheckIDs := make(map[string]struct{})
53+
5054
for _, module := range modules {
5155
metadata, err := retriever.RetrieveMetadata(ctx, module)
5256
if err != nil {
57+
log.Warn("Failed to retrieve metadata", log.String("avdid", metadata.AVDID), log.Err(err))
5358
continue
5459
}
60+
5561
if metadata.AVDID == "" {
62+
log.Warn("Check ID is empty", log.FilePath(module.Package.Location.File))
5663
continue
5764
}
58-
rules.Register(
59-
metadata.ToRule(),
60-
)
65+
66+
if !metadata.Deprecated {
67+
regoCheckIDs[metadata.AVDID] = struct{}{}
68+
}
69+
70+
rules.Register(metadata.ToRule())
71+
}
72+
73+
for _, check := range rules.GetRegistered() {
74+
if !check.Deprecated && check.CanCheck() {
75+
if _, exists := regoCheckIDs[check.AVDID]; exists {
76+
log.Warn("Ignore duplicate Go check", log.String("avdid", check.AVDID))
77+
rules.Deregister(check)
78+
}
79+
}
6180
}
6281
}
6382

@@ -95,8 +114,7 @@ func LoadPoliciesFromDirs(target fs.FS, paths ...string) (map[string]*ast.Module
95114
ProcessAnnotation: true,
96115
})
97116
if err != nil {
98-
// s.debug.Log("Failed to load module: %s, err: %s", filepath.ToSlash(path), err.Error())
99-
return err
117+
return fmt.Errorf("failed to parse Rego module: %w", err)
100118
}
101119
modules[path] = module
102120
return nil

pkg/iac/rego/embed_test.go

+48
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package rego
22

33
import (
44
"testing"
5+
"testing/fstest"
56

67
"github.com/open-policy-agent/opa/ast"
78
"github.com/stretchr/testify/assert"
@@ -10,6 +11,7 @@ import (
1011
checks "github.com/aquasecurity/trivy-checks"
1112
"github.com/aquasecurity/trivy/pkg/iac/rules"
1213
"github.com/aquasecurity/trivy/pkg/iac/scan"
14+
"github.com/aquasecurity/trivy/pkg/iac/state"
1315
)
1416

1517
func Test_EmbeddedLoading(t *testing.T) {
@@ -204,3 +206,49 @@ deny[res]{
204206
})
205207
}
206208
}
209+
210+
func Test_IgnoreDuplicateChecks(t *testing.T) {
211+
rules.Reset()
212+
213+
r := scan.Rule{
214+
AVDID: "TEST001",
215+
Check: func(s *state.State) (results scan.Results) {
216+
for _, bucket := range s.AWS.S3.Buckets {
217+
if bucket.Name.Value() == "evil" {
218+
results.Add("Bucket name should not be evil", bucket.Name)
219+
}
220+
}
221+
return
222+
},
223+
}
224+
reg := rules.Register(r)
225+
defer rules.Deregister(reg)
226+
227+
fsys := fstest.MapFS{
228+
"test.rego": &fstest.MapFile{
229+
Data: []byte(`
230+
# METADATA
231+
# title: "Test rego"
232+
# scope: package
233+
# schemas:
234+
# - input: schema["cloud"]
235+
# custom:
236+
# avd_id: TEST001
237+
# severity: LOW
238+
package user.test001
239+
240+
deny[res] {
241+
res := result.new("test", {})
242+
}
243+
`),
244+
},
245+
}
246+
247+
modules, err := LoadPoliciesFromDirs(fsys, ".")
248+
require.NoError(t, err)
249+
250+
RegisterRegoRules(modules)
251+
registered := rules.GetRegistered()
252+
assert.Len(t, registered, 1)
253+
assert.Equal(t, "TEST001", registered[0].AVDID)
254+
}

0 commit comments

Comments
 (0)