Skip to content

Commit

Permalink
feat(aws): apply filter options to result (aquasecurity#6367)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin committed Mar 29, 2024
1 parent 87a9aa6 commit 09e37b7
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 6 deletions.
81 changes: 81 additions & 0 deletions pkg/cloud/aws/commands/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -915,6 +972,7 @@ func Test_Run(t *testing.T) {
regoPolicy string
allServices []string
inputData string
ignoreFile string
}{
{
name: "succeed with cached infra",
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions pkg/cloud/aws/commands/testdata/.trivyignore
Original file line number Diff line number Diff line change
@@ -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
10 changes: 6 additions & 4 deletions pkg/cloud/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion pkg/result/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/result/ignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 09e37b7

Please sign in to comment.