diff --git a/pkg/scanner/local/scan.go b/pkg/scanner/local/scan.go index 63822852cb71..edb39b15ae8f 100644 --- a/pkg/scanner/local/scan.go +++ b/pkg/scanner/local/scan.go @@ -211,7 +211,8 @@ func (s Scanner) fillPkgsInVulns(pkgResults, vulnResults types.Results) types.Re } func (s Scanner) misconfsToResults(misconfs []ftypes.Misconfiguration, options types.ScanOptions) types.Results { - if !ShouldScanMisconfigOrRbac(options.Scanners) { + if !ShouldScanMisconfigOrRbac(options.Scanners) && + !options.ImageConfigScanners.Enabled(types.MisconfigScanner) { return nil } diff --git a/pkg/scanner/local/scan_test.go b/pkg/scanner/local/scan_test.go index 5b5b8e9fd5d3..2cee7311f73f 100644 --- a/pkg/scanner/local/scan_test.go +++ b/pkg/scanner/local/scan_test.go @@ -1111,6 +1111,132 @@ func TestScanner_Scan(t *testing.T) { }, wantErr: "failed to scan application libraries", }, + { + name: "scan image history", + args: args{ + target: "alpine:latest", + layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, + options: types.ScanOptions{ + ImageConfigScanners: types.Scanners{types.MisconfigScanner}, + }, + }, + fixtures: []string{"testdata/fixtures/happy.yaml"}, + applyLayersExpectation: ApplierApplyLayersExpectation{ + Args: ApplierApplyLayersArgs{ + BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, + }, + Returns: ApplierApplyLayersReturns{ + Detail: ftypes.ArtifactDetail{ + OS: ftypes.OS{ + Family: ftypes.Alpine, + Name: "3.11", + }, + Misconfigurations: []ftypes.Misconfiguration{ + { + FileType: ftypes.Dockerfile, + FilePath: "Dockerfile", + Successes: ftypes.MisconfResults{ + { + Namespace: "builtin.dockerfile.DS001", + Query: "data.builtin.dockerfile.DS001.deny", + Message: "", + PolicyMetadata: ftypes.PolicyMetadata{ + ID: "DS001", + AVDID: "AVD-DS-0001", + Type: "Dockerfile Security Check", + Title: "':latest' tag used", + Description: "When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.", + Severity: "MEDIUM", + RecommendedActions: "Add a tag to the image in the 'FROM' statement", + }, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + }, + }, + Failures: ftypes.MisconfResults{ + { + Namespace: "builtin.dockerfile.DS002", + Query: "data.builtin.dockerfile.DS002.deny", + Message: "Specify at least 1 USER command in Dockerfile with non-root user as argument", + PolicyMetadata: ftypes.PolicyMetadata{ + ID: "DS002", + AVDID: "AVD-DS-0002", + Type: "Dockerfile Security Check", + Title: "Image user should not be 'root'", + Description: "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.", + Severity: "HIGH", + RecommendedActions: "Add 'USER ' line to the Dockerfile", + }, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + }, + }, + }, + }, + }, + }, + }, + wantResults: types.Results{ + { + Target: "Dockerfile", + Class: types.ClassConfig, + Type: ftypes.Dockerfile, + Misconfigurations: []types.DetectedMisconfiguration{ + { + Namespace: "builtin.dockerfile.DS002", + Query: "data.builtin.dockerfile.DS002.deny", + Message: "Specify at least 1 USER command in Dockerfile with non-root user as argument", + Type: "Dockerfile Security Check", + ID: "DS002", + AVDID: "AVD-DS-0002", + Title: "Image user should not be 'root'", + Description: "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.", + Severity: "HIGH", + Resolution: "Add 'USER ' line to the Dockerfile", + Status: types.StatusFailure, + PrimaryURL: "https://avd.aquasec.com/misconfig/ds002", + References: []string{"https://avd.aquasec.com/misconfig/ds002"}, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + }, + { + Namespace: "builtin.dockerfile.DS001", + Query: "data.builtin.dockerfile.DS001.deny", + Message: "No issues found", + Type: "Dockerfile Security Check", + ID: "DS001", + AVDID: "AVD-DS-0001", + Title: "':latest' tag used", + Description: "When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.", + Severity: "MEDIUM", + Resolution: "Add a tag to the image in the 'FROM' statement", + Status: types.StatusPassed, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + PrimaryURL: "https://avd.aquasec.com/misconfig/ds001", + References: []string{"https://avd.aquasec.com/misconfig/ds001"}, + }, + }, + }, + }, + wantOS: ftypes.OS{ + Family: "alpine", + Name: "3.11", + Eosl: false, + }, + }, } for _, tt := range tests {