Written by Mateus Alexandre, DevOps Engineer at TrackIt
Web applications exposed to the internet are consistently targeted by automated threats such as credential stuffing, content scraping, vulnerability scanning, and denial-of-service attempts. Services like Cloudflare and Amazon CloudFront have popularized the use of browser challenges (automated checks to verify that a request is coming from a legitimate browser) and CAPTCHA as effective defenses against bots and automation.
For infrastructures built on AWS, Amazon CloudFront combined with AWS WAF (Web Application Firewall) provides native, integrated capabilities that offer comparable or enhanced protection—enabling fine-grained control and strong alignment with AWS environments.
The sections below outline how to secure applications using CAPTCHA and Challenge actions in AWS WAF, detailing their functionality and providing guidance on configuration strategies. These recommendations are applicable both when migrating from Cloudflare and when designing a new security approach for applications deployed at the edge.
Contents
- Understanding CAPTCHA and Challenge Actions in AWS WAF
- Cloudflare Turnstile
- AWS WAF vs. Cloudflare Turnstile
- How to Configure CAPTCHA and Challenge Actions in AWS WAF
- Configuration Steps Using AWS Console
- Configuration Steps Using Terraform
- Testing the Configuration
- Beyond CAPTCHA and Challenge: Building a Broader WAF Protection Strategy
- Managed Rule Groups
- Detecting Bots with AWS Bot Control
- Combining Protection Layers
- Conclusion
- About TrackIt
Understanding CAPTCHA and Challenge Actions in AWS WAF
AWS WAF offers two inspection actions to help protect applications from unwanted or automated traffic: CAPTCHA and Challenge.
- CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) presents an interactive puzzle that must be solved to confirm human interaction. This action is particularly effective for scenarios requiring a higher level of confidence — such as login attempts or access to sensitive routes. Upon successful completion, AWS issues a token that allows the requestor to bypass the CAPTCHA for a configurable duration, referred to as immunity time.
- Challenge performs a silent browser validation without requiring user input. It evaluates client-side behavior, such as support for JavaScript and cookies, to distinguish legitimate browsers from basic bots. This action is useful for mitigating low-complexity automated traffic while maintaining a frictionless experience for legitimate users.
Cloudflare Turnstile
Cloudflare offers an alternative approach with Turnstile, a CAPTCHA replacement designed to verify requests without introducing user-facing friction. It relies on a combination of:
- Client-side signals (such as browser environment and behavior)
- Server-side risk scoring
- Private challenge mechanisms that remain invisible under most conditions
In many cases, Turnstile is able to validate requests without displaying a visual challenge.
AWS WAF vs. Cloudflare Turnstile
While both services aim to protect applications from automated abuse, their approaches differ:
Aspect | AWS WAF CAPTCHA / Challenge | Cloudflare Turnstile |
Type of verification | Visual CAPTCHA or JS-based challenge | Mostly invisible background validation |
Control of when to apply | Fully rule-based (WAF conditions, rate limits, geolocation, etc.) | Applied via embedded widget or server config |
Integration and Deployment | Works natively with AWS services like CloudFront, ALB, or API Gateway, and no external routing required | Requires traffic to pass through Cloudflare as a reverse proxy (CDN or tunnel) |
Customization | Theme, retry limit, immunity time, response code | Minimal |
Visibility to end-user | CAPTCHA visible when triggered; challenge is transparent but passive | Typically no user-visible element unless needed |
One key difference is that AWS WAF does not require changes to front-end or application code to enforce CAPTCHA or Challenge actions. These are triggered automatically based on WAF rule logic, using conditions such as rate limits or geolocation.
In contrast, Cloudflare Turnstile requires embedding a widget into the application and performing token validation on the server side, making it a more tightly integrated front-end implementation.
How to Configure CAPTCHA and Challenge Actions in AWS WAF
The following section outlines a practical example of configuring CAPTCHA and Challenge actions using AWS WAF with CloudFront, through both the AWS Console and Terraform. The objective is to establish a layered defense strategy that enhances protection against bots while preserving the user experience.
This configuration includes:
- A global Challenge rule applied to all requests, enabling transparent bot detection without affecting legitimate users.
- A CAPTCHA rule for the /login path, triggered only when a client exceeds a predefined request rate—an effective control for mitigating brute-force attempts while maintaining accessibility for valid users.
Configuration Steps Using AWS Console
Prerequisites
- An Amazon CloudFront distribution already deployed and serving the application
- Permissions to associate a Web ACL with the CloudFront distribution
- A predictable route within the application (e.g., /login)
Create or Edit a Web ACL
- Navigate to the AWS WAF Console and select Web ACLs

