AWS WAF is a web application firewall that helps protect your web applications from common web exploits.
Here’s a look at how it works in practice. Let’s say you have a WordPress site hosted on an EC2 instance behind an Application Load Balancer (ALB). You want to protect it from SQL injection attacks.
First, you’d create a Web ACL in AWS WAF. This Web ACL is essentially a container for your security rules.
aws wafv2 create-web-acl --name MyWordPressWAF --scope CLOUDFRONT --default-action Allow --visibility-config CloudWatchMetricsEnabled=true,MetricName=MyWordPressWAF,CloudWatchRegion=us-east-1
Next, you’d add a managed rule group to this Web ACL. AWS provides several managed rule groups, including one for common SQL injection attacks.
aws wafv2 put-web-acl-from-file --web-acl-id <your-web-acl-id> --web-acl-name MyWordPressWAF --scope CLOUDFRONT --default-action Allow --rules-file rules.json
The rules.json file would contain the definition for adding the managed rule group. A simplified example looks like this:
{
"Rules": [
{
"Name": "AWSManagedRulesCommonRuleSet",
"Priority": 0,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "CommonRuleSet"
}
},
"Action": {
"Block": {}
},
"OverrideAction": {
"None": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "CommonRuleSet"
}
}
],
"DefaultAction": {
"Allow": {}
},
"AssemblyConfig": {
"RuleGroupReturnStatement": {}
}
}
In this configuration, Priority: 0 means this rule is evaluated first. Action: Block means that if the request matches the SQL injection patterns in the CommonRuleSet, the request will be blocked. DefaultAction: Allow means that any request not matching a rule will be allowed.
Now, you associate this Web ACL with your CloudFront distribution or ALB. For an ALB, you’d go to the ALB’s configuration in the AWS console and under "AWS WAF" select your newly created Web ACL.
aws wafv2 associate-web-acl --web-acl-arn arn:aws:wafv2:<region>:<account-id>:webacl/<web-acl-id>/<web-acl-name> --resource-arn arn:aws:elasticloadbalancing:<region>:<account-id>:loadbalancer/app/<alb-name>/<alb-id>
When a user tries to access your WordPress site, the request first hits the ALB, which then consults the associated WAF Web ACL. If the request contains a string like ' OR '1'='1, the CommonRuleSet will detect it as a potential SQL injection attempt and, because of the Block action, the ALB will return a 403 Forbidden response to the user. If the request is clean, it passes through to your EC2 instance.
The real power comes from the detail within the managed rule sets. AWS analyzes common attack patterns and updates these rules continuously. For example, the CommonRuleSet includes rules for SQL injection, cross-site scripting (XSS), and command injection. You can also create your own custom rules based on specific patterns or IP addresses.
One aspect that often trips people up is understanding the difference between Scope when creating a Web ACL. CLOUDFRONT scope is for CloudFront distributions, while REGIONAL scope is for regional resources like Application Load Balancers, API Gateway, and AppSync. Choosing the wrong scope means your WAF rules won’t be applied to your resource.
The next step in securing your web application might involve setting up rate-based rules to prevent brute-force attacks.