Skip to main content
KBY Technologies Logo
cd ../config-traps
risk/register/rds-inherits-the-default-security-group-you-forgot.html
AWS RDS Networkingcritical severityAWS RDS

RDS Inherits the Default Security Group You Forgot

Severity
critical
Reviewed
18 Jul 2026
Remediation
~20 minutes
Overview

A CreateDBInstance call without an explicit VpcSecurityGroupIds parameter silently attaches the VPC's default security group, and that group often still carries a 0.0.0.0/0 rule on 3306 or 5432 left over from an old migration script, exposing MySQL or PostgreSQL to the internet the moment PubliclyAccessible is set to true.

At a glance

Unsafe setting
RDS instance created without an explicit VpcSecurityGroupIds parameter, causing inheritance of the VPC's default security group.
Failure trigger
PubliclyAccessible is set to true while the inherited default security group still carries a 0.0.0.0/0 ingress rule on 3306 or 5432 from an earlier ad hoc change.
Blast radius
The database becomes directly reachable from the internet on its engine port with no bastion, VPN, or PrivateLink boundary in the path.
Recommended control
Strip ingress from the default security group, mandate explicit scoped VpcSecurityGroupIds on every RDS instance, and enforce AWS Config rules rds-instance-public-access-check and vpc-default-security-group-closed.

The Trap

Default Security Group Inheritance on RDS. When a CreateDBInstance API call, Terraform resource, or console wizard omits an explicit security group, RDS does not refuse the request or fall back to a locked-down default. It silently attaches the VPC’s “default” security group to the new instance’s network interface, whatever state that group happens to be in.

The Default State

Most VPCs still carry the AWS-created default security group, sgid ending in the VPC’s own default, with its original self-referencing ingress rule intact. That would be harmless on its own. The problem is that this group is shared infrastructure: someone, at some point, opened it to 0.0.0.0/0 on port 3306 or 5432 to unblock a one-off data load, a Lambda function that couldn’t resolve a VPC endpoint, or a contractor’s laptop. Nobody revoked the rule afterwards because the default group looks like background noise, not a production control. Separately, a Terraform module or console default sets publicly_accessible to true for a “quick dev instance” and that instance later gets promoted, cloned, or copied into a production account with the flag untouched.

The Blast Radius

The two defaults compound. PubliclyAccessible=true assigns the instance a public IP and route through the internet gateway. The inherited default security group, still carrying the stale 0.0.0.0/0 ingress rule on 3306 or 5432, permits any source address to reach the listener. There is no bastion, no VPN, no PrivateLink boundary in the path. The database becomes reachable directly from the internet using nothing but its engine port. Credential-stuffing bots that scan for open RDS ports will find it within hours, and a weak or default master password turns into full data exfiltration or ransomware encryption of the instance. AWS Config and GuardDuty may eventually flag it, but by then the damage window has already closed.

The Lead Mechanic Fix

Strip all ingress from the account’s default security group so it can never again serve as an accidental attach point: aws ec2 revoke-security-group-ingress --group-id sg-default --protocol -1 --cidr 0.0.0.0/0. Require every aws_db_instance resource to set vpc_security_group_ids explicitly to a purpose-built group scoped to the application subnet CIDR only. Enable the AWS Config managed rules rds-instance-public-access-check and vpc-default-security-group-closed with automatic remediation, and force any drift back with aws rds modify-db-instance --db-instance-identifier --no-publicly-accessible --vpc-security-group-ids sg-scoped --apply-immediately.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

aws ec2 revoke-security-group-ingress --group-id sg-default --protocol -1 --cidr 0.0.0.0/0
aws rds modify-db-instance --db-instance-identifier  --no-publicly-accessible --vpc-security-group-ids sg-scoped --apply-immediately
04

Verify, roll back or escalate

Verify

Re-run the detection test and a controlled negative-path test. Confirm the unsafe behaviour is blocked while approved traffic still succeeds.

Rollback

Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.