Back to Checks
DMS replication instance is not publicly exposed to the Internet
dms_instance_no_public_access
Service: dmsSeverity: critical
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsDmsReplicationInstance
AWS DMS replication instances are evaluated for public exposure. Exposure is identified when PubliclyAccessible is enabled and an attached security group allows inbound traffic from any address. Private or allowlisted instances are not considered exposed.
Risk
Publicly reachable replication instances threaten:
- Confidentiality: migration data and credentials can be intercepted or exfiltrated.
- Integrity: attackers may alter tasks or inject records.
- Availability: abuse or DDoS can stall replication and delay cutovers.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks dms_instance_no_public_accessRecommendation
Adopt a private-only design:
- Disable
PubliclyAccessible; place instances in private subnets. - Enforce least privilege security groups (no
0.0.0.0/0); allow only required sources/ports. - Provide access via VPN, peering, or Direct Connect.
- Layer controls (ACLs, monitoring) and restrict IAM to necessary actions.
Remediation
Terraform
# DMS instance not publicly accessible
resource "aws_dms_replication_instance" "<example_resource_name>" {
replication_instance_id = "<example_resource_id>"
replication_instance_class = "dms.t3.micro"
publicly_accessible = false # Critical: disables public access to prevent Internet exposure
}NativeIaC
# CloudFormation: DMS instance not publicly accessible
Resources:
<example_resource_name>:
Type: AWS::DMS::ReplicationInstance
Properties:
ReplicationInstanceClass: dms.t3.micro
PubliclyAccessible: false # Critical: disables public access to prevent Internet exposureOther
1In the AWS Console, open Database Migration Service > Replication instances and select the instance
2In Details > Networking, click each attached Security Group ID to open it in the EC2 console
3In Inbound rules, delete any rule with Source 0.0.0.0/0 or ::/0
4Save rules for each security group
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.dms.dms_client import dms_client
from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group
def _get_ec2_client():
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
return ec2_client
class dms_instance_no_public_access(Check):
def execute(self):
findings = []
for instance in dms_client.instances:
report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
report.status = "PASS"
report.status_extended = (
f"DMS Replication Instance {instance.id} is not publicly accessible."
)
if instance.public:
report.status_extended = f"DMS Replication Instance {instance.id} is set as publicly accessible, but is not publicly exposed."
# Check if any DB Instance Security Group is publicly open
if instance.security_groups:
report.status = "PASS"
report.status_extended = f"DMS Replication Instance {instance.id} is set as publicly accessible but filtered with security groups."
for security_group in _get_ec2_client().security_groups.values():
if security_group.id in instance.security_groups:
for ingress_rule in security_group.ingress_rules:
if check_security_group(
ingress_rule,
"-1",
any_address=True,
all_ports=True,
):
report.status = "FAIL"
report.status_extended = f"DMS Replication Instance {instance.id} is set as publicly accessible and security group {security_group.name} ({security_group.id}) is open to the Internet."
break
findings.append(report)
return findingsReferences
- https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-1
- https://docs.aws.amazon.com/amazonq/detector-library/terraform/restrict-public-access-dms-terraform/
- https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/aws/DMS/publicly-accessible.html
- https://support.icompaas.com/support/solutions/articles/62000233448-ensure-dms-instances-are-not-publicly-accessible