Back to Checks
aws

Amazon Cognito user pool is associated with a WAF Web ACL

cognito_user_pool_waf_acl_attached
Service: cognitoSeverity: medium
OfficialBuilt-inVerified
Categories:threat-detectioninternet-exposed
Resource Type:AwsWafv2WebAcl

Amazon Cognito user pools are evaluated for an association with an AWS WAFv2 web ACL that filters and controls requests to the hosted UI and public user pool API endpoints.

Risk

Without a web ACL, Cognito endpoints lack layer-7 filtering, enabling:

  • Credential stuffing and account enumeration
  • Bot abuse and high-rate requests degrading service
  • Malicious payload probes

This threatens availability, risks unauthorized access to user data (confidentiality), and undermines session integrity.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks cognito_user_pool_waf_acl_attached

Recommendation

Associate an AWS WAFv2 web ACL with each user pool to enforce layer-7 controls. Use defense-in-depth: managed rule groups, rate-based limits, IP reputation, and bot mitigation. Enable request logging and continuously tune rules to reduce false positives. Avoid rule sets incompatible with Cognito endpoints.

Remediation

CLI

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

Terraform

resource "aws_wafv2_web_acl_association" "<example_resource_name>" {
  resource_arn = "<example_resource_arn>"  # Critical: Cognito User Pool ARN
  web_acl_arn  = "<example_web_acl_arn>"   # Critical: WAF Web ACL ARN
}

NativeIaC

Resources:
  <example_resource_name>:
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      ResourceArn: <example_resource_arn>  # Critical: Cognito User Pool ARN to protect
      WebACLArn: <example_web_acl_arn>     # Critical: WAF Web ACL ARN to associate

Other

1Open the AWS Console and go to Cognito > User pools
2Select the user pool
3In Security, open the AWS WAF tab and click Edit
4Check Use AWS WAF with your user pool
5Select the existing regional Web ACL
6Click Save changes

Check Code

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


class cognito_user_pool_waf_acl_attached(Check):
    def execute(self):
        findings = []
        for pool in cognito_idp_client.user_pools.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=pool)
            report.status = "FAIL"
            report.status_extended = (
                f"Cognito User Pool {pool.name} is not associated with a WAF Web ACL."
            )
            for acl in wafv2_client.web_acls.values():
                if pool.arn in acl.user_pools:
                    report.status = "PASS"
                    report.status_extended = f"Cognito User Pool {pool.name} is associated with the WAF Web ACL {acl.name}."
                    break
            findings.append(report)

        return findings