I recently had to attach a Web Application Firewall (WAF) regional Access Control List (ACL) to an API gateway created using the Serverless Framework. The only quality documentation I could find was from our very own Natalie Laing in this post she wrote back in 2019. I ran into an issue where my WebACL would not properly associate to the API. After some research I found that many others also faced this issue, mainly because the ‘Classic WAF’ has been depreciated by AWS.
AWS WAFV2 is the latest version of the AWS WAF API released in November 2019. Configuring the WAFV2 with an API is pretty straightforward, however, there are little resources available online. Hence, this post is to help those who are as lost as I was configuring a WAFV2 with an API gateway.
I got the tip on these ahead of my implementation thanks to Natalie’s article.
arn:aws:apigateway:{region}::/restapis/{rest_api_id}/stages/{stage_name}
To configure your WAF you'll need to provision a WebACL then associate it to your API. In this case I was configuring a WAF to block SQL injection, however, this format could be used for other security protocols as well. Hence, the resources required at a minimum are:
WebACL:
Type: "AWS::WAFv2::WebACL"
Properties:
Name: WebACLSQLi
Scope: REGIONAL
Description: Web ACL to block SQL injection
DefaultAction:
Allow: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: MyMetricName
Rules:
- Name: SQLInject-RuleSet
Priority: 0
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesSQLiRuleSet
OverrideAction:
None: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: SQLInjection-ruleset-metric
WebACLAssociation:
Type: "AWS::WAFv2::WebACLAssociation"
Properties:
WebACLArn: !GetAtt WebACL.Arn
ResourceArn: !Ref ApiARN
I have used Amazon's Managed Rules to do the hard work of SQL injection blocking. You can see the other rule sets available here
If your API was created using the Serverless Framework you will need to run npm i serverless-associate-waf.
In your serverless.yml you will need to utilize this plugin:
plugins:
- serverless-associate-waf
You will then need to append the following snippet:
custom:
associateWaf:
name: WebACLSQLi
version: V2
The name must be the name you specified in your WebACL.
And voila, that's it. Simple right? Hopefully this post saves you the hours of frustration I endured.
If you'd like your API's secured, feel free to contact-us.