Skip to main content
emnode / learn
Compliance Low severity

AWS Security Hub · RDS

RDS.23: RDS runs on a well-known default port

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub RDS.23 check?

RDS.23 checks whether an RDS instance listens on its engine's well-known default port — 3306 for MySQL/MariaDB, 5432 for PostgreSQL, 1433 for SQL Server, 1521 for Oracle. It reports FAILED for any instance still on the factory default, whether public or private.

Why does RDS.23 matter?

Changing a port is not encryption or isolation — it is a single layer of friction. But at internet scale that friction matters: automated botnets sweep IPv4 looking for 3306, not 53306, and most move on the moment the default fails. An attacker who finds your endpoint will try the engine default first because it is right the overwhelming majority of the time. A non-standard port removes that free first guess.

How do I fix RDS.23?

  1. Inventory instances still on the engine default port.
  2. Pick a non-standard port and apply it with modify-db-instance --db-port-number (this triggers a restart, so schedule a maintenance window).
  3. Update every client in lockstep — connection strings in Secrets Manager, IaC, and Lambda environment variables — then roll out in stages to avoid connection outages.
  4. Bake the non-default port into provisioning templates so new instances inherit it.

Remediation script · bash

# Revoke an over-open admin rule, covering both IPv4 and IPv6 in one call.
aws ec2 revoke-security-group-ingress --group-id sg-0a1b2c3d \
  --ip-permissions 'IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp=0.0.0.0/0}],Ipv6Ranges=[{CidrIpv6=::/0}]'

# Where access is genuinely needed, re-add it scoped to a source security group, not a CIDR.
aws ec2 authorize-security-group-ingress --group-id sg-0a1b2c3d \
  --ip-permissions 'IpProtocol=tcp,FromPort=6379,ToPort=6379,UserIdGroupPairs=[{GroupId=sg-0app1234,Description=app-tier}]'

# Strip a default security group to empty by feeding its current rules back into revoke.
INGRESS=$(aws ec2 describe-security-groups --group-ids sg-0default01 \
  --query 'SecurityGroups[0].IpPermissions')
[ "$INGRESS" != "[]" ] && aws ec2 revoke-security-group-ingress \
  --group-id sg-0default01 --ip-permissions "$INGRESS"

Full walkthrough (console steps, edge cases and verification) in the lesson Harden security groups and restrict ingress.

Part of the learning path Lock down access
  • RDS.1 An RDS snapshot is shared publicly
  • RDS.2 An RDS instance is publicly accessible from the internet
  • RDS.3 RDS DB instances should be encrypted at rest
  • RDS.4 RDS snapshots should be encrypted at rest
  • RDS.5 RDS DB instances should use multiple AZs
  • RDS.6 RDS lacks enhanced monitoring
  • RDS.7 RDS clusters should have deletion protection
  • RDS.8 RDS DB instances should have deletion protection
  • RDS.9 RDS engine logs are not shipped to CloudWatch
  • RDS.10 RDS relies on long-lived database passwords
  • RDS.11 RDS instances should have automatic backups
  • RDS.12 IAM auth should be configured for RDS clusters