Public Resource Exposure

Public Resource Exposure

Public resource exposure remains the most common and damaging IaC vulnerability. Cloud providers design services to be secure by default, but IaC configurations can inadvertently override these defaults. S3 buckets made public through misconfigured ACLs or policies have led to countless data breaches. Databases exposed to the internet through security group misconfigurations provide attackers with direct access to sensitive data.

The complexity of cloud networking contributes to public exposure vulnerabilities. Developers might not fully understand the implications of CIDR blocks like 0.0.0.0/0 or the interaction between network ACLs and security groups. IaC templates copied from tutorials or examples often contain permissive network configurations suitable for learning but dangerous in production.

# Common PUBLIC EXPOSURE vulnerabilities in Terraform

# VULNERABLE: S3 bucket with public read access
resource "aws_s3_bucket" "vulnerable_bucket" {
  bucket = "my-app-data"
  acl    = "public-read"  # DANGER: Anyone can read bucket contents
}

# VULNERABLE: S3 bucket with public access through bucket policy
resource "aws_s3_bucket_policy" "vulnerable_policy" {
  bucket = aws_s3_bucket.data.id
  
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "PublicReadGetObject"
        Effect    = "Allow"
        Principal = "*"  # DANGER: Allows anyone
        Action    = "s3:GetObject"
        Resource  = "${aws_s3_bucket.data.arn}/*"
      }
    ]
  })
}

# SECURE: S3 bucket with proper access controls
resource "aws_s3_bucket" "secure_bucket" {
  bucket = "my-app-data"
}

resource "aws_s3_bucket_public_access_block" "secure_bucket_pab" {
  bucket = aws_s3_bucket.secure_bucket.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_acl" "secure_bucket_acl" {
  bucket = aws_s3_bucket.secure_bucket.id
  acl    = "private"
}

# VULNERABLE: RDS instance exposed to internet
resource "aws_db_instance" "vulnerable_database" {
  identifier     = "myapp-database"
  engine         = "postgres"
  instance_class = "db.t3.micro"
  
  username = "admin"
  password = "changeme123"  # Additional vulnerability: hardcoded password
  
  publicly_accessible = true  # DANGER: Database accessible from internet
  
  vpc_security_group_ids = [aws_security_group.vulnerable_db_sg.id]
}

# VULNERABLE: Security group allowing all inbound traffic
resource "aws_security_group" "vulnerable_db_sg" {
  name = "database-sg"
  
  ingress {
    from_port   = 5432
    to_port     = 5432
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]  # DANGER: Allows connections from anywhere
  }
}

# SECURE: RDS instance with proper network isolation
resource "aws_db_instance" "secure_database" {
  identifier     = "myapp-database"
  engine         = "postgres"
  instance_class = "db.t3.micro"
  
  username = "admin"
  password = random_password.db_password.result
  
  publicly_accessible    = false  # Not accessible from internet
  db_subnet_group_name   = aws_db_subnet_group.private.name
  vpc_security_group_ids = [aws_security_group.secure_db_sg.id]
  
  storage_encrypted = true  # Additional security: encryption at rest
  
  backup_retention_period = 7
  backup_window          = "03:00-04:00"
}

# SECURE: Security group with restricted access
resource "aws_security_group" "secure_db_sg" {
  name   = "database-sg"
  vpc_id = aws_vpc.main.id
  
  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.app_sg.id]  # Only from app servers
  }
  
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["127.0.0.1/32"]  # No outbound connections
  }
}

Load balancers and API gateways present similar exposure risks. While these resources legitimately need internet access, misconfigurations can expose backend services unintentionally. Missing authentication requirements, overly permissive CORS policies, or incorrect target group configurations create attack vectors.