Deny non-browser Traffic or Blocklisted ASNs

Learn how to block traffic from known threats with the Vercel WAF API.
Last updated April 11, 2025
Security

In the following example, we send a Patch request to the Update Firewall Configuration endpoint of the Vercel REST API security group. This request creates a new rule in your project's WAF configuration.

Both the conditionGroup and action body parameters are required fields

A common strategy to protect your web application from specific known threats, can include the following:

  • Denying non-browser traffic by targeting non "Mozilla" user-agents, which helps with blocking bots and scrapers.
  • Blocking traffic from certain Autonomous System Numbers (ASN) that are known to be associated with malicious activities.

To enable this on your Vercel project, create a custom rule using the following code:

app/api/firewall/route.ts
export async function PATCH() {
  let baseUrl = 'https://api.vercel.com/v1/security/firewall/config';
  let teamId = 'team_a5j...';
  let projectId = 'QmTrK...';
 
  const body = JSON.stringify({
    action: 'rules.insert',
    id: null,
    value: {
      active:
        true /** Whether this rule is enabled or not in your Vercel WAF configuration */,
      name: 'Deny non-browser traffic or blacklisted ASN',
      description: 'Deny traffic without Mozilla or from a specific ASN',
      conditionGroup: [ /** Any of the conditions in this array can be true */
        {
          conditions: [
            {
              neg: true, /** Perform negative match */
              op: "re", /** Operator used to compare - re equivalent to "Match regex expression" */,
              type: 'user_agent' /** Parameter from incoming traffic */,
              value: '.*Mozilla.*',
            },
          ],
        },
        {
          conditions: [
            {
              op: 'inc' /** Operator used to compare - inc equivalent to "Includes"*/,
              type: 'geo_as_number' /** Parameter from incoming traffic */,
              value: ["124", "456", "789"], /** includes any of the number combinations in the array */
            },
          ],
        },
      ],
      action: {
        mitigate: {
          action: 'deny',
          rateLimit: null,
          redirect: null,
          actionDuration: null,
        },
      },
    },
  });
 
  let res = await fetch(`${baseUrl}?projectId=${projectId}&teamId=${teamId}`, {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${process.env.VERCEL_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body,
  });
 
  if (!res.ok) {
    return Response.json(
      { status: 'Failed to update Firewall' },
      { status: res.status },
    );
  }
 
  return Response.json({ status: 'New rule added to Firewall' });
}