This check flags security group rules that open a non-web port to the entire internet (0.0.0.0/0 or ::/0). Open ports like SSH, RDP, and database listeners are prime targets for automated attacks. Replace the wide-open CIDR with a specific source range or move access behind a bastion or VPN.
Security groups are the front door to your AWS infrastructure, and like any door, leaving it wide open is asking for trouble. The sg_allows_all check looks for one specific bad habit: a rule that permits inbound traffic from anywhere on a port that has no business being public.
Web ports (80 and 443) are usually meant to face the world, so this check skips them. Everything else, SSH on 22, RDP on 3389, PostgreSQL on 5432, Redis on 6379, and the long tail of management and database ports, is treated as something that should never accept connections from 0.0.0.0/0.
What this check detects
Lensix scans every security group in your account and inspects each ingress rule. The check fails when both of these are true:
- The rule allows traffic from
0.0.0.0/0(all IPv4) or::/0(all IPv6). - The port is not a recognized web port (anything outside 80 and 443).
A typical offending rule looks like this when you describe it:
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"IpRanges": [
{ "CidrIp": "0.0.0.0/0" }
]
}
That rule says "let anyone on the internet attempt an SSH connection." It is one of the most common findings in any cloud security audit, and it shows up far more often than people expect, usually because someone opened it to debug a problem and never closed it.
Note: Security groups are stateful. If you allow an inbound connection, the response traffic is automatically permitted out, regardless of outbound rules. That makes a single permissive ingress rule more impactful than it might seem at first glance.
Why it matters
An open management or database port is not a theoretical risk. The internet is constantly scanned by automated bots looking for exactly this. The moment an EC2 instance with port 22 open to the world gets a public IP, it will start receiving login attempts within minutes.
Real-world attack scenarios
- SSH and RDP brute force: Bots cycle through common usernames and leaked password lists. If you have password authentication enabled or a weak key setup, this is a direct path to a shell on your box.
- Exposed databases: Open ports for MongoDB (27017), Elasticsearch (9200), Redis (6379), and MySQL (3306) have caused some of the largest data breaches on record. Many of these services historically shipped with no authentication by default. An open port plus a default config equals a public database.
- Exploitation of unpatched services: A management interface exposed to the internet gives attackers unlimited time to fingerprint your software version and fire off known exploits. RDP in particular has a long history of wormable vulnerabilities like BlueKeep.
- Lateral movement: Once an attacker lands on one over-exposed instance, that stateful security group and the instance's IAM role become a launchpad into the rest of your VPC.
Danger: An exposed database port with default or no authentication can be discovered, accessed, and exfiltrated by automated tooling without any human attacker ever looking at it directly. Treat any open database port as a live incident, not a backlog item.
Beyond the direct breach risk, this finding maps to controls in nearly every compliance framework. PCI DSS, SOC 2, CIS AWS Foundations Benchmark, and HIPAA all expect network access to be restricted to known sources. An auditor will flag a wide-open SSH port immediately.
How to fix it
The goal is to replace 0.0.0.0/0 with the narrowest source that still lets legitimate traffic through. Here is how to do it across the console, CLI, and infrastructure as code.
1. Find the offending rule
List all security groups that allow ingress from anywhere on something other than web ports:
aws ec2 describe-security-groups \
--filters Name=ip-permission.cidr,Values=0.0.0.0/0 \
--query 'SecurityGroups[].{ID:GroupId,Name:GroupName,Rules:IpPermissions}' \
--output json
2. Revoke the open rule
Warning: Revoking a rule takes effect immediately and will drop existing and new connections from any source that relied on it. Confirm who is actually using the port before you remove it, or you may lock yourself or a service out.
Remove the wide-open SSH rule:
aws ec2 revoke-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0
3. Add a scoped replacement rule
Re-add access from a known source, such as your corporate egress IP or a VPN range:
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.10/32
The /32 suffix locks this down to a single IP address. Use a wider CIDR only if you genuinely need a range.
Console steps
- Open the EC2 console and go to Security Groups.
- Select the group, then the Inbound rules tab, and click Edit inbound rules.
- Find the rule with source
0.0.0.0/0on a non-web port. - Change the source from Anywhere-IPv4 to My IP or a custom CIDR, or delete the rule entirely.
- Click Save rules.
Better than a fixed IP: remove public access entirely
The strongest fix is to not expose the port at all. A few patterns to consider:
- AWS Systems Manager Session Manager gives you shell access to instances with no open inbound ports and no bastion host. Connections go through the SSM agent over the AWS API.
- A bastion host in a public subnet, locked to your VPN, with private instances only reachable from the bastion's security group.
- Reference another security group as the source instead of a CIDR, so only resources inside your VPC can connect.
# Allow PostgreSQL only from the application tier's security group
aws ec2 authorize-security-group-ingress \
--group-id sg-db0123456789abcde \
--protocol tcp \
--port 5432 \
--source-group sg-app0123456789abc
Tip: Session Manager removes the need for inbound SSH entirely. Once the SSM agent and an instance profile with AmazonSSMManagedInstanceCore are in place, you can run aws ssm start-session --target i-0abc123 and close port 22 for good.
Terraform example
If you manage security groups with Terraform, scope the source instead of using an open CIDR:
resource "aws_security_group" "app" {
name = "app-sg"
description = "Application server access"
vpc_id = aws_vpc.main.id
ingress {
description = "SSH from VPN only"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["203.0.113.0/24"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
How to prevent it from happening again
Fixing the rule once is easy. Keeping it fixed across a team of engineers who are all under deadline pressure is the real challenge. Automation is the answer.
Catch it in CI before it ships
Run a static analysis tool against your Terraform or CloudFormation in the pipeline. Checkov, tfsec, and Trivy all ship with rules for open security group ingress out of the box.
# Fail the build if any plan opens a non-web port to the world
checkov -d . --check CKV_AWS_24,CKV_AWS_25
Wire this into your pull request checks so a risky change cannot merge without a human override.
Enforce with policy as code
Use an Open Policy Agent or Sentinel policy as a hard gate. A simple rule: deny any rule where the CIDR is 0.0.0.0/0 and the port is not 80 or 443.
# OPA / Conftest against a Terraform plan
conftest test plan.json --policy ./policies
Detect drift at runtime
Pipelines only cover changes made through your pipeline. People still click around the console during incidents. Catch those with continuous monitoring:
- Enable the AWS Config managed rule
restricted-sshandrestricted-common-ports. - Use Lensix to scan continuously and alert the moment
sg_allows_alltrips, so a temporary debugging rule does not silently become permanent.
Note: The most common cause of this finding is a "temporary" rule added during troubleshooting. Pairing runtime detection with a clear owner for each security group is what stops those from lingering for months.
Best practices
- Default deny. Open only the ports a workload actually needs, sourced from the narrowest CIDR or, better, another security group.
- No management ports on the public internet. SSH and RDP belong behind a VPN, a bastion, or Session Manager. There is rarely a good reason for either to face 0.0.0.0/0.
- Reference security groups, not IP ranges, for internal traffic. This keeps rules accurate as instances come and go and avoids hardcoded CIDRs that drift out of date.
- Tag and document every rule. Use the rule description field to record who owns it and why it exists. Undocumented rules are the ones nobody is brave enough to delete.
- Review regularly. Audit security groups on a schedule and remove rules tied to decommissioned services.
- Layer your defenses. Pair tight security groups with private subnets, network ACLs, and a WAF for anything that genuinely must be public. A security group is one control, not the whole strategy.
The fix for this check is almost always quick. The discipline of never opening a non-web port to the world in the first place is what keeps your attack surface small over the long run.

