WAF guide/How a request gets checked
Edge readySend a request

Your site is public. Your rulesdecide who gets in.

Webflow's Web Application Firewall checks requests to your custom domains at the edge, before your site loads. Follow one through, then send your own.

One request, start to finish

Every visit to a custom domain on Webflow takes the same route. Scroll, and this one makes the trip.

  1. Visitor
    GET /pricing
    Request

    A visitor asks for a page

    Someone opens www.yoursite.com/pricing. The request carries their IP address, a User-Agent, and the path.

  2. Webflow edge
    cdn.webflow.com
    Edge

    It lands on Webflow's edge

    Your custom domain points at Webflow's global edge network. The request arrives at a nearby location, and the firewall runs there.

  3. Platform rules
    Runs first
    Platform rules

    Webflow's rules go first

    Account-level security rules apply to every Webflow site. They run before yours and can block a request on their own.

  4. Your WAF rules
    Bots · IP · Country · ASN · UA
    WAF rules
    403 Forbidden

    Then your rules decide

    Your site's rules run in a fixed order. If one blocks the request, the visitor gets a 403 Forbidden response and never reaches your site.

  5. Your site
    200 OK
    Your site

    Everyone else gets your site

    A request that clears every check is served from your published site, exactly as it would be without a firewall.

Five checks, always in this order

After Webflow's platform rules, your rules run in a fixed sequence. You can't reorder them, so the order is worth knowing by heart.

Webflow's platform rules

Account-level rules that Webflow applies to all sites. They run before anything you configure, so a request they block never reaches your rules.

Verified bots skip your rules

With Allow verified bots on, Cloudflare-verified bots like Googlebot and GPTBot bypass your site's rules. Every other request moves on to the IP check.

IP addresses and ranges

Match single IPv4 or IPv6 addresses, or CIDR ranges. Entries are read top to bottom and the first match wins: BLOCK ends the request with a 403, ALLOW skips the rest of the IP list.

{ "ips": [
  { "ip": "203.0.113.4", "mode": "BLOCK" },
  { "ip": "198.51.100.0/24", "mode": "BLOCK" }
] }

Countries

Match the visitor's country by its two-letter ISO code. BLOCK denies the countries you list. ALLOW denies every country you don't.

{ "countryList": ["DE", "AT", "CH"], "mode": "ALLOW" }

Networks (ASN)

An Autonomous System Number names the network a request comes from, like a cloud host or an ISP. Blocking hosting networks stops a lot of scraper traffic, and a network is much harder to fake than a User-Agent.

{ "asnList": [16509, 14061, 24940], "mode": "BLOCK" }

Amazon (16509), DigitalOcean (14061), Hetzner (24940).

User-Agent

Match text anywhere in the User-Agent header, ignoring case. Patterns run top to bottom and the first match wins, so put your exceptions first.

{ "patterns": [
  { "pattern": "Googlebot", "mode": "ALLOW" },
  { "pattern": "bot", "mode": "BLOCK" }
] }

A User-Agent is whatever the client says it is. Anyone can claim to be Googlebot, which is why verified bots get their own check.

Cleared every check? Your site loads.

There's no catch-all at the end: a request nothing blocked is served normally. And an ALLOW never ends the check early. A request your IP list allows still faces the country, ASN, and User-Agent rules.

BLOCK lists who's out. ALLOW lists who's in.

Every rule can block or allow. They sound like mirror images. On country and network rules they're not: an ALLOW list turns away everyone you didn't name.

Geo-blocking
{ "countryList": ["DE", "AT", "CH"], "mode": "BLOCK" }
  • GB
  • US
  • JP
  • US
  • MX
  • CA
  • US
  • FR
  • AU
  • CA
  • ES
  • US
  • GB
  • JP
  • AT
  • DE
  • ES
  • GB
  • KR
  • IN
  • CH
  • MX
  • ES
  • US
  • US
  • FR
  • NL
  • US
  • BR
  • You · US
  • DE
  • DE
  • BR
  • IN
  • DE
  • CH
  • NL
  • NL
  • US
  • JP
  • GB
  • AU
  • SE
  • KR
  • US
  • FR
  • US
  • AT
  • BR
  • SE
  • GB
  • IN
  • AU
  • US
  • CA
  • FR
  • DE
  • US
  • IN
  • CA

