Bot protection for Laravel

A single middleware, registered globally or per-route group, that scores every request before your controllers run.

How ZeroBot fits Laravel

Laravel makes this straightforward: the request lifecycle gives you a clean insertion point, and the queue system means you can log verdicts asynchronously without adding latency. The useful pattern is to score in middleware, block hard failures outright, and push everything else to a queued job so your threat log is complete without the request path paying for it. Because ZeroBot returns the individual signals alongside the score, you can build rules on specific reasons — datacenter ASN, Tor exit, headless browser — rather than on the score alone.

The integration

app/Http/Middleware/BotGuard.php

public function handle(Request $request, Closure $next) { $v = Http::withToken(config('services.zerobot.key')) ->asForm() ->post('https://api.zerobot.info/v3/openapi', [ 'ip' => $request->ip(), 'domain' => $request->getHost(), 'useragent' => $request->userAgent() ?? '', ])->json(); if (($v['risk_score'] ?? 0) >= 80) { abort(403); } $request->attributes->set('zerobot', $v); return $next($request); }

Full endpoint reference and an interactive tester are in the API docs. Get a key from the free tier — no card required.

What actually attacks Laravel sites

API abuse and enumeration

Laravel apps usually expose JSON endpoints that are cheaper to abuse than web pages. Scrapers probing /api/users/{id} generate far less obvious server load than page scraping, and often go unnoticed for months.

Credential stuffing on auth routes

Attacks against /login and /register from distributed residential proxies. Rate limiting alone does not stop them because each IP tries once.

Queue and webhook flooding

Public webhook endpoints that accept unauthenticated payloads are a cheap way to exhaust your queue workers and your database.

Frequently asked questions

Where should the middleware go?

Register it globally for a first pass so you can see the traffic shape, then move it to the route groups that matter and drop it from asset and health-check routes.

Can I fail closed?

Yes. ZeroBot fails open by default because an unreachable security service should not take your application down, but the API exposes the switch and you can set it per domain.

Does this work with Octane and queued requests?

Yes. The call is a plain HTTP request with no session or filesystem dependency, so it behaves identically under any runtime.

Protect your Laravel app this week.

Free tier, real verdicts, and documentation with a built-in tester.

Get started free →

Bot protection for other stacks

WooCommerce Node.js Django Next.js Cloudflare Worker