Back to Checks
aws

AWS WAFv2 Web ACL has at least one rule or rule group attached

wafv2_webacl_with_rules
Service: wafv2Severity: high
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsWafv2WebAcl

AWS WAFv2 web ACLs are evaluated for the presence of at least one configured rule or rule group that defines how HTTP(S) requests are inspected and acted upon.

Risk

Without rules, traffic is governed only by the web ACL DefaultAction, often allowing requests without inspection. This increases risks to confidentiality (data exfiltration via injection), integrity (XSS/parameter tampering), and availability (layer-7 DDoS, bot abuse).

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks wafv2_webacl_with_rules

Recommendation

Populate each web ACL with targeted rules or managed rule groups to enforce least-privilege web access: cover common exploits (SQLi/XSS), IP reputation, and rate limits, scoped to your apps. Use a conservative DefaultAction, monitor metrics/logs, and continually tune-supporting defense in depth and zero trust.

Remediation

Terraform

# Terraform: Ensure the WAFv2 Web ACL has at least one rule
resource "aws_wafv2_web_acl" "<example_resource_name>" {
  name  = "<example_resource_name>"
  scope = "REGIONAL"

  default_action {
    allow {}
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "<example_resource_name>"
    sampled_requests_enabled   = true
  }

  rule { # CRITICAL: Presence of this rule makes the Web ACL non-empty and passes the check
    name     = "<example_rule_name>"
    priority = 0
    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"  # Minimal managed rule group
      }
    }
    override_action { count {} } # Non-blocking
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "<example_rule_name>"
      sampled_requests_enabled   = true
    }
  }
}

NativeIaC

# CloudFormation: Add at least one rule to the WAFv2 WebACL
Resources:
  <example_resource_name>:
    Type: AWS::WAFv2::WebACL
    Properties:
      Scope: REGIONAL
      DefaultAction:
        Allow: {}
      VisibilityConfig:
        SampledRequestsEnabled: true
        CloudWatchMetricsEnabled: true
        MetricName: <example_resource_name>
      Rules:  # CRITICAL: Adding any rule/rule group here fixes the finding by making the Web ACL non-empty
        - Name: <example_rule_name>
          Priority: 0
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet  # Uses an AWS managed rule group
          OverrideAction:
            Count: {}  # Non-blocking to minimize impact
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: <example_rule_name>

Other

1In the AWS Console, go to AWS WAF
2Open Web ACLs and select the failing Web ACL
3Go to the Rules tab and click Add rules
4Choose Add managed rule group, select AWS > AWSManagedRulesCommonRuleSet
5Set action to Count (to avoid blocking), then Add rule and Save
6Verify the Web ACL now shows at least one rule

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.wafv2.wafv2_client import wafv2_client


class wafv2_webacl_with_rules(Check):
    def execute(self):
        findings = []
        for web_acl in wafv2_client.web_acls.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=web_acl)
            report.status = "FAIL"
            report.status_extended = f"AWS WAFv2 Web ACL {web_acl.name} does not have any rules or rule groups attached."

            if web_acl.rules or web_acl.rule_groups:
                report.status = "PASS"
                report.status_extended = f"AWS WAFv2 Web ACL {web_acl.name} does have rules or rule groups attached."

            findings.append(report)

        return findings