Skip to content

Commit

Permalink
fix(helm): scan the subcharts once (aquasecurity#6382)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin authored Mar 26, 2024
1 parent 97f95c4 commit f148eb1
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 9 deletions.
33 changes: 24 additions & 9 deletions pkg/iac/scanners/helm/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/fs"
"path/filepath"
"strings"
"sync"

"github.com/liamg/memoryfs"

Expand Down Expand Up @@ -38,6 +39,8 @@ type Scanner struct {
skipRequired bool
frameworks []framework.Framework
spec string
regoScanner *rego.Scanner
mu sync.Mutex
}

func (s *Scanner) SetSpec(spec string) {
Expand Down Expand Up @@ -120,6 +123,10 @@ func (s *Scanner) SetRegoErrorLimit(_ int) {}

func (s *Scanner) ScanFS(ctx context.Context, target fs.FS, path string) (scan.Results, error) {

if err := s.initRegoScanner(target); err != nil {
return nil, fmt.Errorf("failed to init rego scanner: %w", err)
}

var results []scan.Result
if err := fs.WalkDir(target, path, func(path string, d fs.DirEntry, err error) error {
select {
Expand Down Expand Up @@ -150,6 +157,7 @@ func (s *Scanner) ScanFS(ctx context.Context, target fs.FS, path string) (scan.R
} else {
results = append(results, scanResults...)
}
return fs.SkipDir
}

return nil
Expand All @@ -174,14 +182,6 @@ func (s *Scanner) getScanResults(path string, ctx context.Context, target fs.FS)
return nil, nil
}

regoScanner := rego.NewScanner(types.SourceKubernetes, s.options...)
policyFS := target
if s.policyFS != nil {
policyFS = s.policyFS
}
if err := regoScanner.LoadPolicies(s.loadEmbeddedLibraries, s.loadEmbeddedPolicies, policyFS, s.policyDirs, s.policyReaders); err != nil {
return nil, fmt.Errorf("policies load: %w", err)
}
for _, file := range chartFiles {
file := file
s.debug.Log("Processing rendered chart file: %s", file.TemplateFilePath)
Expand All @@ -191,7 +191,7 @@ func (s *Scanner) getScanResults(path string, ctx context.Context, target fs.FS)
return nil, fmt.Errorf("unmarshal yaml: %w", err)
}
for _, manifest := range manifests {
fileResults, err := regoScanner.ScanInput(ctx, rego.Input{
fileResults, err := s.regoScanner.ScanInput(ctx, rego.Input{
Path: file.TemplateFilePath,
Contents: manifest,
FS: target,
Expand Down Expand Up @@ -219,3 +219,18 @@ func (s *Scanner) getScanResults(path string, ctx context.Context, target fs.FS)
}
return results, nil
}

func (s *Scanner) initRegoScanner(srcFS fs.FS) error {
s.mu.Lock()
defer s.mu.Unlock()
if s.regoScanner != nil {
return nil
}
regoScanner := rego.NewScanner(types.SourceKubernetes, s.options...)
regoScanner.SetParentDebugLogger(s.debug)
if err := regoScanner.LoadPolicies(s.loadEmbeddedLibraries, s.loadEmbeddedPolicies, srcFS, s.policyDirs, s.policyReaders); err != nil {
return err
}
s.regoScanner = regoScanner
return nil
}
41 changes: 41 additions & 0 deletions pkg/iac/scanners/helm/test/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,44 @@ deny[res] {
require.NoError(t, err)
assert.NotNil(t, code)
}

func TestScanSubchartOnce(t *testing.T) {
check := `# METADATA
# title: "Test rego"
# description: "Test rego"
# scope: package
# schemas:
# - input: schema["kubernetes"]
# custom:
# id: ID001
# avd_id: AVD-USR-ID001
# severity: LOW
# input:
# selector:
# - type: kubernetes
# subtypes:
# - kind: pod
package user.kubernetes.ID001
import data.lib.kubernetes
deny[res] {
container := kubernetes.containers[_]
container.securityContext.readOnlyRootFilesystem == false
res := result.new("set 'securityContext.readOnlyRootFilesystem' to true", container)
}
`

scanner := helm.New(
options.ScannerWithEmbeddedPolicies(false),
options.ScannerWithEmbeddedLibraries(true),
options.ScannerWithPolicyNamespaces("user"),
options.ScannerWithPolicyReader(strings.NewReader(check)),
)

results, err := scanner.ScanFS(context.TODO(), os.DirFS("testdata/with-subchart"), ".")
require.NoError(t, err)
require.Len(t, results, 1)

assert.Len(t, results.GetFailed(), 0)
}
6 changes: 6 additions & 0 deletions pkg/iac/scanners/helm/test/testdata/with-subchart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: test
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: nginx
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 8080
securityContext:
readOnlyRootFilesystem: {{ .Values.readOnlyFs }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
readOnlyFs: false
2 changes: 2 additions & 0 deletions pkg/iac/scanners/helm/test/testdata/with-subchart/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
nginx:
readOnlyFs: true

0 comments on commit f148eb1

Please sign in to comment.