- Switch the region to Global

- Click Create web ACL or select an existing ACL to edit
- Choose Global resources under Resource type

- Provide a name for the Web ACL and a corresponding CloudWatch metric name.
- In the Associated AWS resources section, click Add AWS resources.

- Select the appropriate CloudFront distribution and click Add.

- Leave the remaining settings at their defaults and click Next to continue.
Add a Global Challenge Rule
- In the Add rules and rule groups section, click Add rules > Add my own rules and rule groups.

- For Rule type, select Rule builder.

- Provide a name for the rule and select Regular rule as the type.

- Under If a request, choose matches the statement.
- In the Inspection section:
- Set the field to URI path
- Select String match condition with match type Starts with string
- Enter / as the String to match

- Set the Action to Challenge.

- Set the Immunity time if needed, and click Add rule.
Add a CAPTCHA Rule for /login with Rate Limiting
- Click Add rule > Add my own rules and rule groups.
- Set Rule type to Rule builder.
- Provide a rule name and select Rate-based rule as the type.

Configure rate-limiting criteria:
- Set the Rate limit to 10 (minimum value).
- Set the Evaluation window to 1 minute (60 seconds).
- Under Request aggregation, choose Source IP address.
- For Scope of inspection and rate limiting, select Only consider requests that match the criteria in a rule statement.

Define the match criteria:
- Under If a request, choose matches the statement.
- In the Statement section:
- Select URI path in inspect.
- Match type: String match condition > Exactly matches string.
- String to match: /login

- In the Action section:
- Select CAPTCHA.
- Set the Immunity time if needed, and click Add rule.

