Skip to content

Commit

Permalink
fix(iam): pass all document metadata fields to rego (#81)
Browse files Browse the repository at this point in the history
* fix(iam): pass all document metadata fields to rego

* chore(deps): bump defsec

* test: mark tests as integration

---------

Co-authored-by: simar7 <[email protected]>
  • Loading branch information
nikpivkin and simar7 authored Jan 27, 2024
1 parent d0d4b1b commit 3d8e412
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 41 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/BurntSushi/toml v1.3.2
github.com/Masterminds/semver v1.5.0
github.com/apparentlymart/go-cidr v1.1.0
github.com/aquasecurity/defsec v0.94.1
github.com/aquasecurity/defsec v0.94.2-0.20240119001230-c2d65f49dfeb
github.com/aquasecurity/trivy-policies v0.8.0
github.com/aws/smithy-go v1.19.0
github.com/bmatcuk/doublestar/v4 v4.6.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/aquasecurity/defsec v0.94.1 h1:lk44bfUltm0f0Dw4DbO3Ka9d/bf3N8cWclSdHXMyKF4=
github.com/aquasecurity/defsec v0.94.1/go.mod h1:wiX9BX0SOG0ZWjVIPYGPl46fyO3Gu8lJnk4rmhFR7IA=
github.com/aquasecurity/defsec v0.94.2-0.20240119001230-c2d65f49dfeb h1:7x3aMSnQhXJLcFOCivOmNBk0zAVLKkEk5UWkrRxxHIk=
github.com/aquasecurity/defsec v0.94.2-0.20240119001230-c2d65f49dfeb/go.mod h1:wiX9BX0SOG0ZWjVIPYGPl46fyO3Gu8lJnk4rmhFR7IA=
github.com/aquasecurity/trivy-policies v0.8.0 h1:LvmIdw/DfTF72Lc8L+CKLYzfb5BFYzLBGFFR95PKC74=
github.com/aquasecurity/trivy-policies v0.8.0/go.mod h1:qF/t59pgK/0JTV6tXaeA3Iw3opzoMgzGCDcTDBmqb30=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
Expand Down
1 change: 0 additions & 1 deletion pkg/scanners/terraform/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ func (s *Scanner) ScanFSWithMetrics(ctx context.Context, target fs.FS, dir strin
}

rootModules = excludeNonRootModules(rootModules)

for _, module := range rootModules {
s.execLock.RLock()
e := executor.New(s.executorOpt...)
Expand Down
118 changes: 118 additions & 0 deletions pkg/scanners/terraform/scanner_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,121 @@ deny[res] {
fmt.Printf("Debug logs:\n%s\n", debugLog.String())
}
}

func Test_OptionWithSkipDownloaded(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}

fs := testutil.CreateFS(t, map[string]string{
"test/main.tf": `
module "s3-bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "3.14.0"
bucket = "mybucket"
create_bucket = true
}
`,
// creating our own rule for the reliability of the test
"/rules/test.rego": `
package defsec.abcdefg
__rego_input__ := {
"combine": false,
"selector": [{"type": "defsec", "subtypes": [{"service": "s3", "provider": "aws"}]}],
}
deny[cause] {
bucket := input.aws.s3.buckets[_]
bucket.name.value == "mybucket"
cause := bucket.name
}`,
})

t.Run("without skip", func(t *testing.T) {
scanner := New(
options.ScannerWithPolicyDirs("rules"),
options.ScannerWithRegoOnly(true),
options.ScannerWithEmbeddedPolicies(false),
options.ScannerWithEmbeddedLibraries(true),
)
results, err := scanner.ScanFS(context.TODO(), fs, "test")
require.NoError(t, err)

assert.Len(t, results, 1)
assert.Len(t, results.GetFailed(), 1)
})

t.Run("with skip", func(t *testing.T) {
scanner := New(
ScannerWithSkipDownloaded(true),
options.ScannerWithPolicyDirs("rules"),
options.ScannerWithRegoOnly(true),
options.ScannerWithEmbeddedPolicies(false),
options.ScannerWithEmbeddedLibraries(true),
)
results, err := scanner.ScanFS(context.TODO(), fs, "test")
require.NoError(t, err)

assert.Len(t, results, 1)
assert.Len(t, results.GetIgnored(), 1)
})
}

func Test_OptionWithSkipDownloadedIAMDocument(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}

fs := testutil.CreateFS(t, map[string]string{
"test/main.tf": `
module "karpenter" {
source = "terraform-aws-modules/eks/aws//modules/karpenter"
version = "19.21.0"
cluster_name = "test"
irsa_oidc_provider_arn = "example"
}
`,
// creating our own rule for the reliability of the test
"/rules/test.rego": `
package defsec.abcdefg
__rego_input__ := {
"combine": false,
"selector": [{"type": "defsec", "subtypes": [{"service": "iam", "provider": "aws"}]}],
}
allows_permission(statements, permission, effect) {
statement := statements[_]
statement.Effect == effect
action = statement.Action[_]
action == permission
}
deny[res] {
policy := input.aws.iam.policies[_]
value = json.unmarshal(policy.document.value)
statements = value.Statement
not allows_permission(statements, "iam:PassRole", "Deny")
allows_permission(statements, "iam:PassRole", "Allow")
res = result.new("IAM policy allows 'iam:PassRole' action", policy.document)
}
`,
})

scanner := New(
ScannerWithSkipDownloaded(true),
options.ScannerWithPolicyDirs("rules"),
options.ScannerWithRegoOnly(true),
options.ScannerWithEmbeddedLibraries(true),
options.ScannerWithEmbeddedPolicies(false),
)
results, err := scanner.ScanFS(context.TODO(), fs, "test")
require.NoError(t, err)
assert.Len(t, results, 1)

ignored := results.GetIgnored()
assert.Len(t, ignored, 1)
assert.NotNil(t, ignored[0].Metadata().Parent())
}
37 changes: 0 additions & 37 deletions pkg/scanners/terraform/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,43 +534,6 @@ deny[res] {
}
}

func Test_OptionWithSkipDownloaded(t *testing.T) {
fs := testutil.CreateFS(t, map[string]string{
"test/main.tf": `
module "s3-bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "3.14.0"
bucket = mybucket
}
`,
// creating our own rule for the reliability of the test
"/rules/test.rego": `
package defsec.abcdefg
__rego_input__ := {
"combine": false,
"selector": [{"type": "defsec", "subtypes": [{"service": "s3", "provider": "aws"}]}],
}
deny[cause] {
bucket := input.aws.s3.buckets[_]
bucket.name.value == "mybucket"
cause := bucket.name
}`,
})

scanner := New(options.ScannerWithEmbeddedPolicies(true), options.ScannerWithEmbeddedLibraries(true))
results, err := scanner.ScanFS(context.TODO(), fs, "test")
assert.NoError(t, err)
assert.Greater(t, len(results.GetFailed()), 0)

scanner = New(ScannerWithSkipDownloaded(true))
results, err = scanner.ScanFS(context.TODO(), fs, "test")
assert.NoError(t, err)
assert.Len(t, results.GetFailed(), 0)

}

func Test_IAMPolicyRego(t *testing.T) {
fs := testutil.CreateFS(t, map[string]string{
"/code/main.tf": `
Expand Down

0 comments on commit 3d8e412

Please sign in to comment.