Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · EC2

EC2.15: Subnets auto-assign public IPs to new instances

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub EC2.15 check?

EC2.15 fails for any subnet that auto-assigns a public address on launch: either MapPublicIpOnLaunch (public IPv4) or AssignIpv6AddressOnCreation (IPv6) set to true. The control reads both flags from DescribeSubnets, so any subnet that hands instances a public IPv4 or IPv6 address without an explicit override is flagged.

Why does EC2.15 matter?

When either attribute is on, every instance launched into the subnet gets a public IPv4 or IPv6 address unless the launch call explicitly opts out (console launches, CloudFormation, SDK calls, and EKS managed node groups all inherit it). That silently puts workloads on the public internet before patching or config management runs. Flipping both attributes off makes "private by default" the unavoidable outcome unless someone deliberately overrides it.

How do I fix EC2.15?

  1. Run describe-subnets across every region and categorise each subnet by intended tier (public ALB/NAT/bastion versus everything else).
  2. Turn both attributes off with modify-subnet-attribute --no-map-public-ip-on-launch --no-assign-ipv6-address-on-creation on every subnet that does not legitimately need them.
  3. Document the legitimate exceptions (ALB, NAT, bastion subnets) as Security Hub suppressions with a recorded reason rather than disabling the control.
  4. Enable the AWS Config rule subnet-auto-assign-public-ip-disabled to alert if anyone re-enables the attribute.

Remediation script · bash

# Close the highest-impact public exposure first: databases.
for db in $(aws rds describe-db-instances \
    --query 'DBInstances[?PubliclyAccessible==`true`].DBInstanceIdentifier' --output text); do
  aws rds modify-db-instance --db-instance-identifier "$db" \
    --no-publicly-accessible --apply-immediately
  echo "$db: public access removed"
done

# Ratchet S3 shut at the account level so no bucket can be made public again.
aws s3control put-public-access-block --account-id 123456789012 \
  --public-access-block-configuration \
    'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'

Full walkthrough (console steps, edge cases and verification) in the lesson Block public access to AWS resources.

Is EC2.15 a false positive?

Subnets fronting public ALBs, NAT gateways, or bastions legitimately keep auto-assign on. Those are not bugs: suppress the specific resources with a documented justification instead of treating the finding as wrong.

Part of the learning path Trim your network spend
  • EC2.1 An EBS snapshot is publicly restorable by any account
  • EC2.2 Default security groups still allow traffic
  • EC2.3 Attached EBS volumes are not encrypted at rest
  • EC2.4 Long-stopped instances are abandoned attack surface
  • EC2.6 No VPC flow logs, so there is no network audit trail
  • EC2.7 New EBS volumes are not encrypted by default
  • EC2.8 IMDSv1 lets an SSRF steal instance credentials
  • EC2.9 Instances are directly reachable on public IPv4
  • EC2.10 EC2 API traffic leaves the VPC over the internet
  • EC2.13 SSH (port 22) is open to the entire internet
  • EC2.14 RDP (port 3389) is open to the entire internet
  • EC2.17 Instances with multiple ENIs can bridge network boundaries