meteo-concept/hiddenfieldantispam-bundle
Symfony bundle that adds a hidden honeypot field to forms, silently blocking spam bots that fill it in while letting real users submit normally. A lightweight, CAPTCHA-free antispam layer that requires no user interaction and minimal setup.
This is the initial release (v1.0.1), so treat it as a first-look, not a stable dependency. The stated core is present: it detects bots and returns an error message to them while leaving normal traffic alone. Translation of that message is explicitly unfinished, which tells you the user-facing surface is small and still moving.
php artisan vendor:publish --tag=<vendor>-config) and read the config end-to-end before touching anything. The defaults define your allow/deny baseline.# Should return the package's bot error
curl -i -A "curl/8.0" https://your-app.test/protected
# Should pass through
curl -i -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..." https://your-app.test/protected
If the second command also gets blocked, stop and fix the matcher before going further.
Route-scoped middleware is the safe default. Global middleware on a v1.0.x bot filter is a good way to block your own uptime monitor. Prefer:
Route::post('/contact', ContactController::class)
->middleware('bot-block');
Layer it with throttling, don't replace it. Bot filtering complements throttle: — it does not substitute for rate limiting. A spoofed user-agent defeats UA matching entirely, so keep the rate limiter in front.
Centralize the allowlist in config, not code. Health checks, synthetic monitors, Stripe webhooks, and your own CI all look like bots. Keep them in the published config's allow/allowlist section (or an env-driven override) so ops can adjust without a deploy:
'allow' => array_filter(explode(',', env('BOT_BLOCK_ALLOW', ''))),
Test the block path in feature tests. Use Laravel's header helpers to pin behavior:
$this->withHeader('User-Agent', 'Googlebot/2.1')
->get('/protected')
->assertStatus(/* whatever the package returns */);
Write one test for the blocked case and one for the passthrough case. When v1.x changes the response code (likely, given the release is a first cut), the test tells you immediately.
Log every block, at least initially. Wrap or observe the middleware so you can answer "did we block a real customer?" Bot filters fail silently by design; without a log you won't know you have false positives until someone complains.
Keep it behind a toggle. An env flag read in the config lets you disable blocking instantly during an incident without reverting a deploy.
$request->ip() is the proxy unless TrustProxies is configured. IP-based bot rules will match or miss the wrong thing entirely. Check config/trustedproxy before you trust any IP logic.bootstrap/app.php. If the bot middleware runs after session/auth middleware, blocked requests still touch the database and session store. Move it early to get the cheap-rejection benefit.curl, python-requests, Go-http-client, axios, and empty UA strings are the common offenders — but so is your own queue worker hitting an internal endpoint. Test your own infrastructure before enabling globally."vendor/package": "1.0.*") and read the changelog before minor bumps; expect the config keys and the public middleware name to be the most likely things to shift.How can I help you explore Laravel packages today?