DEV Community

Mustafa Güngör
Mustafa Güngör

Posted on

I built an open-source alternative to Cloudflare Turnstile using Fitts's Law and Kinematics

Hey everyone! 👋

I’ve always hated intrusive CAPTCHAs and expensive proprietary cloud WAFs. Even the "invisible" ones (like Cloudflare Turnstile or reCAPTCHA v3) are black boxes that collect massive amounts of user telemetry.

So, I spent the last few months building Synapse Shield — a completely open-source, self-hosted behavioral bot mitigation engine for Python (FastAPI/Django/Flask) and React.


🧠 How it works (Kinematics & Math)

Instead of just checking if a mouse moves in a straight line, Synapse Shield analyzes 19D kinematic vectors in sub-milliseconds:

  1. Jerk (3rd Derivative of Position): Human muscles have micro-tremors. Bots (even advanced Bézier curve bots) produce near-zero or static Jerk. The engine looks for biological tremors ($da/dt$).
  2. Fitts's Law Terminal Deceleration: Humans naturally decelerate as the cursor approaches a target to click. We measure the terminal_decel_ratio to catch bots.
  3. Poisson Anomaly Detection: Headless API flooders are caught using a cumulative Poisson distribution algorithm.

✨ Key Features & Hardening (v0.5.0)

  • Async Non-Blocking SLA (<0.5ms): Offloaded via asyncio.to_thread so it never blocks the FastAPI/Django event loop.
  • 🔐 Cryptographic Replay Defense: Uses HMAC-SHA256 signed nonces (with SQLite WAL) to ensure tokens can't be replayed.
  • Accessibility Mode: accessibility_mode=True gracefully scales down kinematic thresholds so motor-impaired users aren't falsely flagged.
  • ⚛️ React & Next.js SSR Support: Native "use client" Drop-in Component and hook to avoid Hydration errors.
  • 📈 Enterprise Prometheus Metrics: Native PROMETHEUS_MULTIPROC_DIR support for Gunicorn/Uvicorn workers.

🚀 Quick Code Example (FastAPI)


python
from fastapi import FastAPI, Request
from synapse_shield import shield_protect, SynapseShieldMiddleware

app = FastAPI()
app.add_middleware(SynapseShieldMiddleware, protected_paths=["/api/auth"])

@app.post("/api/login")
@shield_protect(max_risk_score=50.0, accessibility_mode=False)
async def login(request: Request):
    return {"status": "authenticated"}

I'm a 2nd-year Computer Engineering student, and I built this to bridge the gap between low-level math and modern web frameworks.

I’d love your feedback, code audits, or ideas on how to improve the kinematics engine!
Enter fullscreen mode Exit fullscreen mode

Top comments (0)