Waf

AWS WAF with rate limiting, IP reputation, OWASP core rules and SQL injection protection in one line. Starts in count mode so nothing breaks.

Security · anvil:aws:Waf

Attach it to a site with waf: { arn }, or to a Cognito user pool with a regional-scope WAF. Logging to CloudWatch is on by default (blocked and counted requests only, credentials redacted). Costs about $10/month plus $0.60 per million requests.

Minimal

The smallest config that deploys.

import { App } from '@anvil-cloud/sdk';
import * as anvil from '@anvil-cloud/sdk';

export default new App({
  run(ctx) {
    const edge = new anvil.aws.Waf('edge');
  },
});
import anvil_cloud as anvil

def infra(ctx: anvil.Context):
    edge = anvil.aws.Waf("edge")

anvil.App(run=infra)
package main

import (
    "github.com/anvil-cloud/anvil/sdk/go/anvil"
    anvilaws "github.com/anvil-cloud/anvil/sdk/go/anvil/aws"
)

func main() {
    anvil.Run(anvil.AppConfig{
        Run: func(ctx *anvil.Context) error {
            _, err := anvilaws.NewWaf(ctx.PulumiCtx(), "edge", nil)
            if err != nil {
                return err
            }
            return nil
        },
    })
}

Attaching it

Pass the WAF's arn to a site, or to a Cognito user pool with a WAF created with scope: 'regional' in the pool's region.

const site = new anvil.aws.SvelteKitSite('web', {
  path: 'web',
  waf: { arn: edge.arn },
});
site = anvil.aws.SvelteKitSite("web",
    path="web",
    waf=anvil.aws.SiteWafArgs(arn=edge.arn),
)
site, err := anvilaws.NewSvelteKitSite(ctx.PulumiCtx(), "web", &anvilaws.SvelteKitSiteArgs{
    Path: pulumi.String("web"),
    Waf:  &anvilaws.SiteWafArgs{Arn: edge.Arn},
})
if err != nil {
    return err
}

What attaching does

  • Every request to the site passes through the WAF's rules at CloudFront before it reaches your app.
  • While a WAF is attached, the site's server only accepts requests from CloudFront, so the WAF can't be bypassed.
  • One WAF can protect several sites. A scope that doesn't match what it's attached to fails the deploy.

Good to know

  • A new WAF starts in count mode: it logs what it would block but blocks nothing except ipBlockList. Check the logs, then set mode: 'block'. The Rollout and logs tab shows how.
  • CloudFront WAFs live in us-east-1 whatever your stack's region, so look for their logs and metrics there.
  • Costs about $10 a month with the defaults, plus $0.60 per million requests and CloudWatch Logs for blocked and counted requests.
  • Only the first 16 KB of a request body is inspected, so keep validating input in your app.
  • The Rules tab lists what's blocked by default, what isn't covered, and how it tested on AWS.

The Full example tab has a complete program. Every argument and attribute is on the Reference tab. More on: Rules,Rollout and logs.