Data loss vulnerability from disabled deletion protection on RDS instances

High Risk infrastructure-security
awsrdsdatabasedata-lossdeletion-protectionterraforminfrastructure-security

What it is

AWS RDS database instances configured without deletion protection can be accidentally or maliciously deleted, causing permanent data loss and service disruption. Without this safeguard, a single API call or console action can immediately destroy production databases and all their data, with no recovery option beyond point-in-time restore from backups.

# VULNERABLE: RDS without deletion protection
resource "aws_db_instance" "vulnerable" {
  identifier           = "production-db"
  engine              = "postgres"
  engine_version      = "14.7"
  instance_class      = "db.t3.medium"
  allocated_storage   = 100
  db_name             = "appdb"
  username            = "admin"
  password            = var.db_password
  
  # VULNERABLE: No deletion protection
  # deletion_protection defaults to false
  
  backup_retention_period = 7
  skip_final_snapshot    = false
  final_snapshot_identifier = "production-db-final-snapshot"
  
  tags = {
    Environment = "production"
    Critical    = "true"
  }
}

# VULNERABLE: Multi-AZ RDS still unprotected
resource "aws_db_instance" "vulnerable_multi_az" {
  identifier           = "app-database"
  engine              = "mysql"
  engine_version      = "8.0.32"
  instance_class      = "db.r5.large"
  allocated_storage   = 500
  multi_az            = true
  
  # VULNERABLE: Can be deleted despite multi-AZ
  deletion_protection = false
  
  tags = {
    Application = "critical-app"
  }
}
# SECURE: RDS with deletion protection enabled
resource "aws_db_instance" "secure" {
  identifier           = "production-db"
  engine              = "postgres"
  engine_version      = "14.7"
  instance_class      = "db.t3.medium"
  allocated_storage   = 100
  db_name             = "appdb"
  username            = "admin"
  password            = var.db_password
  
  # SECURE: Enable deletion protection
  deletion_protection = true
  
  # Additional data protection
  backup_retention_period    = 30
  skip_final_snapshot       = false
  final_snapshot_identifier = "production-db-final-snapshot"
  copy_tags_to_snapshot     = true
  
  # Enable encryption
  storage_encrypted = true
  
  tags = {
    Environment = "production"
    Critical    = "true"
  }
}

# SECURE: Multi-AZ with deletion protection
resource "aws_db_instance" "secure_multi_az" {
  identifier           = "app-database"
  engine              = "mysql"
  engine_version      = "8.0.32"
  instance_class      = "db.r5.large"
  allocated_storage   = 500
  multi_az            = true
  
  # SECURE: Deletion protection enabled
  deletion_protection = true
  
  backup_retention_period = 30
  storage_encrypted      = true
  
  tags = {
    Application = "critical-app"
  }
}

💡 Why This Fix Works

The vulnerable configurations either omit the deletion_protection parameter (defaulting to false) or explicitly set it to false, allowing the RDS instance to be deleted with a single API call or console action. The secure version sets deletion_protection to true, which requires this setting to be disabled before the database can be deleted, providing a critical safeguard against accidental or malicious deletion of production databases.

Why it happens

RDS database instances are created without explicitly setting deletion_protection to true. Since this parameter defaults to false, databases remain vulnerable to accidental or malicious deletion through the AWS console or API.

Root causes

Missing Deletion Protection Flag

RDS database instances are created without explicitly setting deletion_protection to true. Since this parameter defaults to false, databases remain vulnerable to accidental or malicious deletion through the AWS console or API.

Insecure Default Configuration

AWS RDS defaults to deletion_protection = false for easier testing and development workflows. Production databases inherit this insecure default unless teams explicitly enable protection, creating a dangerous gap in data safety.

Incomplete Infrastructure-as-Code Reviews

Terraform or CloudFormation templates lack deletion protection configuration, and code reviews fail to catch this omission. Database modules and templates may not include this critical safety parameter.

Speed Over Safety Development Culture

Teams prioritize rapid development and deployment cycles over implementing data safety guardrails. Deletion protection may be seen as an obstacle to quick database iteration and testing.

Missing Database Provisioning Standards

Organizations lack standardized database provisioning processes and automated guardrails. No policies or automated checks ensure deletion protection is enabled for production databases during deployment.

Fixes

1

Enable Deletion Protection Parameter

Set deletion_protection = true on all RDS database instances in your Terraform or CloudFormation configurations. This prevents the database from being deleted until this setting is explicitly disabled, providing a critical safeguard.

2

Apply Protection to All Production Databases

Audit all existing production RDS instances and enable deletion protection via the AWS console or CLI. Make this a mandatory requirement in your database deployment checklist and infrastructure code templates.

3

Enforce Protection with Service Control Policies

Use AWS Organizations Service Control Policies (SCPs) to prevent creation of RDS instances without deletion protection in production accounts. This provides organization-wide enforcement at the account level.

4

Implement Multi-Factor Delete Processes

For critical databases, implement additional safeguards beyond deletion protection such as requiring multi-factor authentication for any IAM principals with rds:DeleteDBInstance permissions, and approval workflows for database modifications.

5

Monitor with AWS Config Rules

Deploy AWS Config rules like rds-instance-deletion-protection-enabled to continuously monitor and alert on any RDS instances without deletion protection. Integrate these alerts into your security monitoring and incident response processes.

Detect This Vulnerability in Your Code

Sourcery automatically identifies data loss vulnerability from disabled deletion protection on rds instances and many other security issues in your codebase.