VPC subnet does not assign public IP addresses by default
VPC subnets where MapPublicIpOnLaunch is true automatically assign a public IPv4 address to instances at launch.
This identifies subnets configured for default public IP assignment.
Risk
Internet-exposed instances become reachable by default, enabling port scans, SSH/RDP brute force, and exploit attempts. Successful access can lead to data exfiltration (confidentiality), unauthorized changes (integrity), and outages (availability) through abuse or DDoS.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks vpc_subnet_no_public_ip_by_defaultRecommendation
Disable subnet auto-assign to enforce least-privilege exposure. Place workloads in private subnets, use controlled egress (NAT or private endpoints), and prefer bastions or SSM for administration.
When public access is necessary, assign IPs explicitly and restrict with tight security groups and routes for defense in depth.
Remediation
CLI
aws ec2 modify-subnet-attribute --subnet-id <SUBNET_ID> --no-map-public-ip-on-launchTerraform
# Subnet with public IP auto-assign disabled
resource "aws_subnet" "example" {
vpc_id = "<example_resource_id>"
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = false # Critical: prevents assigning public IPs by default
}NativeIaC
# CloudFormation: Subnet with public IP auto-assign disabled
Resources:
ExampleSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: <example_resource_id>
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: false # Critical: disables automatic public IPv4 assignment on instance launchOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.vpc.vpc_client import vpc_client
class vpc_subnet_no_public_ip_by_default(Check):
def execute(self):
findings = []
for vpc in vpc_client.vpcs.values():
for subnet in vpc.subnets:
# Check if ignoring flag is set and if the VPC Subnet is in use
if vpc_client.provider.scan_unused_services or subnet.in_use:
report = Check_Report_AWS(metadata=self.metadata(), resource=subnet)
if subnet.mapPublicIpOnLaunch:
report.status = "FAIL"
report.status_extended = f"VPC subnet {subnet.name if subnet.name else subnet.id} assigns public IP by default."
else:
report.status = "PASS"
report.status_extended = f"VPC subnet {subnet.name if subnet.name else subnet.id} does NOT assign public IP by default."
findings.append(report)
return findings