Authorization bypass from wildcard resources in IAM policy statements in Terraform

High Risk infrastructure-security
awsiamauthorizationleast-privilegewildcardresource-level-permissionsterraformauthorization-bypass

What it is

AWS IAM policies that use wildcard (*) in the Resource field for actions that support resource-level permissions create overly broad access that can lead to unauthorized operations across all AWS resources. This violates the principle of least privilege and enables potential authorization bypasses.

# VULNERABLE: Wildcard resources granting excessive permissions
data "aws_iam_policy_document" "vulnerable" {
  statement {
    sid    = "AllowS3Access"
    effect = "Allow"
    
    actions = [
      "s3:GetObject",
      "s3:PutObject",
      "s3:DeleteObject"
    ]
    
    # VULNERABLE: Access to ALL S3 buckets
    resources = ["*"]
  }
  
  statement {
    sid    = "AllowSecretsAccess"
    effect = "Allow"
    
    actions = [
      "secretsmanager:GetSecretValue"
    ]
    
    # VULNERABLE: Can read ANY secret
    resources = ["*"]
  }
  
  statement {
    sid    = "AllowRDSAccess"
    effect = "Allow"
    
    actions = [
      "rds:CreateDBSnapshot",
      "rds:DeleteDBInstance"
    ]
    
    # VULNERABLE: Affects ANY RDS resource
    resources = ["*"]
  }
}
# SECURE: Specific resource ARNs with least privilege
data "aws_iam_policy_document" "secure" {
  statement {
    sid    = "AllowSpecificS3BucketAccess"
    effect = "Allow"
    
    actions = [
      "s3:GetObject",
      "s3:PutObject"
    ]
    
    # SECURE: Only specific bucket and paths
    resources = [
      "arn:aws:s3:::app-bucket",
      "arn:aws:s3:::app-bucket/uploads/*"
    ]
    
    # SECURE: Additional condition for encryption
    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values   = ["true"]
    }
  }
  
  statement {
    sid    = "AllowSpecificSecretAccess"
    effect = "Allow"
    
    actions = [
      "secretsmanager:GetSecretValue"
    ]
    
    # SECURE: Only specific secrets
    resources = [
      "arn:aws:secretsmanager:us-east-1:123456789012:secret:app/database-*"
    ]
    
    # SECURE: Restrict by resource tags
    condition {
      test     = "StringEquals"
      variable = "secretsmanager:ResourceTag/Application"
      values   = ["myapp"]
    }
  }
  
  statement {
    sid    = "AllowSpecificRDSOperations"
    effect = "Allow"
    
    actions = [
      "rds:CreateDBSnapshot"
    ]
    
    # SECURE: Only specific RDS instances
    resources = [
      "arn:aws:rds:us-east-1:123456789012:db:myapp-*"
    ]
  }
}

💡 Why This Fix Works

The vulnerable policy uses wildcard (*) in the Resource field, granting access to all resources of each type across the entire AWS account. The secure version specifies exact ARN patterns for each resource, uses conditions to further restrict access, and applies the principle of least privilege by limiting permissions to only the resources needed for the application.

Why it happens

Developers use Resource: '*' in IAM policies for convenience during development or to avoid determining specific resource ARNs. This overly permissive pattern often makes it into production without being tightened to specific resources.

Root causes

Convenience Over Security

Developers use Resource: '*' in IAM policies for convenience during development or to avoid determining specific resource ARNs. This overly permissive pattern often makes it into production without being tightened to specific resources.

Copy-Pasted Overly Broad Permissions

Teams copy IAM policy examples from documentation, tutorials, or Stack Overflow that use wildcards for simplicity. These broad permissions are used without modification or understanding of their security implications.

Insufficient Resource Planning

Lack of understanding or documentation about which specific AWS resources an application needs to access. Without proper resource mapping, teams default to wildcard access rather than determining exact ARN patterns.

Missing IAM Policy Reviews

Inadequate security reviews of IAM policies during code review or deployment processes. Overly broad resource permissions are not flagged or questioned, allowing them to persist in production.

Unawareness of Resource-Level Permissions

Developers don't realize that many AWS actions support resource-level permissions and can be scoped to specific ARNs. They use wildcards assuming it's the only way to grant access to AWS services.

Fixes

1

Replace Wildcards with Specific ARNs

Identify and replace all Resource: '*' entries with specific AWS resource ARNs or ARN patterns. Use the AWS CLI or console to find the exact ARNs your application needs, then update IAM policies to reference only those specific resources.

2

Leverage Resource-Level Permissions

Consult the AWS documentation to determine which actions support resource-level permissions. For these actions, always specify explicit resource ARNs in your IAM policies rather than using wildcards, implementing the principle of least privilege.

3

Add IAM Condition Key Restrictions

Use IAM condition keys like aws:SourceAccount, aws:PrincipalOrgID, or service-specific conditions to further restrict access even when some wildcard usage is necessary. Conditions add additional security layers beyond resource ARN restrictions.

4

Implement Tag-Based Access Control

Apply consistent resource tagging across your AWS infrastructure and use tag-based conditions in IAM policies (e.g., aws:ResourceTag/Environment) to scope permissions dynamically based on resource attributes rather than hardcoding ARNs.

5

Establish IAM Policy Review Process

Implement automated scanning tools like AWS IAM Access Analyzer, checkov, or custom scripts to regularly audit IAM policies for overly broad resource permissions. Make policy reviews a mandatory part of your code review and deployment pipeline.

Detect This Vulnerability in Your Code

Sourcery automatically identifies authorization bypass from wildcard resources in iam policy statements in terraform and many other security issues in your codebase.