Back to Checks
aws

AWS WAFv2 Web ACL has Amazon CloudWatch metrics enabled for all rules and rule groups

wafv2_webacl_rule_logging_enabled
Service: wafv2Severity: medium
OfficialBuilt-inVerified
Categories:logging
Resource Type:AwsWafv2WebAcl

AWS WAFv2 Web ACLs are assessed to confirm that every associated rule and rule group has CloudWatch metrics enabled for visibility into rule evaluations and traffic

Risk

Absent CloudWatch metrics, WAF telemetry is lost, masking spikes, rule bypasses, and misconfigurations. This delays detection of SQLi/XSS probes and bot floods, risking data confidentiality, request integrity, and application availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks wafv2_webacl_rule_logging_enabled

Recommendation

Enable CloudWatch metrics for all WAF rules and rule groups (including managed rule groups). Use consistent metric names, centralize dashboards and alerts, and review trends to validate rule efficacy. Integrate with a SIEM for defense in depth and tune rules based on telemetry.

Remediation

Terraform

# Terraform: Enable CloudWatch metrics on WAFv2 Web ACL rules
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                = "<metric_name>"
    sampled_requests_enabled   = true
  }

  rule {
    name     = "<example_rule_name>"
    priority = 1

    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesCommonRuleSet"
      }
    }

    override_action { none {} }

    visibility_config {
      cloudwatch_metrics_enabled = true  # Critical: enables CloudWatch metrics for this rule
      metric_name                = "<rule_metric_name>"  # Required with CloudWatch metrics
      sampled_requests_enabled   = true
    }
  }
}

NativeIaC

# CloudFormation: Enable CloudWatch metrics on WAFv2 Web ACL rules
Resources:
  <example_resource_name>:
    Type: AWS::WAFv2::WebACL
    Properties:
      Name: <example_resource_name>
      Scope: REGIONAL
      DefaultAction:
        Allow: {}
      VisibilityConfig:
        SampledRequestsEnabled: true
        CloudWatchMetricsEnabled: true
        MetricName: <metric_name>
      Rules:
        - Name: <example_rule_name>
          Priority: 1
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet
          OverrideAction:
            None: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true  # Critical: enables CloudWatch metrics for this rule
            MetricName: <rule_metric_name>  # Required with CloudWatch metrics

Other

1In AWS Console, go to AWS WAF & Shield > Web ACLs, select the Web ACL
2Open the Rules tab, edit each rule, and enable CloudWatch metrics (Visibility configuration > CloudWatch metrics enabled), then Save
3For rule groups: go to AWS WAF & Shield > Rule groups, select the rule group, edit Visibility configuration, enable CloudWatch metrics, then Save

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_rule_logging_enabled(Check):
    def execute(self):
        findings = []
        for web_acl in wafv2_client.web_acls.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=web_acl)

            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 CloudWatch Metrics enabled in all its rules."

                rules_metrics_disabled = []
                for rule in web_acl.rules:
                    if not rule.cloudwatch_metrics_enabled:
                        rules_metrics_disabled.append(rule.name)

                rule_groups_metrics_disabled = []
                for rule_group in web_acl.rule_groups:
                    if not rule_group.cloudwatch_metrics_enabled:
                        rule_groups_metrics_disabled.append(rule_group.name)

                if rules_metrics_disabled and rule_groups_metrics_disabled:
                    report.status = "FAIL"
                    report.status_extended = f"AWS WAFv2 Web ACL {web_acl.name} does not have CloudWatch Metrics enabled in rules: {', '.join(rules_metrics_disabled)} nor in rule groups: {', '.join(rule_groups_metrics_disabled)}."
                elif rules_metrics_disabled:
                    report.status = "FAIL"
                    report.status_extended = f"AWS WAFv2 Web ACL {web_acl.name} does not have CloudWatch Metrics enabled in rules: {', '.join(rules_metrics_disabled)}."
                elif rule_groups_metrics_disabled:
                    report.status = "FAIL"
                    report.status_extended = f"AWS WAFv2 Web ACL {web_acl.name} does not have CloudWatch Metrics enabled in rule groups: {', '.join(rule_groups_metrics_disabled)}."

                findings.append(report)

        return findings