EC2 instance is not internet-facing with an instance profile attached
EC2 instances with a public IP address and an attached instance profile (IAM role) are identified.
Instances lacking public exposure or without an instance profile are excluded.
Risk
Publicly reachable instances with IAM role credentials expand the blast radius. Remote exploits or misconfigurations can steal credentials via the instance metadata service, enabling unauthorized API calls, data exfiltration, and lateral movement, impacting confidentiality, integrity, and availability.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks ec2_instance_internet_facing_with_instance_profileRecommendation
Avoid direct Internet exposure. Place workloads behind an Application Load Balancer and protect HTTP apps with WAF. Remove public IPs or restrict ingress to trusted sources. Apply least privilege to instance profiles and enforce IMDSv2. Use bastion hosts or Session Manager for admin access.
Remediation
CLI
aws ec2 disassociate-iam-instance-profile --association-id <ASSOCIATION_ID>Terraform
# EC2 instance without a public IP to avoid being internet-facing
resource "aws_instance" "<example_resource_name>" {
ami = "<example_ami_id>"
instance_type = "t3.micro"
associate_public_ip_address = false # Critical: disables public IPv4 so the instance is not internet-facing
}NativeIaC
# CloudFormation: EC2 instance without a public IP to avoid being internet-facing
Resources:
<example_resource_name>:
Type: AWS::EC2::Instance
Properties:
ImageId: <example_ami_id>
InstanceType: t3.micro
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: <example_resource_id>
AssociatePublicIpAddress: false # Critical: disables public IPv4 so the instance is not internet-facingOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
class ec2_instance_internet_facing_with_instance_profile(Check):
def execute(self):
findings = []
for instance in ec2_client.instances:
if instance.state != "terminated":
report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
report.status = "PASS"
report.status_extended = f"EC2 Instance {instance.id} is not internet facing with an instance profile."
if instance.public_ip and instance.instance_profile:
report.status = "FAIL"
report.status_extended = f"EC2 Instance {instance.id} at IP {instance.public_ip} is internet-facing with Instance Profile {instance.instance_profile['Arn']}."
findings.append(report)
return findingsReferences
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html
- https://aws.amazon.com/blogs/aws/aws-web-application-firewall-waf-for-application-load-balancers/
- https://support.icompaas.com/support/solutions/articles/62000127121-ensure-instance-profile-is-attached-for-internet-facing-ec2-instances