RDS instances exposed to the internet via PubliclyAccessible
What does ZopNight detect here?
ZopNight fires this critical finding when the RDS DescribeDBInstances API reports PubliclyAccessible as true, meaning the database has a public IP and an internet-resolvable DNS endpoint. The rule abstains entirely when the flag was not discovered, and the fix is 1 console change: set Publicly accessible to No.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-085 |
| Category | compliance |
| Severity | critical |
| Metric | none — pure configuration read |
| Source | rds_public_access.go |
Where it applies
What the flag actually grants
PubliclyAccessible: true gives an RDS instance a public IP address and a DNS endpoint
that resolves from anywhere on the internet. Security groups still have to permit a
connection, but the flag removes the structural barrier: the database endpoint becomes
something the internet can name and route to, one permissive inbound rule away from
exposure. That is why this finding is rated critical while carrying $0 of savings: it
is a pure attack-surface reduction.
One flag, read from the source of truth
The discoverer captures the PubliclyAccessible attribute from the RDS
DescribeDBInstances API and stores it as provider state. The rule fires only when
that captured value is explicitly true.
The history here is instructive: an earlier contract read a publicly_accessible tag,
a key nothing ever wrote, so the rule was permanently dead while looking implemented.
Reading the attribute the API actually returns is what revived it.
The abstain case
When the flag was not discovered at all (enrichment skipped, or the API call denied), the rule reports nothing. Fail-closed is the right default even at critical severity: an unknown exposure state is a visibility problem to fix in discovery, not a security incident to alert on. The rule never fires on inference.
Find every exposed instance now
aws rds describe-db-instances \ --query "DBInstances[?PubliclyAccessible==\`true\`].[DBInstanceIdentifier,Engine,Endpoint.Address]" \ --output tableEvery row in that output is an endpoint the internet can resolve.
Closing the hole without breaking the app
Flip Publicly accessible to No under the instance’s connectivity settings, either immediately or in the next maintenance window if change control demands it. Then update application connection strings to use the private endpoint, restrict the security group to the application tier’s security group only, and give administrators a bastion host or VPC endpoints instead of a public route. The only clients that break are the ones connecting from outside the VPC, which is the point. If one of those turns out to be a legitimate integration, it belongs behind the bastion too, not on a database port exposed to 4 billion routable addresses.