EMR Cluster Public Accessibility
Overview
This check examines whether your Amazon EMR (Elastic MapReduce) clusters are exposed to the public internet. It analyzes the security groups attached to your master and core/task nodes, looking for inbound rules that allow unrestricted access from anywhere (0.0.0.0/0 or ::/0).
Only active clusters are evaluated. A finding indicates that one or more security groups attached to your EMR cluster allow traffic from the entire internet.
Risk
Severity: Medium
When EMR clusters are publicly accessible, attackers can:
- Gain direct access to cluster services and web interfaces (Spark UI, YARN, etc.)
- Attempt brute-force attacks against authentication mechanisms
- Exploit vulnerabilities to run unauthorized code on your cluster
- Steal sensitive data processed or stored by your cluster
- Hijack compute resources for cryptocurrency mining or other malicious purposes
EMR clusters often process sensitive business data, making public exposure a significant security concern.
Remediation Steps
Prerequisites
- AWS Console access with permissions to modify security groups and EMR settings
- Knowledge of which IP addresses or CIDR ranges legitimately need access to your cluster
Required IAM permissions
To perform this remediation, you need permissions including:
ec2:DescribeSecurityGroupsec2:RevokeSecurityGroupIngressec2:AuthorizeSecurityGroupIngresselasticmapreduce:DescribeClusterelasticmapreduce:PutBlockPublicAccessConfigurationelasticmapreduce:GetBlockPublicAccessConfiguration
AWS Console Method
Step 1: Identify the affected security groups
- Go to the Amazon EMR Console at https://console.aws.amazon.com/emr/
- Click Clusters in the left navigation
- Select your cluster from the list
- In the cluster details, find the Security and access section
- Note the security group IDs for:
- Master security group (e.g.,
sg-xxxxxxxxx) - Core/Task security group (e.g.,
sg-yyyyyyyyy)
- Master security group (e.g.,
Step 2: Remove public access from security groups
- Go to the EC2 Console at https://console.aws.amazon.com/ec2/
- Click Security Groups in the left navigation under "Network & Security"
- Find and select the security group ID noted in Step 1
- Click the Inbound rules tab
- Click Edit inbound rules
- Look for any rules with Source set to
0.0.0.0/0or::/0 - For each public rule, either:
- Delete it by clicking the "Delete" button (X icon), or
- Restrict the source to a specific IP range (e.g., your corporate network CIDR)
- Click Save rules
- Repeat for all affected security groups
Step 3: Enable EMR Block Public Access (recommended)
This account-level setting prevents future clusters from being created with public security groups.
- Go to the Amazon EMR Console
- Click Block public access in the left navigation
- Click Edit
- Toggle Block public access to On
- Optionally, add permitted port exceptions (e.g., port 22 for SSH from specific IPs)
- Click Save
AWS CLI (optional)
Identify cluster security groups
aws emr describe-cluster \
--cluster-id j-XXXXXXXXXXXXX \
--region us-east-1 \
--query 'Cluster.Ec2InstanceAttributes.{MasterSG:EmrManagedMasterSecurityGroup,CoreSG:EmrManagedSlaveSecurityGroup}'
List inbound rules for a security group
aws ec2 describe-security-groups \
--group-ids sg-XXXXXXXXX \
--region us-east-1 \
--query 'SecurityGroups[*].IpPermissions'
Remove a public ingress rule
Replace the values with your specific security group and rule details:
aws ec2 revoke-security-group-ingress \
--group-id sg-XXXXXXXXX \
--protocol tcp \
--port 8088 \
--cidr 0.0.0.0/0 \
--region us-east-1
For more complex rules, use the --ip-permissions parameter:
aws ec2 revoke-security-group-ingress \
--group-id sg-XXXXXXXXX \
--ip-permissions IpProtocol=tcp,FromPort=8088,ToPort=8088,IpRanges=[{CidrIp=0.0.0.0/0}] \
--region us-east-1
Enable EMR Block Public Access
aws emr put-block-public-access-configuration \
--block-public-access-configuration BlockPublicSecurityGroupRules=true,PermittedPublicSecurityGroupRuleRanges=[{MinRange=22,MaxRange=22}] \
--region us-east-1
CloudFormation (optional)
When creating EMR clusters via CloudFormation, use security groups that restrict access to known CIDR ranges:
AWSTemplateFormatVersion: '2010-09-09'
Description: EMR cluster with restricted security groups
Parameters:
TrustedCIDR:
Type: String
Description: CIDR block allowed to access EMR cluster
Default: 10.0.0.0/8
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Subnet for the EMR cluster
Resources:
EMRMasterSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EMR Master node security group - restricted access
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref TrustedCIDR
Description: SSH from trusted network
- IpProtocol: tcp
FromPort: 8088
ToPort: 8088
CidrIp: !Ref TrustedCIDR
Description: YARN ResourceManager from trusted network
Tags:
- Key: Name
Value: emr-master-sg-restricted
EMRCoreSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EMR Core/Task node security group - restricted access
VpcId: !Ref VpcId
Tags:
- Key: Name
Value: emr-core-sg-restricted
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC for security groups
Outputs:
MasterSecurityGroupId:
Description: Security group ID for EMR master node
Value: !Ref EMRMasterSecurityGroup
CoreSecurityGroupId:
Description: Security group ID for EMR core/task nodes
Value: !Ref EMRCoreSecurityGroup
Terraform (optional)
# Security group for EMR master node with restricted access
resource "aws_security_group" "emr_master" {
name = "emr-master-sg-restricted"
description = "EMR Master node security group - restricted access"
vpc_id = var.vpc_id
# SSH from trusted network only
ingress {
description = "SSH from trusted network"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.trusted_cidr]
}
# YARN ResourceManager from trusted network only
ingress {
description = "YARN ResourceManager from trusted network"
from_port = 8088
to_port = 8088
protocol = "tcp"
cidr_blocks = [var.trusted_cidr]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "emr-master-sg-restricted"
}
}
# Security group for EMR core/task nodes
resource "aws_security_group" "emr_core" {
name = "emr-core-sg-restricted"
description = "EMR Core/Task node security group - restricted access"
vpc_id = var.vpc_id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "emr-core-sg-restricted"
}
}
# Enable EMR Block Public Access at account level
resource "aws_emr_block_public_access_configuration" "this" {
block_public_security_group_rules = true
# Optionally permit SSH (port 22) with public access
permitted_public_security_group_rule_range {
min_range = 22
max_range = 22
}
}
variable "vpc_id" {
description = "VPC ID for security groups"
type = string
}
variable "trusted_cidr" {
description = "CIDR block allowed to access EMR cluster"
type = string
default = "10.0.0.0/8"
}
Verification
After making changes, verify the remediation was successful:
- In the EC2 Console: Check the inbound rules for each security group and confirm no rules have
0.0.0.0/0or::/0as the source - In the EMR Console: Verify that Block Public Access is enabled under "Block public access" settings
- Re-run the Prowler check:
prowler aws --checks emr_cluster_publicly_accesible --region us-east-1
CLI verification commands
Check that no public ingress rules exist:
aws ec2 describe-security-groups \
--group-ids sg-XXXXXXXXX \
--region us-east-1 \
--query 'SecurityGroups[*].IpPermissions[?contains(IpRanges[*].CidrIp, `0.0.0.0/0`) || contains(Ipv6Ranges[*].CidrIpv6, `::/0`)]'
An empty result [] indicates no public rules remain.
Verify EMR Block Public Access is enabled:
aws emr get-block-public-access-configuration --region us-east-1
Look for "BlockPublicSecurityGroupRules": true in the output.
Additional Resources
- AWS EMR Block Public Access Documentation
- AWS EMR Security Best Practices
- AWS Security Group Best Practices
- Prowler EMR Checks Documentation
Notes
- Running clusters: Modifying security groups takes effect immediately for running clusters. Test changes during a maintenance window if possible.
- Application connectivity: Before removing rules, ensure you understand which applications and users need access. Coordinate with your team to avoid disrupting legitimate access.
- Private subnets: For maximum security, deploy EMR clusters in private subnets without public IP addresses and use a bastion host, VPN, or AWS Systems Manager Session Manager for administrative access.
- Block Public Access exceptions: If you must allow public access to specific ports (e.g., SSH for emergency access), use the "Permitted public security group rule ranges" feature sparingly and combine it with additional controls like IP allowlisting.