diff --git a/pkg/iac/adapters/terraform/aws/iam/convert.go b/pkg/iac/adapters/terraform/aws/iam/convert.go index dc5008d048..700544415c 100644 --- a/pkg/iac/adapters/terraform/aws/iam/convert.go +++ b/pkg/iac/adapters/terraform/aws/iam/convert.go @@ -17,6 +17,11 @@ type wrappedDocument struct { } func ParsePolicyFromAttr(attr *terraform.Attribute, owner *terraform.Block, modules terraform.Modules) (*iam.Document, error) { + if attr == nil { + return &iam.Document{ + Metadata: owner.GetMetadata(), + }, nil + } attr.RewriteExpr(func(e hclsyntax.Expression) hclsyntax.Expression { if te, ok := e.(*hclsyntax.TemplateExpr); ok { return &terraform.PartialTemplateExpr{TemplateExpr: te} diff --git a/pkg/iac/adapters/terraform/aws/iam/policies.go b/pkg/iac/adapters/terraform/aws/iam/policies.go index c74c3b3f82..c14262c8ba 100644 --- a/pkg/iac/adapters/terraform/aws/iam/policies.go +++ b/pkg/iac/adapters/terraform/aws/iam/policies.go @@ -1,6 +1,8 @@ package iam import ( + "github.com/hashicorp/hcl/v2/hclsyntax" + "github.com/aquasecurity/iamgo" "github.com/aquasecurity/trivy/pkg/iac/providers/aws/iam" "github.com/aquasecurity/trivy/pkg/iac/terraform" @@ -140,11 +142,20 @@ func findAttachmentPolicy(modules terraform.Modules) func(resource *terraform.Bl } } - if block, err := modules.GetReferencedBlock(attr, resource); err == nil { - return findPolicy(modules)(block) + // Searching for a referenced block only makes sense for traversal expressions, + // since only they can directly reference other blocks in the configuration. + switch attr.HCLAttribute().Expr.(type) { + case *hclsyntax.RelativeTraversalExpr, *hclsyntax.ScopeTraversalExpr: + if block, err := modules.GetReferencedBlock(attr, resource); err == nil { + return findPolicy(modules)(block) + } + } + return &iam.Policy{ + Metadata: resource.GetMetadata(), + Document: iam.Document{ + Metadata: resource.GetMetadata(), + }, } - - return nil } } diff --git a/pkg/iac/adapters/terraform/aws/iam/roles_test.go b/pkg/iac/adapters/terraform/aws/iam/roles_test.go index 687a9f17f9..de02eb8071 100644 --- a/pkg/iac/adapters/terraform/aws/iam/roles_test.go +++ b/pkg/iac/adapters/terraform/aws/iam/roles_test.go @@ -338,6 +338,32 @@ resource "aws_iam_role_policy_attachment" "test" { }, }, }, + { + name: "policy is template with unknown part", + terraform: `resource "aws_iam_role" "default" { + name = "test" +} + +resource "aws_iam_role_policy_attachment" "amazon_eks_cluster_policy" { + role = aws_iam_role.default.name + policy_arn = format("arn:%s:iam::aws:policy/AmazonEKSClusterPolicy", data.aws_partition.current.partition) +} + + +data "aws_partition" "current" {} +`, + expected: []iam.Role{ + { + Name: iacTypes.StringTest("test"), + Policies: []iam.Policy{ + { + Name: iacTypes.StringTest(""), + Document: iam.Document{}, + }, + }, + }, + }, + }, } for _, test := range tests { diff --git a/pkg/iac/terraform/attribute.go b/pkg/iac/terraform/attribute.go index c8a3d68093..a536b82c98 100644 --- a/pkg/iac/terraform/attribute.go +++ b/pkg/iac/terraform/attribute.go @@ -834,7 +834,14 @@ func safeOp[T any](a *Attribute, fn func(cty.Value) T) T { // RewriteExpr applies the given function `transform` to the expression of the attribute, // recursively traversing and transforming it. func (a *Attribute) RewriteExpr(transform func(hclsyntax.Expression) hclsyntax.Expression) { - a.hclAttribute.Expr = RewriteExpr(a.hclAttribute.Expr.(hclsyntax.Expression), transform) + if a == nil || a.hclAttribute == nil { + return + } + expr, ok := a.hclAttribute.Expr.(hclsyntax.Expression) + if !ok { + return + } + a.hclAttribute.Expr = RewriteExpr(expr, transform) } // nolint: gocyclo