Bot protection for Django

Standard Django middleware, placed high in MIDDLEWARE so it runs before sessions and authentication touch the request.

How ZeroBot fits Django

Placement is the whole game in Django. Middleware runs top-down, so bot screening belongs above SessionMiddleware and AuthenticationMiddleware — otherwise every request creates a session row and a database hit before it is rejected, which is exactly the cost you were trying to avoid. Above those, a blocked request costs one function call and one HTTP round trip.

The integration

yourapp/middleware.py

import requests from django.conf import settings from django.http import HttpResponse class BotGuardMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): v = requests.post( 'https://api.zerobot.info/v3/openapi', headers={'Authorization': f'Bearer {settings.ZEROBOT_KEY}'}, data={ 'ip': request.META.get('REMOTE_ADDR', ''), 'domain': request.get_host(), 'useragent': request.META.get('HTTP_USER_AGENT', ''), }, timeout=0.5, ).json() if v.get('risk_score', 0) >= 80: return HttpResponse(status=403) return self.get_response(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 Django sites

Session table exhaustion

Anonymous bots that fetch every URL create a session row per request. Django makes this easy to miss until the session table is the largest thing in your database.

Admin path probing

Automated sweeps for /admin, /wp-login.php and other known paths, generating constant noise in your logs and occasional indexing of anything left unauthenticated.

Form and endpoint flooding

Public forms without a CAPTCHA are trivially scriptable, and DRF endpoints can be enumerated cheaply if the URL scheme is predictable.

Frequently asked questions

Where in MIDDLEWARE should this go?

Above SessionMiddleware. Anything below it has already paid the session cost by the time the verdict arrives.

The timeout is 0.5s — is that too aggressive?

It is deliberate. A short timeout with a fail-open fallback keeps your worst-case request latency bounded. ZeroBot’s median is under 50ms, so the timeout is a safety valve rather than the normal path.

Does this work with Django REST Framework?

Yes — middleware runs before DRF views, so API endpoints are covered by the same guard.

Protect your Django app this week.

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

Get started free →

Bot protection for other stacks

WooCommerce Laravel Node.js Next.js Cloudflare Worker