9of 60 visitors blocked

BLOCK turns away only the countries you list. Everyone else gets through.

Allow lists are powerful and easy to get wrong. If your team, your agency, or your uptime monitor sits outside the list, they're locked out too. When in doubt, use BLOCK.

Keep search engines in.

A rule that blocks every User-Agent containing "bot" catches a lot of junk. It would catch Googlebot too, unless verified bots get through first.

Bots

Allow verified bots

Cloudflare-verified bots like Googlebot or GPTBot skip your rules. Turning this off can affect search indexing.

Active rule{ "pattern": "bot", "mode": "BLOCK" }
  • Googlebot

    Mozilla/5.0 (compatible; Googlebot/2.1)

    Verified
    UA rule
    Served
  • GPTBot

    Mozilla/5.0 (compatible; GPTBot/1.2)

    Verified
    UA rule
    Served
  • "Googlebot" on a cloud server

    Mozilla/5.0 (compatible; Googlebot/2.1)

    Not verified
    UA rule
    403
  • Scraping script

    python-requests/2.32

    Not verified
    UA rule
    Served

The scraping script never says "bot", so this rule lets it through. Pair User-Agent rules with an ASN rule for scrapers on cloud networks.

Where rules apply, and when

The practical edges: which pages a rule covers, which domains it protects, how much you can fit, and how fast a change goes live.

Pagespaths
  • Home/
  • Pricing/pricing
  • Promo/promoGeo rule
  • Spring sale/promo/springGeo rule
  • Promotions/promotions
  • Blog/blog

Scope rules with paths

Add a paths list to a country, ASN, or User-Agent rule and it only runs there. A path covers itself and everything under it: /promo matches /promo/spring, but not /promotions.

{ "countryList": ["DE", "AT", "CH"],
  "mode": "ALLOW",
  "paths": [{ "path": "/promo" }] }

Custom domains only

Rules apply to every custom domain connected to the site. Your webflow.io staging domain isn't covered.

PublishCustom domains
  • www.yoursite.comProtected
  • yoursite.comProtected
  • yoursite.webflow.ioNot covered
SecurityRule budget
IPCountryASNUser-Agent0.4 of 4 KB

One 4KB budget

All your rules share a single 4KB configuration budget. Ranges and networks go further than long lists of single addresses.

Live in minutes, no publish

Saved changes can take up to 5 minutes to reach the edge. You don't need to publish your site.

Changes to WAF rules and settings may take up to 5 minutes to apply. You don't need to publish your site.
SavedLive at the edge
yoursite.com/promo

403

Blocked means 403

A blocked visitor gets an HTTP 403 Forbidden response instead of your page.

Now send your own

Pick a visitor, change the rules, and send. The simulator follows the same order and matching as the real firewall. Every visitor here is a made-up example.

VisitorExample
IP203.0.113.24
CountryDE
ASN64500 · Example ISP
User-AgentMozilla/5.0 (Macintosh) Safari
Verified botNo
Path
  1. Platform rulesWaiting0
  2. Verified botsWaiting0
  3. IPWaiting0
  4. CountryWaiting0
  5. ASNWaiting0
  6. User-AgentWaiting0
  7. Your siteWaiting0
···

Ready when you are

Pick a visitor, then send the request.

  1. TraceIdleEach check explains its verdict here after you send a request.
GET /pricing
Rulesyoursite.com
Allow verified bots
IP blockingFirst match
Geo-blocking
ASN blockingBLOCK
User-Agent filteringFirst match
{ "ips": [{ "ip": "203.0.113.4", "mode": "BLOCK" }] }

0 bytes of the 4 KB budget

Request log0 requests
  1. ···Waiting for your first requestResults show up here, newest first.

Set it up in Site settings

  1. 1

    Open Site settings for the site you want to protect.

  2. 2

    Go to Security.

  3. 3

    Choose Add rule, pick a rule type, and edit its JSON.

  4. 4

    Save. Changes reach the edge within 5 minutes, and you don't need to publish.

Your site stays public. Now it's public on your terms.

Back to the simulator