Back to Checks
aws

Application Load Balancer has a WAF Web ACL attached

elbv2_waf_acl_attached
Service: elbv2Severity: medium
OfficialBuilt-inVerified
Resource Type:AwsElbv2LoadBalancer

Application Load Balancers are evaluated for an associated AWS WAF web ACL that governs HTTP(S) requests. The evaluation detects ALBs missing a web ACL and recognizes associations from WAFv2 or regional WAF Classic.

Risk

Absent a WAF web ACL, ALBs accept unfiltered Layer 7 traffic, enabling:

  • Injection (SQLi/XSS) harming confidentiality and integrity
  • Credential stuffing and bot abuse
  • Resource exhaustion degrading availability

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks elbv2_waf_acl_attached

Recommendation

Associate a WAF web ACL with each ALB as defense in depth. Use managed and custom rules, IP reputation lists, and rate limiting to block attacks. Continuously tune policies and monitor logs. Apply least privilege by scoping rules to required paths, methods, and sources.

Remediation

CLI

aws wafv2 associate-web-acl --web-acl-arn <WEB_ACL_ARN> --resource-arn <ALB_ARN>

Terraform

# Associate WAFv2 Web ACL with an ALB
resource "aws_wafv2_web_acl_association" "<example_resource_name>" {
  resource_arn = "<example_resource_id>" # CRITICAL: ALB ARN
  web_acl_arn  = "<example_resource_id>" # CRITICAL: WAFv2 Web ACL ARN
}

NativeIaC

# CloudFormation: associate an existing WAFv2 Web ACL to an ALB
Resources:
  <example_resource_name>:
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      ResourceArn: <example_resource_id>  # CRITICAL: ALB ARN to protect
      WebACLArn: <example_resource_id>    # CRITICAL: WAFv2 Web ACL ARN to attach

Other

1In the AWS Console, open **WAF & Shield**
2Go to **Web ACLs** and select your regional Web ACL
3Click **Associated AWS resources** > **Associate resource**
4Select the target **Application Load Balancer** and click **Associate**

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.elbv2.elbv2_client import elbv2_client
from prowler.providers.aws.services.waf.wafregional_client import wafregional_client
from prowler.providers.aws.services.wafv2.wafv2_client import wafv2_client


class elbv2_waf_acl_attached(Check):
    def execute(self):
        findings = []
        for lb in elbv2_client.loadbalancersv2.values():
            if lb.type == "application":
                report = Check_Report_AWS(metadata=self.metadata(), resource=lb)
                report.status = "FAIL"
                report.status_extended = (
                    f"ELBv2 ALB {lb.name} is not protected by WAF Web ACL."
                )
                for acl in wafv2_client.web_acls.values():
                    if lb.arn in acl.albs:
                        report.status = "PASS"
                        report.status_extended = f"ELBv2 ALB {lb.name} is protected by WAFv2 Web ACL {acl.name}."
                for acl in wafregional_client.web_acls.values():
                    if lb.arn in acl.albs:
                        report.status = "PASS"
                        report.status_extended = f"ELBv2 ALB {lb.name} is protected by WAFv1 Web ACL {acl.name}."

                findings.append(report)

        return findings