Back to Checks
aws

API Gateway stage has a WAF Web ACL attached

apigateway_restapi_waf_acl_attached
Service: apigatewaySeverity: medium
OfficialBuilt-inVerified
Resource Type:AwsApiGatewayStage

Amazon API Gateway (REST API) stages are assessed for an associated AWS WAF web ACL. The finding reflects whether a web ACL is linked at the stage level.

Risk

Absent a WAF web ACL, APIs are exposed to application-layer threats that impact CIA:

  • Confidentiality: data exfiltration via injection
  • Integrity: parameter tampering and path traversal
  • Availability: L7 floods, bot abuse, resource exhaustion Public endpoints face heightened risk.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks apigateway_restapi_waf_acl_attached

Recommendation

Attach an AWS WAF web ACL to each exposed stage and apply defense in depth:

  • Use managed rule groups and tailored allow/deny lists
  • Apply rate limiting to throttle abuse
  • Enforce least-privilege network exposure
  • Continuously tune rules using logs and metrics Validate changes to reduce false positives.

Remediation

CLI

aws wafv2 associate-web-acl --web-acl-arn <WEB_ACL_ARN> --resource-arn arn:aws:apigateway:<REGION>::/restapis/<REST_API_ID>/stages/<STAGE_NAME>

Terraform

# Attach a WAFv2 Web ACL to an API Gateway REST API stage
resource "aws_wafv2_web_acl_association" "<example_resource_name>" {
  resource_arn = "arn:aws:apigateway:<example_region>::/restapis/<example_resource_id>/stages/<example_stage_name>" # CRITICAL: target API Gateway stage
  web_acl_arn  = "<example_resource_arn>" # CRITICAL: Web ACL to attach
}

NativeIaC

# CloudFormation: Attach a WAFv2 Web ACL to an API Gateway REST API stage
Resources:
  <example_resource_name>:
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      ResourceArn: arn:aws:apigateway:<example_region>::/restapis/<example_resource_id>/stages/<example_stage_name>  # CRITICAL: target API Gateway stage
      WebACLArn: <example_resource_arn>  # CRITICAL: Web ACL to attach

Other

1Open the AWS Console and go to WAF & Shield
2Select Web ACLs (Scope: Regional), choose your Web ACL
3Click Add AWS resource
4Select API Gateway, choose the REST API and the specific Stage
5Click Add/Associate to attach the Web ACL

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.apigateway.apigateway_client import (
    apigateway_client,
)


class apigateway_restapi_waf_acl_attached(Check):
    def execute(self):
        findings = []
        for rest_api in apigateway_client.rest_apis:
            for stage in rest_api.stages:
                report = Check_Report_AWS(metadata=self.metadata(), resource=stage)
                report.resource_id = rest_api.name
                report.region = rest_api.region
                if stage.waf:
                    report.status = "PASS"
                    report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} in stage {stage.name} has {stage.waf} WAF ACL attached."
                else:
                    report.status = "FAIL"
                    report.status_extended = f"API Gateway {rest_api.name} ID {rest_api.id} in stage {stage.name} does not have WAF ACL attached."
                findings.append(report)

        return findings