Back to Checks
aws

Non-default network ACL is associated with a subnet

ec2_networkacl_unused
Service: ec2Severity: low
OfficialBuilt-inVerified
Categories:trust-boundaries
Resource Type:AwsEc2NetworkAcl

VPC network ACLs that are not associated with any subnet are considered unused. The evaluation focuses on non-default ACLs and identifies those without a current subnet association; the default network ACL is excluded.

Risk

Unused ACLs raise the risk of misassociation, unexpectedly changing subnet filtering. A permissive ACL could expose workloads (confidentiality, integrity), while an overly restrictive one could disrupt traffic (availability). Stale objects also hinder reviews and conceal drift.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_networkacl_unused

Recommendation

Remove unused non-default ACLs to minimize drift. Apply least privilege and change control to ACL creation and associations. If retention is necessary, tag owner and purpose, restrict who can associate ACLs, and review regularly as part of defense in depth.

Remediation

CLI

aws ec2 delete-network-acl --network-acl-id <nacl_id>

Terraform

# Associate the unused non-default NACL to a subnet so it's in use
resource "aws_network_acl_association" "<example_resource_name>" {
  subnet_id      = "<example_resource_id>"     # Critical: makes the subnet use this NACL
  network_acl_id = "<example_resource_id>"     # Critical: the unused non-default NACL to associate
}

NativeIaC

# Associate the unused non-default NACL to a subnet so it's in use
Resources:
  <example_resource_name>:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: <example_resource_id>        # Critical: makes the subnet use this NACL
      NetworkAclId: <example_resource_id>    # Critical: the unused non-default NACL to associate

Other

1In the AWS console, open VPC > Network ACLs
2Select the non-default NACL with Association: None
3Choose Actions > Delete ACL > Delete
4Alternative (if you want to keep it):
5Select the NACL > Actions > Edit subnet associations
6Check a subnet to associate > Save

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_networkacl_unused(Check):
    def execute(self):
        findings = []
        for arn, network_acl in ec2_client.network_acls.items():
            if not network_acl.default:
                report = Check_Report_AWS(
                    metadata=self.metadata(), resource=network_acl
                )

                if not network_acl.in_use:
                    report.status = "FAIL"
                    report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} is not associated with any subnet and is not the default network ACL."
                else:
                    report.status = "PASS"
                    report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} is associated with a subnet."

                findings.append(report)

        return findings