github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/internal/adapters/terraform/aws/iam/policies.go (about) 1 package iam 2 3 import ( 4 "github.com/aquasecurity/defsec/pkg/providers/aws/iam" 5 "github.com/aquasecurity/defsec/pkg/terraform" 6 defsecTypes "github.com/aquasecurity/defsec/pkg/types" 7 "github.com/liamg/iamgo" 8 ) 9 10 func parsePolicy(policyBlock *terraform.Block, modules terraform.Modules) (iam.Policy, error) { 11 policy := iam.Policy{ 12 Metadata: policyBlock.GetMetadata(), 13 Name: policyBlock.GetAttribute("name").AsStringValueOrDefault("", policyBlock), 14 Document: iam.Document{ 15 Metadata: defsecTypes.NewUnmanagedMetadata(), 16 Parsed: iamgo.Document{}, 17 IsOffset: false, 18 HasRefs: false, 19 }, 20 Builtin: defsecTypes.Bool(false, policyBlock.GetMetadata()), 21 } 22 var err error 23 doc, err := ParsePolicyFromAttr(policyBlock.GetAttribute("policy"), policyBlock, modules) 24 if err != nil { 25 return policy, err 26 } 27 policy.Document = *doc 28 return policy, nil 29 } 30 31 func adaptPolicies(modules terraform.Modules) (policies []iam.Policy) { 32 for _, policyBlock := range modules.GetResourcesByType("aws_iam_policy") { 33 policy, err := parsePolicy(policyBlock, modules) 34 if err != nil { 35 continue 36 } 37 policies = append(policies, policy) 38 } 39 return 40 } 41 42 // applyForDependentResource returns the result of 43 // applying the function to the dependent block from the parent block and true 44 // if the parent block was found. 45 // 46 // resource "aws_s3_bucket" "this" { 47 // bucket = ... 48 // ... 49 // } 50 // 51 // resource "aws_s3_bucket_logging" "this" { 52 // bucket = aws_s3_bucket.this.id 53 // ... 54 // } 55 func applyForDependentResource[T any]( 56 modules terraform.Modules, 57 refBlockID string, 58 refAttrName string, 59 dependentResourceType string, 60 dependentAttrName string, 61 fn func(resource *terraform.Block) T, 62 ) (T, bool) { 63 for _, resource := range modules.GetResourcesByType(dependentResourceType) { 64 relatedAttr := resource.GetAttribute(dependentAttrName) 65 if relatedAttr.IsNil() { 66 continue 67 } 68 69 refBlock, err := modules.GetBlockById(refBlockID) 70 if err != nil { 71 continue 72 } 73 74 if isDependentBlock(refBlock, refAttrName, relatedAttr) { 75 return fn(resource), true 76 } 77 } 78 var res T 79 return res, false 80 } 81 82 func isDependentBlock(refBlock *terraform.Block, refAttrName string, relatedAttr *terraform.Attribute) bool { 83 refAttr := refBlock.GetAttribute(refAttrName).AsStringValueOrDefault("", refBlock).Value() 84 return relatedAttr.Equals(refBlock.ID()) || relatedAttr.Equals(refAttr) || relatedAttr.ReferencesBlock(refBlock) 85 } 86 87 func findPolicy(modules terraform.Modules) func(resource *terraform.Block) *iam.Policy { 88 return func(resource *terraform.Block) *iam.Policy { 89 policy, err := parsePolicy(resource, modules) 90 if err != nil { 91 return nil 92 } 93 return &policy 94 } 95 } 96 97 func findAttachmentPolicy(modules terraform.Modules) func(resource *terraform.Block) *iam.Policy { 98 return func(resource *terraform.Block) *iam.Policy { 99 policyAttr := resource.GetAttribute("policy_arn") 100 if policyAttr.IsNil() { 101 return nil 102 } 103 policyBlock, err := modules.GetReferencedBlock(policyAttr, resource) 104 if err != nil { 105 return nil 106 } 107 return findPolicy(modules)(policyBlock) 108 } 109 }