Copy link to headingHow to block or challenge unwanted traffic with Vercel WAF custom rules
The live monitor on your project's Firewall page is where unwanted traffic shows up first. A spike from a country, network, or client you weren't expecting is usually the sign that something needs a rule. The Vercel Web Application Firewall (WAF) gives you that rule, and applying it takes effect globally within 300ms without a new deployment.
Here's how the rules engine works, followed by the rules teams set up first and the legitimate traffic each one can block by accident.
Copy link to headingWhat can Vercel WAF custom rules do?
A custom rule compares a parameter from the incoming request against a value you set, then applies an action when the conditions match. You can combine conditions with AND or OR, and you can reorder rules so the ones you want evaluated first run first.
Parameters fall into three groups. Request properties include path, route, HTTP method, user agent, header, query, cookie, hostname, and protocol. Location conditions match on continent, country, state, city, IP address, and Autonomous System Number (ASN). Client fingerprints use the JA3 and JA4 TLS digests.
The operator decides how that parameter is compared to your value, with choices including exact matches, list membership, contains, starts with, ends with, and Perl Compatible Regular Expressions (PCRE). Any operator can be negated, so a condition can read as user agent does not contain Mozilla.
Each rule ends in one of five actions:
- Log: Records the match and lets the request through untouched. Rule evaluation continues afterward, so a later rule can still act on the request.
- Deny: Returns a
403 Forbiddenand stops evaluating further rules. The request never reaches your application. - Challenge: Serves the Vercel Security Checkpoint, which a client passes only by executing JavaScript. Real browsers solve it once and continue, while scripts cannot.
- Bypass: Skips every remaining custom rule and lets the request through. This is how you exempt trusted automation from a rule that would otherwise catch it.
- Redirect: Sends a temporary
307to a path you choose and stops evaluating further rules. Matched traffic lands somewhere you control instead of being blocked.
Deny and challenge are the two actions you'll choose between. Deny fits traffic that no human would send, such as vulnerability scans. Challenge fits a condition that a real visitor might also meet, and a browser that passes gets a 1-hour session before it has to solve the check again. Because both are cheap to get wrong, every rule in this guide starts in Log mode so you can watch the match before you enforce it.
Copy link to headingHow to block traffic from specific countries in the Vercel WAF
Geographic rules are the most common starting point, usually after a spike appears from a region you don't serve. They also cover the reverse case, where sanctions or data protection rules require you to turn a region off.
To see the current split, open the Firewall overview page. Select Allowed Requests from the traffic grouping drop-down, then Country for the secondary drop-down.
Once you know which country you want to act on, create the rule:
- From your dashboard, select your project, then open Firewall in the sidebar.
- Select ⋯ > Configure on the top right of the Firewall overview page.
- Select Add New... > Rule.
- Enter a name such as
Ireland trafficand a description such asUnderstand Ireland traffic spike. - In the Configure section, set the If condition to Country Equals, then select the country in the third drop-down.
- Select Log for the Then action, then select Save Rule.
- Select Review Changes, review what will be applied, then select Publish.
- Watch the rule'’ traffic on the Firewall overview page until you're satisfied the match is right.
- Return to the rule, change Then to Deny, save, and publish again.
Country is derived from the client IP address, so the rule follows the network the visitor is on rather than where they live. Visitors on a VPN, traveling, or behind a corporate egress in another region will match too. That's the main reason to sit in Log mode long enough to see a full traffic cycle before denying.
Copy link to headingHow to deny non-browser traffic or blocklisted ASNs with the Vercel WAF API
Country rules act on where a request comes from. A user agent condition acts on the client software making the request, and a network condition acts on the ASN it connects from. One rule can carry both.
Real browsers all report a Mozilla token, so matching user agents that lack one catches bots and scrapers that never bothered to spoof it. An ASN condition turns off entire networks tied to malicious activity. The field accepts digits only.
The following route sends a PATCH request to the Update Firewall Configuration endpoint to insert that rule, with the two conditions in separate condition groups so either one can match:
Both conditionGroup and action are required. A condition this broad also matches uptime monitors, CI jobs, your own API clients, and search crawlers. Set the action to log first and read what it catches. If your goal is bot traffic rather than a specific network, the Bot Protection managed ruleset excludes verified bots such as Google's crawler automatically.
Copy link to headingHow to deny traffic from a set of IP addresses with a WAF IP blocking rule
User agents and ASNs cover broad patterns. Once you've identified the exact addresses behind the traffic, an IP blocking rule is more precise, and it applies across every domain on the project at once. It fits an IP network tied to a DDoS attack or automated bot traffic, and any network you're required to block under sanctions or data protection law.
The following route inserts a project-level IP blocking rule for a /24 range across all hostnames:
Project-level IP blocking allows up to 3 rules on Hobby, 100 on Pro, and 1000 on Enterprise. Ranges are shared infrastructure. A /24 can cover a corporate gateway or a mobile carrier alongside the address you're targeting, so narrowing the CIDR is safer than widening it. To do the same for one address from the dashboard, see blocking a single IP.
Copy link to headingHow to challenge cURL requests with a WAF custom rule
Denying an address only works once you know it. Challenges work on clients you can't enumerate, because they test capability rather than identity.
cURL (Client URL) is a common vehicle for scraping, brute force attempts, and other automated activity. A challenge is the right action here rather than a deny, since a real browser solves it once and continues while the script cannot.
The following route inserts a rule that challenges any request whose user agent contains curl:
Automated tools can't establish a challenge session. That's the point of the rule and also its cost. Legitimate command-line clients, deploy scripts, and partner integrations hitting the same paths will start failing. Give those sources a system bypass rule or a custom rule with the bypass action before you enforce.
Copy link to headingHow to block PHP requests with a Vercel WAF rule
Scanners look for the same handful of paths on every site they touch, and .php is near the top of the list. If your application doesn't serve PHP, a path rule turns that entire class of probe into a 403.
Blocking these requests helps in a few ways:
- Vulnerability scanning: Attackers scan for PHP files to find exploitable versions or misconfigurations, and a deny rule ends the scan at the first request.
- Log noise: Probe traffic you don't serve makes real errors harder to spot, so removing it improves what's left.
- Exploitation attempts: Automated attacks target WordPress, phpMyAdmin, and other PHP applications, none of which exist on a project that doesn't use PHP.
Because the condition is a path match rather than a signature, one rule covers every variant a scanner tries.
Create the rule from the dashboard:
- From your dashboard, select your project, then open Firewall in the sidebar.
- Select ⋯ > Configure on the top right of the Firewall overview page.
- Select Add New... > Rule.
- Enter
Block .php request pathsas the name andBlocks any request containing .phpas the description. - In the Configure section, set the If condition to Request Path Contains, then type
.phpin the input box. - Select Log for the Then action, then select Save Rule.
- Select Review Changes, review what will be applied, then select Publish.
- Watch the rule's traffic on the Firewall overview page to confirm it only matches probes.
- Return to the rule, change Then to Deny, save, and publish again.
The condition matches anywhere in the path, so a route such as /blog/from-php-to-node matches too. Check the logged traffic for your own URLs before switching to Deny, and tighten the condition to Ends with if you need to.
Copy link to headingHow to challenge cookieless requests on a specific path with the WAF API
Path and user agent rules act on the request surface. A cookie condition goes one step further and acts on session state, protecting an authenticated area from requests your own front end never issued.
A request to a sensitive path with no session cookie rarely comes from your own front end. Challenging it prevents unauthorized access and adds a layer against CSRF attacks, short for Cross-Site Request Forgery.
The following route inserts a rule that challenges requests starting with /api when they don't carry a _session cookie, using two conditions in the same group so both must match:
Requests your application makes inside a valid challenge session succeed automatically, so first-party calls from a browser that has already solved the challenge are unaffected. Webhooks, mobile clients, and server-to-server calls to /api are a different matter, since they can't establish a session. Give them a bypass rule, or scope the path condition to the routes that require a session.
Copy link to headingHow to test Vercel WAF rules before you enforce them
Each of these rules lands in the same place, a condition you believe matches only unwanted traffic. Testing is how you find out whether that belief is correct, while the cost of being wrong is still zero.
Follow the same sequence each time:
- Create the rule with a Log action and publish it.
- Watch the live traffic view on the Firewall overview page, grouping by the parameter your condition uses.
- Adjust the condition until the matches contain only traffic you're willing to block.
- Change the action to Challenge, Deny, or Bypass, then publish again.
Two features make the switch safer. Persistent actions add a time-based block to a challenge or deny action. A client that trips the rule then stays blocked at the platform-wide firewall for a window you choose. And if a rule misbehaves once live, open View Audit Log from the ellipsis menu on the Firewall page and restore an earlier configuration.
Copy link to headingNext steps
Once a rule matches the traffic you want, the same test-then-enforce sequence applies to every other condition the WAF supports. Browse more WAF examples for rules built around headers, methods, and TLS fingerprints, or start a new project to configure the firewall on a fresh deployment.
Copy link to headingRelated resources
- WAF Custom Rules
- Rule Configuration Reference
- Firewall concepts
- WAF IP Blocking
- Blocking traffic from a specific IP address
- Limit abuse with rate limiting
Copy link to headingFAQ
What is the difference between the Vercel WAF and the Vercel Firewall?
The Vercel Firewall is the platform-wide layer that inspects every request and handles DDoS mitigation for every project with no configuration. The Vercel WAF is the part you configure yourself at the project level, through custom rules, IP blocking, and managed rulesets. It's available on all plans.
What happens when a request fails a Vercel WAF challenge?
A client that fails the check is blocked before the request reaches your application. Solving it creates a challenge session in that browser, valid for 1 hour, after which the client has to solve the check again. Scripts, cURL, and Postman can't establish a session, so direct API calls fail while the rule is active.
Can you configure Vercel WAF rules in code?
Yes. The REST API, Vercel SDK, and Terraform provider all manage WAF configuration, and the vercel firewall CLI covers custom rules and IP blocks. You can also define rules in vercel.json under routes with a mitigate property, though that path supports only the deny and challenge actions.
Does traffic blocked by the Vercel WAF count toward usage?
Requests mitigated by a deny, challenge, or rate limit action don't incur CDN Requests or Fast Data Transfer. The same applies to persistent actions, IP blocking, DDoS mitigation, and Attack Challenge Mode. Requests that pass a challenge continue to your application and count as normal usage.
How many Vercel WAF custom rules can you create?
Custom rules are capped at 3 per project on Hobby, 40 on Pro, and 1000 on Enterprise. Every custom rule parameter is available on all three plans, apart from JA3 (Legacy), which is Enterprise only. Managed rulesets require an Enterprise plan.