DEV Community

Cover image for Securing APIs with AWS WAF Bot Control and Advanced Rate Limiting
Sidra Saleem for SUDO Consultants

Posted on • Originally published at sudoconsultants.com

Securing APIs with AWS WAF Bot Control and Advanced Rate Limiting

APIs are the backbone of modern applications, enabling seamless communication between services. However, this also makes them a prime target for malicious actors. Credential-stuffing attacks, where attackers use stolen credentials to gain unauthorized access, are one of the most common threats. AWS provides a robust set of tools to secure your APIs, including AWS WAF (Web Application Firewall) and Lambda@Edge. This article will guide you through securing your APIs using AWS WAF Bot Control and advanced rate limiting, with a focus on blocking credential-stuffing attacks.

Understanding the Threat: Credential-Stuffing Attacks

Credential-stuffing attacks occur when attackers use automated bots to test large volumes of stolen username and password combinations against login endpoints. These attacks exploit the fact that many users reuse credentials across multiple services. The impact can be devastating, leading to unauthorized access, data breaches, and reputational damage.

To mitigate these attacks, we need to:

  1. Detect and block malicious bots.
  2. Implement rate limiting to prevent brute-force attempts.
  3. Use advanced techniques to identify and block suspicious traffic patterns.

AWS WAF Overview

AWS WAF is a web application firewall that helps protect your web applications and APIs from common web exploits. It allows you to create rules that control access to your content based on conditions like IP addresses, HTTP headers, and custom URI strings. AWS WAF also provides managed rule groups, which are pre-configured rules maintained by AWS or AWS Marketplace sellers.

Key Features of AWS WAF

  • Bot Control: Identify and block malicious bots.
  • Rate-Based Rules: Automatically block IP addresses that exceed a specified request rate.
  • Managed Rule Groups: Pre-configured rules for common threats like SQL injection and cross-site scripting (XSS).
  • Custom Rules: Create rules tailored to your specific needs.

Implementing AWS WAF Bot Control

AWS WAF Bot Control is a managed rule group that helps you identify and block malicious bots. It uses machine learning to detect and categorize bots, allowing you to take action based on their behavior.

Step 1: Set Up AWS WAF

Before you can use AWS WAF, you need to set it up in your AWS account.

CLI-Based Setup

  1. Create a Web ACL:A Web ACL (Access Control List) is a collection of rules that define how AWS WAF should handle incoming requests.
   aws wafv2 create-web-acl \
       --name MyWebACL \
       --scope REGIONAL \
       --default-action Allow={} \
       --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=MyWebACLMetric \
       --region us-east-1
  1. Add the Bot Control Managed Rule Group:Add the AWS Managed Rules Bot Control rule group to your Web ACL.
   aws wafv2 update-web-acl \
       --name MyWebACL \
       --scope REGIONAL \
       --default-action Allow={} \
       --rules Name=BotControlRule,Priority=1,Statement={ManagedRuleGroupStatement={VendorName=AWS,Name=AWSManagedRulesBotControlRuleSet}},OverrideAction={Count={}},VisibilityConfig={SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=BotControlMetric} \
       --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=MyWebACLMetric \
       --region us-east-1

AWS Console-Based Setup

  1. Navigate to AWS WAF & Shield:Go to the AWS Management Console, and under "Security, Identity, & Compliance," select "WAF & Shield."
  2. Create a Web ACL:Click on "Create web ACL," provide a name (e.g., MyWebACL), and select the region where your API is hosted.
  3. Add the Bot Control Rule Group:In the "Add rules and rule groups" section, click on "Add managed rule groups." Select the "AWS Managed Rules" and choose "Bot Control." Set the action to "Count" initially to monitor the traffic before blocking it.
  4. Review and Create:Review your settings and click "Create web ACL."

Step 2: Deploy the Web ACL to Your API

Once the Web ACL is created, you need to associate it with your API.

