Amazon Relational Database Service (RDS) is the backbone of application data for thousands of organizations running on AWS. It simplifies provisioning, patching, and scaling relational databases, but it does not secure them for you. Under the AWS shared responsibility model, database configuration is entirely your responsibility.
RDS misconfigurations remain one of the most common causes of data breaches in the cloud. A single publicly exposed snapshot or an unencrypted production database can lead to regulatory fines, customer data exposure, and loss of trust that takes years to rebuild.
This article covers the 15 most critical AWS RDS security misconfigurations you should actively detect and remediate. Each entry includes the security risk, how to detect it using the AWS CLI, and clear remediation steps.
What Is AWS RDS?
Amazon RDS is a managed service that lets you provision and operate relational databases (MySQL, PostgreSQL, MariaDB, Oracle, SQL Server) in the cloud without managing the underlying infrastructure. AWS handles hardware provisioning, OS patching, and failure detection — but configuration choices around network access, encryption, authentication, and backup remain your responsibility.
The security of your RDS deployment depends entirely on how these controls are configured. Let’s look at where teams most commonly get it wrong.
The 15 Critical AWS RDS Misconfigurations
1. Publicly Accessible RDS Instances
The Risk: When the PubliclyAccessible flag is set to true, your RDS instance is assigned a public DNS name resolvable from the internet. Combined with a permissive security group, this creates a directly addressable target for brute-force attacks, SQL injection, and credential stuffing. Even with a restrictive security group, the public endpoint is discoverable via DNS enumeration.
Why It Matters: AWS Security Hub and every major compliance framework (PCI DSS, HIPAA, SOC 2, GDPR) explicitly prohibit public internet exposure of databases containing sensitive data. Public RDS instances are a top finding in penetration tests.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?PubliclyAccessible==\`true\`].{ID:DBInstanceIdentifier,Public:PubliclyAccessible,Endpoint:Endpoint.Address}" \
--output table
Remediation:
- Modify the instance to set
PubliclyAccessibletofalse. This requires the instance to be in a private subnet with no internet gateway route. - Provision RDS instances exclusively in private subnets within your VPC.
- Use VPC endpoints, bastion hosts, or AWS Systems Manager Session Manager for administrative access.
- For application connectivity, use VPC peering or AWS PrivateLink — never expose the database directly.
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--no-publicly-accessible \
--apply-immediately
2. Public RDS Snapshots
The Risk: An RDS snapshot marked as public can be copied by any AWS account in the world. An attacker can restore your snapshot into their own account, gaining full access to every row of data at the point-in-time the snapshot was created. There is no authentication required — only the knowledge that the snapshot exists.
Why It Matters: Public snapshots have caused high-profile breaches where entire customer databases were exfiltrated. This violates GDPR, HIPAA, PCI DSS, NIST 800-53, and APRA requirements for data confidentiality.
How to Detect:
# Check manual snapshots
aws rds describe-db-snapshots \
--snapshot-type manual \
--query "DBSnapshots[?contains(to_string(DBSnapshotAttributes), 'all')].{Snapshot:DBSnapshotIdentifier,Instance:DBInstanceIdentifier}" \
--include-public
# Direct check for public attribute
aws rds describe-db-snapshot-attributes \
--db-snapshot-identifier <snapshot-id> \
--query "DBSnapshotAttributesResult.DBSnapshotAttributes[?AttributeName=='restore'].AttributeValues"
If the restore attribute contains all, the snapshot is public.
Remediation:
- Remove the
allvalue from therestoreattribute of every manual snapshot. - Use AWS Config rule
rds-snapshots-public-prohibitedfor continuous monitoring. - Implement an SCP (Service Control Policy) that prevents
ModifyDBSnapshotAttributewithallas a value.
aws rds modify-db-snapshot-attribute \
--db-snapshot-identifier <snapshot-id> \
--attribute-name restore \
--values-to-remove all
3. Encryption at Rest Disabled
The Risk: Unencrypted RDS instances store data on disk in plaintext. While physical disk theft is unlikely in AWS, unencrypted data is exposed through snapshot sharing, cross-account access misconfigurations, and backup exfiltration scenarios. Additionally, encryption cannot be enabled after an instance is created — you must create an encrypted snapshot, restore from it, and migrate.
Why It Matters: AWS RDS encryption uses AES-256 and integrates with KMS. It encrypts the underlying storage, automated backups, read replicas, and snapshots. HIPAA, PCI DSS, GDPR, SOC 2, and NIST all require encryption of data at rest. Failing to encrypt at creation time creates a costly remediation path later.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?StorageEncrypted==\`false\`].{ID:DBInstanceIdentifier,Engine:Engine,Storage:StorageEncrypted}" \
--output table
Remediation:
- For new instances: Always enable encryption at creation time. Use
--storage-encryptedand specify a KMS key. - For existing unencrypted instances: Create a snapshot → copy the snapshot with encryption enabled → restore from the encrypted snapshot → switch traffic to the new instance → decommission the old one.
- Enforce encryption with AWS Config rule
rds-storage-encryptedor an SCP denyingCreateDBInstancewithout theStorageEncryptedparameter.
4. Using AWS-Managed Keys Instead of Customer-Managed Keys (CMK)
The Risk: By default, RDS encryption uses the aws/rds AWS-managed KMS key. While this provides encryption, you lose granular control over key policies, rotation schedules, cross-account access rules, and the ability to revoke access by disabling or deleting the key.
Why It Matters: Customer-managed keys (CMKs) allow you to define who can use the key, enforce automatic rotation, audit key usage via CloudTrail, and critically revoke access to encrypted data by disabling the key. For organizations with strict data sovereignty or multi-tenant requirements, CMKs are mandatory. GDPR, PCI DSS, and SOC 2 auditors often require evidence of key management controls that only CMKs provide.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?StorageEncrypted==\`true\`].{ID:DBInstanceIdentifier,KmsKey:KmsKeyId}" \
--output table
If KmsKeyId contains alias/aws/rds, the instance uses an AWS-managed key.
Remediation:
- Create a customer-managed KMS key with an appropriate key policy (restrict admin and usage permissions to specific IAM roles).
- Enable automatic key rotation (annual by default, configurable).
- For existing instances using AWS-managed keys: take an encrypted snapshot, re-encrypt the snapshot copy with your CMK, restore, and migrate traffic.
5. Transport Encryption (SSL/TLS) Not Enforced
The Risk: By default, RDS accepts both encrypted and unencrypted connections. Unless you explicitly enforce SSL/TLS at the database parameter level, applications may connect in plaintext, exposing credentials and query data to network-level interception (especially in shared VPC environments or during VPN-to-VPC transit).
Why It Matters: HIPAA and PCI DSS require encryption of data in transit. Even within a VPC, lateral movement by an attacker with network access can capture unencrypted database traffic. AWS provides free SSL certificates for RDS, there is no reason not to enforce them.
How to Detect:
For PostgreSQL, check the rds.force_ssl parameter:
aws rds describe-db-parameters \
--db-parameter-group-name <param-group> \
--query "Parameters[?ParameterName=='rds.force_ssl'].{Name:ParameterName,Value:ParameterValue}"
For MySQL/MariaDB, check require_secure_transport:
aws rds describe-db-parameters \
--db-parameter-group-name <param-group> \
--query "Parameters[?ParameterName=='require_secure_transport'].{Name:ParameterName,Value:ParameterValue}"
Remediation:
- For PostgreSQL: Set
rds.force_ssl = 1in the parameter group. - For MySQL/MariaDB: Set
require_secure_transport = 1. - For SQL Server: Enable
rds.force_sslvia the parameter group. - Ensure applications use the AWS RDS Certificate Authority bundle for certificate validation.
- Rotate to the latest CA certificate bundle periodically.
6. IAM Database Authentication Disabled
The Risk: Without IAM database authentication, access is controlled solely by database-native username/password credentials. These credentials are often static, shared across teams, stored in application config files, and rarely rotated, creating a persistent credential sprawl problem.
Why It Matters: IAM database authentication generates short-lived (15-minute) tokens tied to IAM policies. This eliminates the need for password management, integrates with AWS CloudTrail for audit logging, and allows centralized access control through IAM policies. It supports MySQL and PostgreSQL engines.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?IAMDatabaseAuthenticationEnabled==\`false\`].{ID:DBInstanceIdentifier,Engine:Engine,IAMAuth:IAMDatabaseAuthenticationEnabled}" \
--output table
Remediation:
- Enable IAM database authentication on the instance:
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--enable-iam-database-authentication \
--apply-immediately
- Create database users that authenticate via IAM (using
AWSAuthenticationPluginfor MySQL orrds_iamrole for PostgreSQL). - Update application code to generate authentication tokens using
aws rds generate-db-auth-token. - For the master user credential, integrate with AWS Secrets Manager for automatic rotation (see #7).
7. Master Credentials Not Managed by Secrets Manager
The Risk: The RDS master username and password are the highest-privilege credentials for your database. If these are hardcoded in application configs, stored in environment variables, or committed to source control, they become a persistent and high-impact attack vector.
Why It Matters: AWS now offers native integration between RDS and Secrets Manager where RDS itself manages the master password — generating, storing, and rotating it automatically every 7 days (configurable). You never see or handle the password. This eliminates the entire class of credential exposure risks for the most privileged database account.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[].{ID:DBInstanceIdentifier,SecretArn:MasterUserSecret.SecretArn}" \
--output table
If SecretArn is null/empty, the master password is not managed by Secrets Manager.
Remediation:
- For new instances: Enable “Manage master credentials in AWS Secrets Manager” during creation.
- For existing instances: Modify the instance to enable Secrets Manager management:
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--manage-master-user-password \
--master-user-secret-kms-key-id <your-cmk-arn> \
--apply-immediately
- Ensure applications that connect as the master user retrieve credentials from Secrets Manager using the AWS SDK.
- Avoid using the master user for application connections entirely, create least-privilege application-specific users.
8. Automated Backups Disabled or Insufficient Retention
The Risk: Disabling automated backups (setting retention period to 0) eliminates point-in-time recovery capability. If the database is corrupted, hit by ransomware, or accidentally modified, you have no recovery path. Even with backups enabled, a retention period shorter than your compliance requirements creates gaps.
Why It Matters: AWS Security Hub recommends a minimum 7-day backup retention. Many compliance frameworks (NIST, APRA, ISO 27001) require longer retention aligned with data classification policies. Automated backups also include transaction logs, enabling point-in-time restore to any second within the retention window; a capability lost without them.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?BackupRetentionPeriod<\`7\`].{ID:DBInstanceIdentifier,Retention:BackupRetentionPeriod}" \
--output table
Remediation:
- Set backup retention to at least 7 days (35 days maximum for RDS):
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--backup-retention-period 14 \
--apply-immediately
- Enable cross-region backup replication for disaster recovery.
- Integrate with AWS Backup for centralized backup governance, lifecycle policies, and compliance reporting.
- Test restores periodically to validate backup integrity.
9. Deletion Protection Disabled
The Risk: Without deletion protection, any IAM user or role with rds:DeleteDBInstance permission can destroy the database — whether through a compromised credential, an automation bug, or human error. The instance and all its automated backups are deleted. Only manual snapshots survive.
Why It Matters: Database deletion is one of the most destructive actions possible in a cloud environment. Deletion protection adds a mandatory two-step process: you must first disable protection, then delete preventing accidental or malicious single-command destruction.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?DeletionProtection==\`false\`].{ID:DBInstanceIdentifier,DeletionProtection:DeletionProtection}" \
--output table
Remediation:
- Enable deletion protection on all production instances:
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--deletion-protection \
--apply-immediately
- Use AWS Config rule
rds-instance-deletion-protection-enabledfor continuous compliance. - Complement with SCPs that deny
rds:DeleteDBInstanceexcept from a specific break-glass role.
10. Unrestricted Security Group Access (0.0.0.0/0)
The Risk: An RDS-associated security group with an inbound rule allowing 0.0.0.0/0 (or ::/0 for IPv6) on the database port opens your database to connection attempts from the entire internet. Combined with weak credentials or a known database vulnerability, this is a direct path to compromise.
Why It Matters: Even if the RDS instance is in a private subnet, a misconfigured security group is a defense-in-depth failure. Security groups should follow least-privilege principles allowing access only from specific application security groups, CIDR blocks, or VPC endpoints.
How to Detect:
# Get the security groups associated with RDS instances
aws rds describe-db-instances \
--query "DBInstances[].{ID:DBInstanceIdentifier,SGs:VpcSecurityGroups[].VpcSecurityGroupId}" \
--output table
# Check each security group for unrestricted access
aws ec2 describe-security-groups \
--group-ids <sg-id> \
--query "SecurityGroups[].IpPermissions[?contains(IpRanges[].CidrIp, '0.0.0.0/0')]"
Remediation:
- Replace
0.0.0.0/0rules with references to specific security group IDs of your application tier (e.g., allow inbound from the web-server security group only). - If CIDR-based rules are necessary, scope them to the narrowest possible range.
- Never allow database ports (3306, 5432, 1433, 1521) from
0.0.0.0/0under any circumstances. - Use AWS Config rule
rds-sg-no-unrestricted-access(custom rule) for continuous monitoring.
11. Audit Logging and Log Exports Disabled
The Risk: Without database audit logging exported to CloudWatch Logs, you have no visibility into who accessed the database, what queries were executed, or whether unauthorized activity occurred. In a breach scenario, the absence of logs makes forensics impossible and incident response ineffective.
Why It Matters: Compliance frameworks universally require audit trails. AWS supports exporting general logs, slow query logs, error logs, and audit logs to CloudWatch. For MySQL and MariaDB, the MariaDB Audit Plugin provides detailed query-level logging. For PostgreSQL, the pgAudit extension provides fine-grained audit capabilities.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[].{ID:DBInstanceIdentifier,Engine:Engine,LogExports:EnabledCloudwatchLogsExports}" \
--output table
If LogExports is empty or missing critical log types (audit, error), the instance is misconfigured.
Remediation:
- Enable all relevant log exports for your engine:
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--cloudwatch-logs-export-configuration '{"EnableLogTypes":["audit","error","general","slowquery"]}' \
--apply-immediately
- For MySQL: Enable the MariaDB Audit Plugin via option groups with
SERVER_AUDIT_EVENTS = CONNECT,QUERY,QUERY_DDL,QUERY_DML. - For PostgreSQL: Install and configure
pgAuditvia a custom parameter group. - Set CloudWatch Logs retention policies appropriate to your compliance requirements.
- Create CloudWatch alarms for suspicious patterns (failed authentication attempts, DDL changes).
12. Multi-AZ Deployment Not Enabled
The Risk: Single-AZ RDS instances have a single point of failure. If the underlying hardware fails, the Availability Zone experiences an outage, or a maintenance event requires a reboot, your database goes offline with no automatic failover.
Why It Matters: Multi-AZ deployments maintain a synchronous standby replica in a different Availability Zone. Failover is automatic (typically 60–120 seconds) with no data loss. This is not a backup — it’s a high-availability mechanism. For production workloads, running single-AZ is accepting unnecessary risk to both availability and data durability.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?MultiAZ==\`false\`].{ID:DBInstanceIdentifier,Engine:Engine,MultiAZ:MultiAZ}" \
--output table
Remediation:
- Enable Multi-AZ for all production instances:
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--multi-az \
--apply-immediately
- Note: Enabling Multi-AZ on an existing instance causes a brief I/O suspension while the standby is created.
- For even higher availability, consider Multi-AZ with two readable standbys (available for MySQL and PostgreSQL), which provides failover in ~1 second when used with RDS Proxy.
13. Auto Minor Version Upgrade Disabled
The Risk: Disabling automatic minor version upgrades means your RDS instances accumulate known security vulnerabilities that have already been patched in newer minor versions. Attackers actively scan for databases running outdated engine versions with known CVEs.
Why It Matters: AWS minor version upgrades include critical security patches, bug fixes, and performance improvements. They are applied during your specified maintenance window, minimizing disruption. With Multi-AZ, minor version upgrades typically incur minimal downtime. Disabling this feature creates a growing security debt.
How to Detect:
aws rds describe-db-instances \
--query "DBInstances[?AutoMinorVersionUpgrade==\`false\`].{ID:DBInstanceIdentifier,Engine:Engine,Version:EngineVersion,AutoUpgrade:AutoMinorVersionUpgrade}" \
--output table
Remediation:
- Enable auto minor version upgrade:
aws rds modify-db-instance \
--db-instance-identifier <instance-id> \
--auto-minor-version-upgrade \
--apply-immediately
- Set a maintenance window during low-traffic hours.
- Test minor version upgrades in staging environments first using snapshot restores.
- Use AWS Config rule
rds-automatic-minor-version-upgrade-enabledfor continuous compliance.
14. RDS Instance Provisioned in a Public Subnet
The Risk: Provisioning an RDS instance in a public subnet (a subnet with a route to an internet gateway) means the instance could be made publicly reachable even if PubliclyAccessible is currently false. A single modification (whether accidental or malicious) flips it to internet-facing. Defense-in-depth requires that databases exist in subnets with no possible internet route.
Why It Matters: This differs from misconfiguration #1 (the PubliclyAccessible flag) because it addresses the network architecture layer. Even if the flag is off today, a public subnet creates a latent risk. The CIS AWS Foundations Benchmark recommends that all data-tier resources reside in private subnets with no internet gateway routes.
How to Detect:
# Get the subnets used by RDS
aws rds describe-db-instances \
--query "DBInstances[].{ID:DBInstanceIdentifier,SubnetGroup:DBSubnetGroup.DBSubnetGroupName}"
# Check if any subnet in the subnet group has an internet gateway route
aws rds describe-db-subnet-groups \
--db-subnet-group-name <subnet-group-name> \
--query "DBSubnetGroups[].Subnets[].SubnetIdentifier"
# For each subnet, check its route table
aws ec2 describe-route-tables \
--filters "Name=association.subnet-id,Values=<subnet-id>" \
--query "RouteTables[].Routes[?GatewayId && starts_with(GatewayId, 'igw-')]"
If any route contains an internet gateway (igw-*), the subnet is public.
Remediation:
- Create a dedicated DB subnet group that only includes private subnets (no internet gateway route).
- Migrate RDS instances to the private subnet group. This requires modifying the DB subnet group or restoring from a snapshot into the new subnet group.
- Use NAT gateways only if the database engine requires outbound internet access (rare for RDS).
- Enforce this with SCPs or AWS Config custom rules.
15. Event Notification Subscriptions Not Configured
The Risk: Without RDS event notifications, your team has no real-time awareness of critical database events failovers, configuration changes, security group modifications, backup failures, storage issues, or maintenance events. By the time someone notices a problem through application errors, damage may already be done.
Why It Matters: RDS event notifications deliver alerts via Amazon SNS within minutes of an event occurring. This enables rapid incident response, change tracking, and operational awareness. Combined with CloudWatch alarms, they form the observability foundation for database security monitoring.
How to Detect:
aws rds describe-event-subscriptions \
--query "EventSubscriptionsList[].{Name:CustSubscriptionId,Source:SourceType,Categories:EventCategoriesList,Enabled:Enabled}" \
--output table
If no subscriptions exist or critical categories (security, failover, configuration change, failure) are missing, notifications are not configured.
Remediation:
- Create event subscriptions for critical categories:
aws rds create-event-subscription \
--subscription-name rds-security-events \
--sns-topic-arn arn:aws:sns:<region>:<account>:rds-alerts \
--source-type db-instance \
--event-categories "security" "failover" "configuration change" "failure" "notification" \
--enabled
- Create separate subscriptions for different source types (db-instance, db-cluster, db-security-group, db-snapshot).
- Route notifications to your SIEM, Slack/PagerDuty, or security orchestration platform.
- At minimum, subscribe to:
security,failover,configuration change, andfailurecategories.
How Cloudanix Helps
Manually auditing 15 misconfigurations across dozens (or hundreds) of RDS instances is unsustainable. Cloudanix continuously monitors your AWS environment and flags RDS security issues in real time — before they become breaches.
With Cloudanix, you get:
- Continuous RDS posture monitoring: Every instance, snapshot, subnet group, and parameter group is assessed against security best practices automatically.
- Pre-built compliance mappings: Checks are mapped to CIS AWS Foundations Benchmark, PCI DSS, HIPAA, SOC 2, NIST 800-53, and GDPR requirements out of the box.
- Automated remediation: One-click and policy-driven remediation workflows fix misconfigurations without manual intervention.
- Complete audit trail: Track configuration changes over time and demonstrate compliance with historical evidence.
Explore Cloudanix’s RDS security capabilities:
- AWS RDS Monitoring & Audit Checks
- Complete List of AWS RDS Misconfigurations
- Cloud Security Posture Management
Start your free trial and get visibility into your RDS security posture in minutes.
Conclusion
AWS RDS misconfigurations are not theoretical risks, they are the root cause of real-world database breaches every year. The 15 security misconfigurations covered in this article represent the most impactful findings across public exposure, encryption, access control, monitoring, and resilience:
- Public access: Never expose RDS directly to the internet.
- Public snapshots: Lock down snapshot sharing permissions.
- Encryption at rest: Encrypt at creation time; retrofitting is painful.
- Customer-managed keys: Retain control over your encryption keys.
- Transport encryption: Force SSL/TLS on all database connections.
- IAM authentication: Replace static passwords with short-lived tokens.
- Secrets Manager: Let AWS manage and rotate master credentials.
- Automated backups: Maintain adequate retention for point-in-time recovery.
- Deletion protection: Prevent accidental or malicious database destruction.
- Security group access: Never allow 0.0.0.0/0 on database ports.
- Audit logging: Export all logs to CloudWatch for forensics and compliance.
- Multi-AZ: Eliminate single points of failure in production.
- Auto minor upgrades: Stay current on security patches.
- Private subnets: Place databases in subnets with no internet route.
- Event notifications: Get real-time alerts on critical database events.
A CSPM tool like Cloudanix gives you automated, continuous detection of these issues across your entire AWS estate — so your team can focus on building rather than auditing.
People Also Read
- Complete List of AWS RDS Misconfigurations
- Top 15 Cloud Misconfigurations in 2026 - How to Fix Them?
- Top 13 AWS EC2 Misconfigurations To Avoid in 2022
- A Complete List of AWS S3 Misconfigurations
- Top 16 AWS S3 Misconfigurations To Avoid in 2023
- How to use CSPM to detect and remediate cloud misconfigurations
- Top 18 Challenges of Cloud Security in 2026
- Top 10 Azure Virtual Machine (VM) Misconfigurations To Avoid