PCI-DSS 4.0 Req 1.2.1 requires that inbound and outbound traffic is restricted to that which is necessary; Req 1.4 prohibits direct public access to any CDE component. A security group with 0.0.0.0/0 on port 22 (SSH) or 5432 (PostgreSQL) means your database is reachable from the entire internet — any brute-force or credential-stuffing attack against it requires only a public IP. CWE-183 (Permissive List of Allowed Inputs) and NIST SC-7 both require deny-by-default firewall posture. A single overly permissive rule can invalidate an otherwise well-segmented network architecture.
High because one allow-all or `0.0.0.0/0` rule on a sensitive port (SSH, database) exposes the CDE directly to internet-sourced attacks, negating any network segmentation investment.
Replace every allow-all ingress rule with explicit source security group references or narrowly scoped CIDR blocks. SSH access must be limited to a bastion host security group — never 0.0.0.0/0. Database ports must accept traffic only from the application tier security group.
# Restrict SSH to bastion only
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.bastion.id]
}
# Database accessible from app tier only
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}
Set a deny-all default egress on CDE security groups and add specific outbound rules only for required destinations (e.g., port 443 to payment processor IPs). Audit terraform plan output for any cidr_blocks = ["0.0.0.0/0"] on ports below 1024.
ID: ecommerce-pci.network-security.firewall-rules
Severity: high
What to look for: Enumerate all firewall and security group rules in infrastructure code. For each rule, classify it as restrictive (specific port + specific source) or permissive (all ports, or 0.0.0.0/0 on sensitive ports like 22, 3306, 5432). Count the total number of ingress rules and the number that are overly permissive. Check for deny-by-default principle (no rule = deny).
Pass criteria: At least 1 security group or firewall configuration exists with explicit rules. No more than 0 rules allow 0.0.0.0/0 on sensitive ports (22, 3306, 5432, 27017). No more than 0 rules allow all ports (from_port: 0, to_port: 65535). All CDE-bound traffic is restricted to specific source security groups or CIDR ranges. Report: "X total ingress rules, Y restrictive, Z permissive."
Fail criteria: At least 1 overly permissive rule exists (allow-all ports from any source, or 0.0.0.0/0 on database/SSH ports), or no firewall rules documented at all.
Skip (N/A) when: All payment processing delegated to third-party (no CDE infrastructure, no security groups in project).
Detail on fail: Identify overly permissive rules. Example: "Security group cde-sg allows 0.0.0.0/0 on port 22 (SSH). 2 of 5 ingress rules are overly permissive." or "Security group has from_port: 0, to_port: 65535 from 0.0.0.0/0. All ports open to internet."
Remediation: Define restrictive firewall rules. Replace allow-all with explicit rules:
# Before: Overly permissive
resource "aws_security_group" "bad" {
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# After: Explicit rules
resource "aws_security_group" "cde" {
# SSH only from bastion
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.bastion.id]
}
# Database from app tier only
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}
# Monitoring from monitoring tools
ingress {
from_port = 9090
to_port = 9090
protocol = "tcp"
security_groups = [aws_security_group.monitoring.id]
}
# Explicit deny-all for unlisted
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = []
}
# Allow specific outbound
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # to internet for updates
}
}