Deny non-browser Traffic or Blocklisted ASNs

Learn how to block traffic from known threats with the Vercel WAF API.
Last updated on November 21, 2024
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' });
}