From 09e37b7c67664ca28923d392dc33fb1ca2600d35 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Fri, 29 Mar 2024 04:12:23 +0300 Subject: [PATCH] feat(aws): apply filter options to result (#6367) --- pkg/cloud/aws/commands/run_test.go | 81 ++++++++++++++++++++ pkg/cloud/aws/commands/testdata/.trivyignore | 8 ++ pkg/cloud/report/report.go | 10 ++- pkg/result/filter.go | 2 +- pkg/result/ignore.go | 2 +- 5 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 pkg/cloud/aws/commands/testdata/.trivyignore diff --git a/pkg/cloud/aws/commands/run_test.go b/pkg/cloud/aws/commands/run_test.go index feacdcc5a762..fe25bf20098d 100644 --- a/pkg/cloud/aws/commands/run_test.go +++ b/pkg/cloud/aws/commands/run_test.go @@ -267,6 +267,63 @@ const expectedS3ScanResult = `{ } ` +const expectedS3ScanResultWithExceptions = `{ + "CreatedAt": "2021-08-25T12:20:30.000000005Z", + "ArtifactName": "12345678", + "ArtifactType": "aws_account", + "Metadata": { + "ImageConfig": { + "architecture": "", + "created": "0001-01-01T00:00:00Z", + "os": "", + "rootfs": { + "type": "", + "diff_ids": null + }, + "config": {} + } + }, + "Results": [ + { + "Target": "arn:aws:s3:::examplebucket", + "Class": "config", + "Type": "cloud", + "MisconfSummary": { + "Successes": 0, + "Failures": 1, + "Exceptions": 8 + }, + "Misconfigurations": [ + { + "Type": "AWS", + "ID": "AVD-AWS-0094", + "AVDID": "AVD-AWS-0094", + "Title": "S3 buckets should each define an aws_s3_bucket_public_access_block", + "Description": "The \"block public access\" settings in S3 override individual policies that apply to a given bucket, meaning that all public access can be controlled in one central types for that bucket. It is therefore good practice to define these settings for each bucket in order to clearly define the public access that can be allowed for it.", + "Message": "Bucket does not have a corresponding public access block.", + "Resolution": "Define a aws_s3_bucket_public_access_block for the given bucket to control public access policies", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0094", + "References": [ + "https://avd.aquasec.com/misconfig/avd-aws-0094" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Resource": "arn:aws:s3:::examplebucket", + "Provider": "aws", + "Service": "s3", + "Code": { + "Lines": null + } + } + } + ] + } + ] +} +` + const expectedCustomScanResult = `{ "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "12345678", @@ -915,6 +972,7 @@ func Test_Run(t *testing.T) { regoPolicy string allServices []string inputData string + ignoreFile string }{ { name: "succeed with cached infra", @@ -1140,6 +1198,25 @@ Summary Report for compliance: my-custom-spec cacheContent: "testdata/s3andcloudtrailcache.json", expectErr: true, }, + { + name: "ignore findings with .trivyignore", + options: flag.Options{ + RegoOptions: flag.RegoOptions{SkipPolicyUpdate: true}, + AWSOptions: flag.AWSOptions{ + Region: "us-east-1", + Services: []string{"s3"}, + Account: "12345678", + }, + CloudOptions: flag.CloudOptions{ + MaxCacheAge: time.Hour * 24 * 365 * 100, + }, + MisconfOptions: flag.MisconfOptions{IncludeNonFailures: true}, + }, + cacheContent: "testdata/s3onlycache.json", + allServices: []string{"s3"}, + ignoreFile: "testdata/.trivyignore", + want: expectedS3ScanResultWithExceptions, + }, } ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) @@ -1192,6 +1269,10 @@ Summary Report for compliance: my-custom-spec require.NoError(t, os.WriteFile(cacheFile, cacheData, 0600)) } + if test.ignoreFile != "" { + test.options.ReportOptions.IgnoreFile = test.ignoreFile + } + err := Run(ctx, test.options) if test.expectErr { assert.Error(t, err) diff --git a/pkg/cloud/aws/commands/testdata/.trivyignore b/pkg/cloud/aws/commands/testdata/.trivyignore new file mode 100644 index 000000000000..44ef395ee173 --- /dev/null +++ b/pkg/cloud/aws/commands/testdata/.trivyignore @@ -0,0 +1,8 @@ +AVD-AWS-0086 +AVD-AWS-0087 +AVD-AWS-0088 +AVD-AWS-0090 +AVD-AWS-0132 +AVD-AWS-0091 +AVD-AWS-0092 +AVD-AWS-0093 \ No newline at end of file diff --git a/pkg/cloud/report/report.go b/pkg/cloud/report/report.go index b2a9d50cf507..2b2f8f3f17ea 100644 --- a/pkg/cloud/report/report.go +++ b/pkg/cloud/report/report.go @@ -70,16 +70,18 @@ func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) e return writeCompliance(ctx, rep, opt, output) } + ignoreConf, err := result.ParseIgnoreFile(ctx, opt.IgnoreFile) + if err != nil { + return xerrors.Errorf("%s error: %w", opt.IgnoreFile, err) + } + var filtered []types.Result // filter results for _, resultsAtTime := range rep.Results { for _, res := range resultsAtTime.Results { resCopy := res - if err := result.FilterResult(ctx, &resCopy, result.IgnoreConfig{}, result.FilterOption{ - Severities: opt.Severities, - IncludeNonFailures: opt.IncludeNonFailures, - }); err != nil { + if err := result.FilterResult(ctx, &resCopy, ignoreConf, opt.FilterOpts()); err != nil { return err } sort.Slice(resCopy.Misconfigurations, func(i, j int) bool { diff --git a/pkg/result/filter.go b/pkg/result/filter.go index 6edcef72046a..dc92d8aff5ec 100644 --- a/pkg/result/filter.go +++ b/pkg/result/filter.go @@ -37,7 +37,7 @@ type FilterOption struct { // Filter filters out the report func Filter(ctx context.Context, report types.Report, opt FilterOption) error { - ignoreConf, err := parseIgnoreFile(ctx, opt.IgnoreFile) + ignoreConf, err := ParseIgnoreFile(ctx, opt.IgnoreFile) if err != nil { return xerrors.Errorf("%s error: %w", opt.IgnoreFile, err) } diff --git a/pkg/result/ignore.go b/pkg/result/ignore.go index 58e7e3c109a8..25f7d03837d7 100644 --- a/pkg/result/ignore.go +++ b/pkg/result/ignore.go @@ -181,7 +181,7 @@ func (c *IgnoreConfig) MatchLicense(licenseID, filePath string) *IgnoreFinding { return c.Licenses.Match(licenseID, filePath, nil) } -func parseIgnoreFile(ctx context.Context, ignoreFile string) (IgnoreConfig, error) { +func ParseIgnoreFile(ctx context.Context, ignoreFile string) (IgnoreConfig, error) { var conf IgnoreConfig if _, err := os.Stat(ignoreFile); errors.Is(err, fs.ErrNotExist) { // .trivyignore doesn't necessarily exist