Back to Checks
Security group does not allow ingress from 0.0.0.0/0 or ::/0 to TCP port 22 (SSH)
ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22
Service: ec2Severity: high
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsEc2SecurityGroup
EC2 security groups are assessed for inbound SSH exposure by locating ingress rules that allow TCP 22 from the Internet (0.0.0.0/0 or ::/0).
Only groups in use are considered; sets already flagged for all-port exposure are not repeated.
Risk
Exposed SSH invites Internet-scale brute force and credential stuffing. A successful login grants remote shell, enabling data theft (confidentiality), code or config tampering (integrity), and cryptomining or service disruption (availability), plus lateral movement within the environment.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22Recommendation
Apply least privilege to SSH:
- Disallow
0.0.0.0/0and::/0; allow only trusted IPs or VPN ranges - Prefer private access via bastion hosts or AWS Systems Manager Session Manager
- Enforce key-based auth, disable passwords, rotate keys
- Add network segmentation and monitoring for defense in depth
Remediation
CLI
aws ec2 revoke-security-group-ingress --group-id <SECURITY_GROUP_ID> --protocol tcp --port 22 --cidr 0.0.0.0/0Terraform
# Terraform: restrict SSH from the Internet
resource "aws_security_group" "<example_resource_name>" {
vpc_id = "<example_resource_id>"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"] # Critical: do not use 0.0.0.0/0 or ::/0
}
}NativeIaC
# CloudFormation: restrict SSH from the Internet
Resources:
<example_resource_name>:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Restrict SSH
VpcId: <example_resource_id>
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/8 # Critical: allows SSH only from a private range, not 0.0.0.0/0Other
1In the AWS Console, go to EC2 > Security Groups
2Select the affected security group
3Open the Inbound rules tab
4Delete any rule for port 22 (SSH) with source 0.0.0.0/0 or ::/0
5Click Save rules
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_all_ports import (
ec2_securitygroup_allow_ingress_from_internet_to_all_ports,
)
from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group
from prowler.providers.aws.services.vpc.vpc_client import vpc_client
class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22(Check):
def execute(self):
findings = []
check_ports = [22]
for security_group_arn, security_group in ec2_client.security_groups.items():
# Check if ignoring flag is set and if the VPC and the SG is in use
if ec2_client.provider.scan_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
):
report = Check_Report_AWS(
metadata=self.metadata(), resource=security_group
)
report.resource_details = security_group.name
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have SSH port 22 open to the Internet."
# only proceed if check "..._to_all_ports" did not run or did not FAIL to avoid to report open ports twice
if not ec2_client.is_failed_check(
ec2_securitygroup_allow_ingress_from_internet_to_all_ports.__name__,
security_group_arn,
):
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
if check_security_group(
ingress_rule, "tcp", check_ports, any_address=True
):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has SSH port 22 open to the Internet."
break
else:
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has all ports open to the Internet and therefore was not checked against the specific SSH port 22."
findings.append(report)
return findings