CLI-Based Deployment

  1. Associate the Web ACL with an API Gateway:If your API is hosted on API Gateway, you can associate the Web ACL using the following command:
   aws wafv2 associate-web-acl \
       --web-acl-arn arn:aws:wafv2:us-east-1:123456789012:regional/webacl/MyWebACL/abc12345-6789-0123-4567-890123456789 \
       --resource-arn arn:aws:apigateway:us-east-1::/restapis/abc12345-6789-0123-4567-890123456789/stages/prod \
       --region us-east-1

AWS Console-Based Deployment

  1. Navigate to API Gateway:Go to the API Gateway console and select your API.
  2. Associate the Web ACL:In the "Stages" section, select the stage (e.g., prod) where you want to deploy the Web ACL. Under the "Settings" tab, find the "Web ACL" section and select the Web ACL you created earlier.
  3. Save Changes:Click "Save" to associate the Web ACL with your API.

Step 3: Monitor and Tune Bot Control

After deploying the Bot Control rule group, monitor the traffic to ensure it’s correctly identifying and blocking malicious bots.

  1. CloudWatch Metrics:AWS WAF integrates with Amazon CloudWatch, allowing you to monitor the traffic and rule matches. Navigate to the CloudWatch console and look for metrics related to your Web ACL.
  2. Adjust Rules:If you notice false positives or negatives, you can adjust the rules. For example, you can change the action from "Count" to "Block" for specific bot categories.

Implementing Advanced Rate Limiting

Rate limiting is a critical component of API security, especially for login endpoints. AWS WAF provides rate-based rules that allow you to block IP addresses that exceed a specified request rate.

Step 1: Create a Rate-Based Rule

CLI-Based Setup

  1. Create a Rate-Based Rule:Create a rate-based rule that blocks IP addresses exceeding 100 requests in a 5-minute period.
   aws wafv2 create-rate-based-rule \
       --name MyRateBasedRule \
       --scope REGIONAL \
       --metric-name MyRateBasedRuleMetric \
       --rate-key IP \
       --rate-limit 100 \
       --region us-east-1
  1. Add the Rule to Your Web ACL:Add the rate-based rule to your Web ACL.
   aws wafv2 update-web-acl \
       --name MyWebACL \
       --scope REGIONAL \
       --default-action Allow={} \
       --rules Name=MyRateBasedRule,Priority=2,Statement={RateBasedStatement={Limit=100,AggregateKeyType=IP}},Action={Block={}},VisibilityConfig={SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=RateBasedRuleMetric} \
       --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=MyWebACLMetric \
       --region us-east-1

AWS Console-Based Setup

  1. Navigate to AWS WAF & Shield:Go to the AWS Management Console, and under "Security, Identity, & Compliance," select "WAF & Shield."
  2. Create a Rate-Based Rule:Click on "Create rule," select "Rate-based rule," and provide a name (e.g., MyRateBasedRule). Set the rate limit to 100 requests per 5 minutes and choose "IP" as the aggregate key.
  3. Add the Rule to Your Web ACL:In the "Add rules and rule groups" section, click on "Add my own rules and rule groups." Select the rate-based rule you created and set the action to "Block."
  4. Review and Create:Review your settings and click "Create."

Step 2: Deploy the Rate-Based Rule

Associate the rate-based rule with your API, as described earlier.

Step 3: Monitor and Tune Rate Limiting

Monitor the traffic to ensure the rate-based rule is effectively blocking excessive requests. Use CloudWatch metrics to identify any false positives or negatives and adjust the rate limit as needed.

Enhancing Security with Lambda@Edge

Lambda@Edge allows you to run AWS Lambda functions at AWS Edge locations, enabling you to customize the content delivered through CloudFront. This can be used to implement advanced security measures, such as custom rate limiting and bot detection.

Step 1: Create a Lambda@Edge Function

