Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
simar7 committed Feb 27, 2023
1 parent 0b4688c commit cff8f53
Show file tree
Hide file tree
Showing 2 changed files with 263 additions and 51 deletions.
6 changes: 5 additions & 1 deletion pkg/rego/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ func isPolicyWithSubtype(sourceType types.Source) bool {
}

func checkSubtype(ii map[string]interface{}, provider string, subTypes []SubType) bool {
if len(subTypes) == 0 { // policy always applies if no subtypes
return true
}

for _, st := range subTypes {
switch services := ii[provider].(type) {
case map[string]interface{}: // cloud
Expand All @@ -310,7 +314,7 @@ func isPolicyApplicable(staticMetadata *StaticMetadata, inputs ...Input) bool {
if ii, ok := input.Contents.(map[string]interface{}); ok {
for provider := range ii {
// TODO(simar): Add other providers
if !strings.Contains(strings.Join([]string{"kind", "aws"}, ","), provider) {
if !strings.Contains(strings.Join([]string{"kind", "aws", "azure"}, ","), provider) {
continue
}

Expand Down
308 changes: 258 additions & 50 deletions pkg/scanners/cloud/aws/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package aws

import (
"context"
"io/fs"
"testing"

"github.com/aquasecurity/defsec/pkg/providers/azure"
"github.com/aquasecurity/defsec/pkg/providers/azure/authorization"

"github.com/aquasecurity/defsec/pkg/providers/aws/iam"

"github.com/aquasecurity/defsec/pkg/framework"
"github.com/aquasecurity/defsec/pkg/providers/aws"
"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/providers/aws/rds"
"github.com/aquasecurity/defsec/pkg/scanners/options"
"github.com/aquasecurity/defsec/pkg/state"
Expand Down Expand Up @@ -53,10 +58,189 @@ func TestScanner_GetRegisteredRules(t *testing.T) {
}
}

func Test_checkPolicyIsApplicable(t *testing.T) {
t.Run("single cloud", func(t *testing.T) {
srcFS := testutil.CreateFS(t, map[string]string{
"policies/rds_policy.rego": `# METADATA
func Test_AWSInputSelectors(t *testing.T) {
testCases := []struct {
name string
srcFS fs.FS
state state.State
expectedResults struct {
totalResults int
summaries []string
}
}{
{
name: "selector is not defined",
srcFS: testutil.CreateFS(t, map[string]string{
"policies/rds_policy.rego": `# METADATA
# title: "RDS Publicly Accessible"
# custom:
# input:
package builtin.aws.rds.aws0999
deny[res] {
res := true
}
`,
"policies/cloudtrail_policy.rego": `# METADATA
# title: "CloudTrail Bucket Delete Policy"
# custom:
# input:
package builtin.aws.cloudtrail.aws0888
deny[res] {
res := true
}
`,
}),
state: state.State{AWS: aws.AWS{
RDS: rds.RDS{
Instances: []rds.Instance{
{Metadata: defsecTypes.Metadata{},
PublicAccess: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
},
},
},
// note: there is no CloudTrail resource in our AWS state (so we expect no results for it)
}},
expectedResults: struct {
totalResults int
summaries []string
}{totalResults: 0},
},
{
name: "selector is empty",
srcFS: testutil.CreateFS(t, map[string]string{
"policies/rds_policy.rego": `# METADATA
# title: "RDS Publicly Accessible"
# custom:
# input:
# selector:
package builtin.aws.rds.aws0999
deny[res] {
res := true
}
`,
"policies/cloudtrail_policy.rego": `# METADATA
# title: "CloudTrail Bucket Delete Policy"
# custom:
# input:
# selector:
package builtin.aws.cloudtrail.aws0888
deny[res] {
res := true
}
`,
}),
state: state.State{AWS: aws.AWS{
RDS: rds.RDS{
Instances: []rds.Instance{
{Metadata: defsecTypes.Metadata{},
PublicAccess: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
},
},
},
}},
expectedResults: struct {
totalResults int
summaries []string
}{totalResults: 0},
},
{
name: "selector without subtype",
srcFS: testutil.CreateFS(t, map[string]string{
"policies/rds_policy.rego": `# METADATA
# title: "RDS Publicly Accessible"
# custom:
# input:
# selector:
# - type: cloud
package builtin.aws.rds.aws0999
deny[res] {
res := true
}
`,
"policies/cloudtrail_policy.rego": `# METADATA
# title: "CloudTrail Bucket Delete Policy"
# custom:
# input:
# selector:
# - type: cloud
package builtin.aws.cloudtrail.aws0888
deny[res] {
res := true
}
`,
}),
state: state.State{AWS: aws.AWS{
RDS: rds.RDS{
Instances: []rds.Instance{
{Metadata: defsecTypes.Metadata{},
PublicAccess: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
},
},
},
// note: there is no CloudTrail resource in our AWS state (so we expect no results for it)
}},
expectedResults: struct {
totalResults int
summaries []string
}{totalResults: 2, summaries: []string{"RDS Publicly Accessible", "CloudTrail Bucket Delete Policy"}},
},
{
name: "selector is defined with empty subtype",
srcFS: testutil.CreateFS(t, map[string]string{
"policies/rds_policy.rego": `# METADATA
# title: "RDS Publicly Accessible"
# custom:
# input:
# selector:
# - type: cloud
# subtypes:
package builtin.aws.rds.aws0999
deny[res] {
res := true
}
`,
"policies/cloudtrail_policy.rego": `# METADATA
# title: "CloudTrail Bucket Delete Policy"
# custom:
# input:
# selector:
# - type: cloud
# subtypes:
package builtin.aws.cloudtrail.aws0888
deny[res] {
res := true
}
`,
}),
state: state.State{AWS: aws.AWS{
RDS: rds.RDS{
Instances: []rds.Instance{
{Metadata: defsecTypes.Metadata{},
PublicAccess: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
},
},
},
// note: there is no CloudTrail resource in our AWS state (so we expect no results for it)
}},
expectedResults: struct {
totalResults int
summaries []string
}{totalResults: 2, summaries: []string{"RDS Publicly Accessible", "CloudTrail Bucket Delete Policy"}},
},
{
name: "single cloud, single selector",
srcFS: testutil.CreateFS(t, map[string]string{
"policies/rds_policy.rego": `# METADATA
# title: "RDS Publicly Accessible"
# description: "Ensures RDS instances are not launched into the public cloud."
# scope: package
Expand Down Expand Up @@ -85,7 +269,7 @@ deny[res] {
res := result.new("Instance has Public Access enabled", instance.publicaccess)
}
`,
"policies/cloudtrail_policy.rego": `# METADATA
"policies/cloudtrail_policy.rego": `# METADATA
# title: "CloudTrail Bucket Delete Policy"
# description: "Ensures CloudTrail logging bucket has a policy to prevent deletion of logs without an MFA token"
# scope: package
Expand Down Expand Up @@ -117,33 +301,26 @@ deny[res] {
res := result.new("Bucket has MFA delete disabled", bucket.name)
}
`,
})
scanner := New(
options.ScannerWithEmbeddedPolicies(false),
options.ScannerWithPolicyFilesystem(srcFS),
options.ScannerWithRegoOnly(true),
options.ScannerWithPolicyDirs("policies/"))

st := state.State{AWS: aws.AWS{
RDS: rds.RDS{
Instances: []rds.Instance{
{Metadata: defsecTypes.Metadata{},
PublicAccess: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
}),
state: state.State{AWS: aws.AWS{
RDS: rds.RDS{
Instances: []rds.Instance{
{Metadata: defsecTypes.Metadata{},
PublicAccess: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
},
},
},
},
// note: there is no CloudTrail resource in our AWS state (so we expect no results for it)
}}

results, err := scanner.Scan(context.TODO(), &st)
require.NoError(t, err)
require.Equal(t, 1, len(results))
require.Equal(t, "RDS Publicly Accessible", results.GetFailed()[0].Rule().Summary)
})

t.Run("multi cloud with similarly named services", func(t *testing.T) {
srcFS := testutil.CreateFS(t, map[string]string{
"policies/azure_iam_policy.rego": `# METADATA
// note: there is no CloudTrail resource in our AWS state (so we expect no results for it)
}},
expectedResults: struct {
totalResults int
summaries []string
}{totalResults: 1, summaries: []string{"RDS Publicly Accessible"}},
},
{
name: "multi cloud, single selector, same named service",
srcFS: testutil.CreateFS(t, map[string]string{
"policies/azure_iam_policy.rego": `# METADATA
# title: "Azure IAM Policy"
# custom:
# input:
Expand All @@ -158,7 +335,7 @@ deny[res] {
res := true
}
`,
"policies/aws_iam_policy.rego": `# METADATA
"policies/aws_iam_policy.rego": `# METADATA
# title: "AWS IAM Policy"
# custom:
# input:
Expand All @@ -173,23 +350,54 @@ deny[res] {
res := true
}
`,
})
scanner := New(
options.ScannerWithEmbeddedPolicies(false),
options.ScannerWithPolicyFilesystem(srcFS),
options.ScannerWithRegoOnly(true),
options.ScannerWithPolicyDirs("policies/"))

st := state.State{AWS: aws.AWS{
IAM: iam.IAM{
PasswordPolicy: iam.PasswordPolicy{MinimumLength: defsecTypes.Int(1, defsecTypes.NewTestMetadata())},
}),
state: state.State{
AWS: aws.AWS{
IAM: iam.IAM{
PasswordPolicy: iam.PasswordPolicy{
MinimumLength: defsecTypes.Int(1, defsecTypes.NewTestMetadata()),
}},
},
Azure: azure.Azure{
Authorization: authorization.Authorization{
[]authorization.RoleDefinition{{
Metadata: defsecTypes.NewTestMetadata(),
Permissions: []authorization.Permission{
{
Metadata: defsecTypes.NewTestMetadata(),
Actions: []defsecTypes.StringValue{
defsecTypes.String("*", defsecTypes.NewTestMetadata()),
},
},
},
AssignableScopes: []defsecTypes.StringValue{
defsecTypes.StringUnresolvable(defsecTypes.NewTestMetadata()),
}},
}},
},
// note: there is no Azure IAM in our cloud state (so we expect no results for it)
},
// note: there is no Azure IAM in our cloud state (so we expect no results for it)
}}

results, err := scanner.Scan(context.TODO(), &st)
require.NoError(t, err)
require.Equal(t, 1, len(results))
require.Equal(t, "AWS IAM Policy", results.GetFailed()[0].Rule().Summary)
})
expectedResults: struct {
totalResults int
summaries []string
}{totalResults: 1, summaries: []string{"AWS IAM Policy"}},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
scanner := New(
options.ScannerWithEmbeddedPolicies(false),
options.ScannerWithPolicyFilesystem(tc.srcFS),
options.ScannerWithRegoOnly(true),
options.ScannerWithPolicyDirs("policies/"))

results, err := scanner.Scan(context.TODO(), &tc.state)
require.NoError(t, err, tc.name)
require.Equal(t, tc.expectedResults.totalResults, len(results), tc.name)
for i := range results.GetFailed() {
require.Contains(t, tc.expectedResults.summaries, results.GetFailed()[i].Rule().Summary, tc.name)
}
})
}
}

0 comments on commit cff8f53

Please sign in to comment.