Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · RDS

RDS.36: RDS MySQL accepts unencrypted connections

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub RDS.36 check?

RDS.36 checks whether an RDS for PostgreSQL DB instance is configured to publish logs to Amazon CloudWatch Logs. Backed by the AWS Config rule rds-postgresql-logs-to-cloudwatch (change-triggered, resource AWS::RDS::DBInstance), it reports FAILED when the instance isn't exporting the log types named in the logTypes parameter. Security Hub sets logTypes to 'postgresql' by default; the rule also recognises the 'upgrade' log type.

Why does RDS.36 matter?

Database logging gives you a detailed record of requests made to an RDS instance, and PostgreSQL's event log captures login failures, fatal server errors, deadlocks, query failures, and (depending on parameters like log_statement and log_min_duration_statement) the statements themselves. If those logs stay on the instance, they age out and disappear the moment the host is replaced, and you have nothing durable to investigate an incident or prove an audit trail. Publishing to CloudWatch Logs centralises the data in durable storage, where you can run real-time analysis, build metric filters, and raise alarms, for example alerting whenever a DDL statement runs. PCI DSS v4.0.1 requirement 10.4.2 expects this kind of automated log review.

How do I fix RDS.36?

  1. In the RDS console, choose the instance, select Modify, then in the Log exports section tick the log types you want (Postgresql log, and Upgrade log if relevant) and apply the change.
  2. Or run: aws rds modify-db-instance --db-instance-identifier my-instance --cloudwatch-logs-export-configuration '{"EnableLogTypes":["postgresql","upgrade"]}'. EnableLogTypes accepts any combination of 'postgresql' and 'upgrade'.
  3. No reboot is needed: a change to the CloudWatch Logs export configuration is applied immediately, so the --apply-immediately flag has no effect here. Only new log events are published going forward; existing on-instance logs are not backfilled.
  4. Confirm log events appear in the CloudWatch log group /aws/rds/instance/<instance-name>/postgresql, then standardise the export setting across PostgreSQL instances so the control holds going forward.

Remediation script · bash

# Find the highest-impact plaintext-permitting stores across engines.
aws rds describe-db-instances \
  --query 'DBInstances[].DBInstanceIdentifier' --output text
aws elasticache describe-replication-groups \
  --query 'ReplicationGroups[?TransitEncryptionEnabled==`false`].ReplicationGroupId' \
  --output text

# RDS for PostgreSQL: require TLS via rds.force_ssl (static -> needs a reboot).
PG=$(aws rds describe-db-instances --db-instance-identifier prod-orders-pg \
  --query 'DBInstances[].DBParameterGroups[].DBParameterGroupName' --output text)
aws rds modify-db-parameter-group --db-parameter-group-name "$PG" \
  --parameters 'ParameterName=rds.force_ssl,ParameterValue=1,ApplyMethod=pending-reboot'
aws rds reboot-db-instance --db-instance-identifier prod-orders-pg

# Redshift: require_ssl on a custom cluster parameter group, then reboot.
aws redshift modify-cluster-parameter-group --parameter-group-name analytics-tls \
  --parameters ParameterName=require_ssl,ParameterValue=true
aws redshift reboot-cluster --cluster-identifier analytics-prod

Full walkthrough (console steps, edge cases and verification) in the lesson Enforce TLS on database and cache connections.

Is RDS.36 a false positive?

There is no real false positive here. If the control reports FAILED, the instance simply isn't exporting every log type listed in logTypes (by default 'postgresql'). Note the rule only checks that PostgreSQL instances publish to CloudWatch Logs: it doesn't evaluate non-PostgreSQL engines, and it doesn't validate what your logging parameters (such as log_statement) actually capture, only that the configured log types are being shipped.

Part of the learning path Encrypt everything
  • 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