- After this step, return to the Add rules and rule groups page and click Next to proceed.
Adjust Rule Priorities
- Assign a lower priority number to the CAPTCHA rule to ensure it takes precedence over the global Challenge rule.
- Click Next.
Configure Logging and Metrics
- For each rule, enable sampling of requests and CloudWatch metrics as needed.
- Set a name for the CloudWatch metric for each rule and set Enable sampled requests.
- Click Next.
Review and create web ACL
- Review the settings and click Create web ACL to finalize the setup.
Configuration Steps Using Terraform
Prerequisites
- An active AWS account with permissions to manage WAF, CloudFront, and IAM
- A CloudFront distribution already deployed, pointing to the application
- Terraform installed locally
- The AWS CLI configured with credentials and default region set to us-east-1
- A Terraform provider for AWS configured in the project
Create the Web ACL Resource
resource “aws_wafv2_web_acl” “captcha-challenge-acl” { name = “captcha-challenge-web-acl” description = “WAF ACL with global challenge and rate-based captcha on /login” scope = “CLOUDFRONT” default_action { allow {} } visibility_config { cloudwatch_metrics_enabled = true metric_name = “waf-captcha-challenge” sampled_requests_enabled = true } rule { name = “captcha-web-acl-rule” priority = 0 action { captcha {} } statement { rate_based_statement { limit = 10 evaluation_window_sec = 60 scope_down_statement { byte_match_statement { text_transformation { priority = 0 type = “NONE” } positional_constraint = “EXACTLY” search_string = “/login” field_to_match { uri_path {} } } } } } captcha_config { immunity_time_property { immunity_time = 300 } } visibility_config { cloudwatch_metrics_enabled = true metric_name = “captcha-login” sampled_requests_enabled = true } } rule { name = “challenge-web-acl-rule-1” priority = 1 action { challenge {} } statement { byte_match_statement { search_string = “/” positional_constraint = “STARTS_WITH” field_to_match { uri_path {} } text_transformation { priority = 0 type = “NONE” } } } visibility_config { cloudwatch_metrics_enabled = true metric_name = “challenge-global” sampled_requests_enabled = true } } } |
Associate the Web ACL with CloudFront
- In the aws_cloudfront_distribution resource, add the web_acl_id:
resource “aws_cloudfront_distribution” “cloudfront” { web_acl_id = aws_wafv2_web_acl.captcha-challenge-acl.arn … |
- Run the terraform command (plan/apply).
Testing the Configuration
Testing CAPTCHA (Rate-Limited on /login)
- Open an incognito or private browser window to bypass any cached tokens.
- Access the /login path: https://your-domain.com/login
- Refresh the page at least 11 times within a one-minute window.
- Once the rate limit is exceeded, the CAPTCHA challenge page should appear, confirming that the rule is functioning as intended.


Testing Challenge (Global)
To validate that the global Challenge rule is active, run the following command in a terminal:
curl –i https://your-domain.com |
The expected output will be:
HTTP/2 202 server: CloudFront content-length: 0 x-amzn-waf-action: challenge |
This response indicates that AWS WAF is issuing a challenge. Since curl does not support JavaScript, it cannot complete the challenge validation, resulting in an empty response with a content-length of 0.
Beyond CAPTCHA and Challenge: Building a Broader WAF Protection Strategy
CAPTCHA and Challenge actions are effective for introducing friction in sensitive user-facing workflows such as login, signup, and checkout. These mechanisms help distinguish legitimate users from automated traffic, particularly when behavior appears suspicious but not definitively malicious.
However, some threats require immediate mitigation rather than friction. Attacks involving SQL injection, cross-site scripting (XSS), or traffic from known malicious IPs typically warrant outright blocking.
In such cases, AWS WAF Managed Rule Groups (MRGs) play a critical role by providing preconfigured protections against common and emerging web threats.
Managed Rule Groups
Managed rule groups are preconfigured sets of WAF rules maintained by AWS or third-party vendors available via the AWS Marketplace. Each group targets a specific category of threat—such as injection attacks, protocol anomalies, or automated bot traffic—and is continuously updated to reflect evolving attack patterns.
These rule groups simplify deployment by enabling comprehensive protection without the need to manually create and manage individual rules. While the internal rule logic is not customizable, updates are handled automatically, providing an effective, low-maintenance layer of security.
Detecting Bots with AWS Bot Control
For applications frequently targeted by automated traffic—such as crawlers, scrapers, or credential stuffing tools—AWS offers the Bot Control managed rule group (AWSManagedRulesBotControlRuleSet).
This rule group evaluates requests using attributes like user-agent strings, HTTP headers, and request behavior to detect non-human activity. It can take predefined actions or assign internal labels that can be referenced in custom WAF rules.
When used alongside CAPTCHA or Challenge actions, Bot Control helps apply verification steps selectively to traffic that demonstrates automated characteristics, reducing friction for legitimate users while increasing deterrence for bots.
Combining Protection Layers
The best results often come from combining multiple layers of protection:
- CAPTCHA and Challenge actions are effective for safeguarding interactive endpoints and slowing down suspicious or high-risk traffic.
- Managed Rule Groups automatically mitigate known attack vectors, malformed requests, and generic automation.
- Custom rules using labels offer precise control over specific request patterns and behaviors.
This layered approach improves coverage while minimizing false positives and maintaining a smooth experience for legitimate users.
Conclusion
AWS WAF’s CAPTCHA and Challenge actions provide a configurable and effective means to defend against automated threats. By introducing verification steps only under defined conditions, these mechanisms minimize disruption for legitimate users while mitigating risks such as credential stuffing, scraping, and brute-force attempts.
Compared to solutions like Cloudflare Turnstile, the AWS approach does not require changes to front-end code and offers complete control through rule-based configurations. This is particularly suited to teams aiming to enforce security policies natively within their AWS environment.
When integrated with Managed Rule Groups, CAPTCHA and Challenge actions contribute to a comprehensive security posture—automatically filtering known threats and selectively verifying suspicious traffic. The result is a robust, adaptable protection strategy that balances security, performance, and user experience.
About TrackIt
TrackIt is an international AWS cloud consulting, systems integration, and software development firm headquartered in Marina del Rey, CA.
We have built our reputation on helping media companies architect and implement cost-effective, reliable, and scalable Media & Entertainment workflows in the cloud. These include streaming and on-demand video solutions, media asset management, and archiving, incorporating the latest AI technology to build bespoke media solutions tailored to customer requirements.
Cloud-native software development is at the foundation of what we do. We specialize in Application Modernization, Containerization, Infrastructure as Code and event-driven serverless architectures by leveraging the latest AWS services. Along with our Managed Services offerings which provide 24/7 cloud infrastructure maintenance and support, we are able to provide complete solutions for the media industry.
TrackIt has also achieved the AWS Security Competency, demonstrating our ability to design and implement secure cloud architectures that align with AWS best practices.