CLI-Based Setup

  1. Create a Lambda Function:Create a Lambda function that inspects incoming requests and blocks suspicious traffic.
   aws lambda create-function \
       --function-name MyLambdaEdgeFunction \
       --runtime nodejs14.x \
       --role arn:aws:iam::123456789012:role/lambda-edge-role \
       --handler index.handler \
       --zip-file fileb://function.zip \
       --region us-east-1
  1. Deploy the Function to Lambda@Edge:Deploy the Lambda function to Lambda@Edge.
   aws lambda publish-version \
       --function-name MyLambdaEdgeFunction \
       --region us-east-1

AWS Console-Based Setup

  1. Navigate to AWS Lambda:Go to the AWS Management Console, and under "Compute," select "Lambda."
  2. Create a Lambda Function:Click on "Create function," provide a name (e.g., MyLambdaEdgeFunction), and select the Node.js runtime.
  3. Deploy the Function to Lambda@Edge:In the "Actions" menu, select "Deploy to Lambda@Edge." Choose the CloudFront distribution associated with your API and select the event type (e.g., "Viewer Request").

Step 2: Implement Custom Rate Limiting in Lambda@Edge

  1. Inspect Incoming Requests:Use the Lambda function to inspect incoming requests and count the number of requests from each IP address.
   const AWS = require('aws-sdk');
   const dynamoDB = new AWS.DynamoDB.DocumentClient();

   exports.handler = async (event) => {
       const request = event.Records[0].cf.request;
       const clientIP = request.clientIp;

       // Check the request count for the client IP
       const params = {
           TableName: 'RateLimitingTable',
           Key: { ip: clientIP },
       };

       const data = await dynamoDB.get(params).promise();
       const requestCount = data.Item ? data.Item.count : 0;

       if (requestCount > 100) {
           return {
               status: '429',
               statusDescription: 'Too Many Requests',
               body: 'Rate limit exceeded',
           };
       }

       // Update the request count
       const updateParams = {
           TableName: 'RateLimitingTable',
           Key: { ip: clientIP },
           UpdateExpression: 'SET #count = if_not_exists(#count, :start) + :inc',
           ExpressionAttributeNames: { '#count': 'count' },
           ExpressionAttributeValues: { ':start': 0, ':inc': 1 },
       };

       await dynamoDB.update(updateParams).promise();

       return request;
   };
  1. Deploy the Function:Deploy the Lambda function to Lambda@Edge and associate it with your CloudFront distribution.

Step 3: Monitor and Tune Lambda@Edge

Monitor the traffic and adjust the rate limit as needed. Use CloudWatch logs to identify any issues and optimize the function.

Real-Life Implementation: Case Study

Scenario: E-Commerce Platform

An e-commerce platform was experiencing a high volume of credential-stuffing attacks on its login endpoint. The platform implemented AWS WAF Bot Control and advanced rate limiting, along with a custom Lambda@Edge function for additional protection.

Results

  • Bot Control: Blocked 95% of malicious bot traffic.
  • Rate Limiting: Reduced the number of brute-force attempts by 90%.
  • Lambda@Edge: Provided an additional layer of security, blocking suspicious traffic patterns that bypassed WAF rules.

Lessons Learned

  • Continuous Monitoring: Regularly monitor traffic and adjust rules as needed.
  • Layered Security: Combine multiple security measures (e.g., WAF, Lambda@Edge) for comprehensive protection.
  • Customization: Tailor security measures to your specific use case for optimal results.

Conclusion

Securing APIs against credential-stuffing attacks requires a multi-layered approach. AWS WAF Bot Control and advanced rate limiting provide a strong foundation, while Lambda@Edge offers additional customization and flexibility. By following the steps outlined in this article, you can effectively protect your APIs from malicious bots and brute-force attacks, ensuring the security and reliability of your applications.

Implementing these measures not only enhances security but also builds trust with your users, safeguarding their data and your reputation. As the threat landscape evolves, staying proactive and leveraging the full suite of AWS security tools will be key to maintaining a robust defense.

Top comments (0)