Skip to content


Created: 2019-09-26 12:56:35 -0700 Modified: 2019-09-26 14:52:46 -0700

  • WAF itself is not region-specific, although you can create rules for specific regions.
  • WAF takes very little time to set up as long as you follow these instructions. It’s not some super-involved process, so feel free to use it reactively to block malicious attacks that you didn’t predict.
  • Web ACLs have rules, and rules have conditions, so you should make them in reverse order (conditions → rules → ACL). I tried going through just the rules originally and the UI didn’t really give me any options (likely because I didn’t have any conditions set up). The Web ACL wizard isn’t even that great in my opinion due to the UI being confusing (“String match condition created successfully” while also showing “You don’t have any string or regex match conditions.”). I think the easiest way to set this up is to go to the WAF console, then start by making conditions.
  • Web ACLs are associated with an Amazon API Gateway API, CloudFront distribution or Application Load Balancer. In order to associate to an API Gateway or ALB, you need to scope the ACL to a certain region (e.g. Oregon) where the resource is defined.
  • To make a rule matching a specific REST API route, it can be a little bit challenging based on how your server handles the route. For example, your route may be POST /login, but maybe your server also allows POST /login?foo, in which case you want to match both of those. However, maybe you also have POST /login/oauth that you don’t want to match for some reason. This requires two conditions—one to match the “POST”, and one to match the route
    • Condition #1
      • Type: Regex match
      • Filter on: URI
      • Transformation: Convert to lowercase
      • Regex: ^\loginb[^]*
        • Explanation
          • ^\login→ matches something that starts with “/login”
          • b → makes sure there’s nothing afterward, e.g. “/loginspecial”
          • [^]* → allows any other number of any character EXCEPT the forward slash, that way you don’t go into a new route like “/login/oauth”
    • Condition #2
      • Filter on: HTTP method
      • Match type: Exactly matches
      • Transformation: Convert to lowercase
      • Value to match: post
  • Great blog post here on rate-based rules: