Back to Checks
aws

RDS snapshot is not publicly shared

rds_snapshots_public_access
Service: rdsSeverity: critical
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsRdsDbSnapshot

RDS DB snapshots and DB cluster snapshots with public visibility (shared with all AWS accounts) are detected.

Snapshots limited to specific accounts or kept private are identified as restricted.

Risk

Public RDS snapshots expose full database copies to all AWS accounts, risking:

  • Loss of confidentiality via data exfiltration (PII, secrets)
  • Offline cracking of hashes and schema reconnaissance
  • Credential harvesting from dumps enabling lateral movement This directly compromises confidentiality and fuels targeted attacks.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks rds_snapshots_public_access

Recommendation

Keep RDS snapshots and cluster snapshots private. Share only with explicit AWS account IDs using least privilege and time-bound access.

Enforce guardrails to block public visibility, require approvals for sharing, and audit snapshot permissions. Use encryption with strict key policies to control who can restore data.

Remediation

CLI

aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot_id> --attribute-name restore --values-to-remove all

Other

1Open the Amazon RDS console and go to Snapshots
2Select the public snapshot (DB snapshot or DB cluster snapshot)
3Click Actions > Share snapshot
4Set visibility to Private (remove "All" from permissions) and click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.rds.rds_client import rds_client


class rds_snapshots_public_access(Check):
    def execute(self):
        findings = []
        for db_snap in rds_client.db_snapshots:
            report = Check_Report_AWS(metadata=self.metadata(), resource=db_snap)
            if db_snap.public:
                report.status = "FAIL"
                report.status_extended = (
                    f"RDS Instance Snapshot {db_snap.id} is public."
                )
            else:
                report.status = "PASS"
                report.status_extended = (
                    f"RDS Instance Snapshot {db_snap.id} is not shared."
                )

            findings.append(report)

        for db_snap in rds_client.db_cluster_snapshots:
            report = Check_Report_AWS(metadata=self.metadata(), resource=db_snap)
            if db_snap.public:
                report.status = "FAIL"
                report.status_extended = f"RDS Cluster Snapshot {db_snap.id} is public."
            else:
                report.status = "PASS"
                report.status_extended = (
                    f"RDS Cluster Snapshot {db_snap.id} is not shared."
                )

            findings.append(report)

        return findings