6.3 KiB
Forum Bot Protection
This document describes the production anti-bot stack protecting forum, auth, profile, and selected API write actions.
Scope
Primary implementation lives in:
config/forum_bot_protection.phppackages/klevze/Plugins/Forum/Services/Securityapp/Http/Middleware/ForumBotProtectionMiddleware.phppackages/klevze/Plugins/Forum/Console/ForumBotScanCommand.phppackages/klevze/Plugins/Forum/Jobs/BotActivityMonitor.php
Protected actions currently include:
- registration
- login
- forum topic create
- forum reply create
- forum post update
- profile update
- selected API write routes
Detection Layers
Risk scoring combines multiple signals:
- honeypot hits
- browser and device fingerprints
- repeated content and spam phrase analysis
- account age and action burst behavior
- proxy, Tor, and blacklist checks
- provider and datacenter CIDR range checks
- account farm heuristics across IP and fingerprint reuse
The score is interpreted through config/forum_bot_protection.php:
allowlogcaptchamoderateblock
Persistence
Bot activity is stored in:
forum_bot_logsforum_bot_ip_blacklistforum_bot_device_fingerprintsforum_bot_behavior_profiles
User records also carry:
bot_risk_scorebot_flagslast_bot_activity_at
Captcha Escalation
When a request risk score reaches the configured captcha threshold, middleware requires a provider-backed challenge before allowing the action.
Provider selection:
FORUM_BOT_CAPTCHA_PROVIDER=turnstileFORUM_BOT_CAPTCHA_PROVIDER=recaptchaFORUM_BOT_CAPTCHA_PROVIDER=hcaptcha
Optional request input override:
FORUM_BOT_CAPTCHA_INPUT
Supported provider environment keys:
Turnstile
TURNSTILE_SITE_KEYTURNSTILE_SECRET_KEYTURNSTILE_SCRIPT_URLTURNSTILE_VERIFY_URL
reCAPTCHA
RECAPTCHA_ENABLEDRECAPTCHA_SITE_KEYRECAPTCHA_SECRET_KEYRECAPTCHA_SCRIPT_URLRECAPTCHA_VERIFY_URL
hCaptcha
HCAPTCHA_ENABLEDHCAPTCHA_SITE_KEYHCAPTCHA_SECRET_KEYHCAPTCHA_SCRIPT_URLHCAPTCHA_VERIFY_URL
If the selected provider is missing required keys, captcha escalation is effectively disabled and high-risk requests will continue through the non-captcha anti-bot path.
Origin Header Setup
Geo-behavior scoring only activates when the origin receives a trusted two-letter country header. The current analyzer checks these headers in order:
CF-IPCountryCloudFront-Viewer-CountryX-Country-CodeX-App-Country-Code
Recommended production setup:
Cloudflare
- If you only need country detection: Cloudflare Dashboard →
Network→ turnIP Geolocationon. - If you want the broader location header set: Cloudflare Dashboard →
Rules→Managed Transforms→ enableAdd visitor location headers. - The origin header used by this app is
CF-IPCountry.
Amazon CloudFront
- Edit the distribution behavior used for the app origin.
- Attach an origin request policy that includes geolocation headers, or create a custom origin request policy that forwards
CloudFront-Viewer-Country. - If you cache on that behavior and want cache variation by forwarded headers, ensure the paired cache policy is compatible with the origin request policy you choose.
Reverse Proxy / Load Balancer
- Pass the CDN country header through unchanged to PHP-FPM / Laravel.
- For Nginx, avoid clearing the header and explicitly preserve it if you normalize upstream headers, for example:
proxy_set_header CF-IPCountry $http_cf_ipcountry;orproxy_set_header CloudFront-Viewer-Country $http_cloudfront_viewer_country;. - If you terminate the CDN header at the proxy and want a normalized application header instead, map it to
X-Country-Codeand keep the value as a two-letter ISO country code.
Validation:
- Send a request through the real edge and confirm the header is visible in Laravel request headers.
- Check that a login event stored in
forum_bot_logs.metadata.country_codecontains the expected country code.
IP Range Configuration
IP reputation supports three types of network lists in config/forum_bot_protection.php:
known_proxies: exact IPs or CIDRs for proxy and VPN rangesdatacenter_ranges: generic datacenter or hosting CIDRsprovider_ranges: provider-specific buckets such asaws,azure,gcp,digitalocean,hetzner, andovh
All three lists accept either exact IP strings or CIDR notation.
Example:
'ip' => [
'known_proxies' => ['198.51.100.0/24'],
'datacenter_ranges' => ['203.0.113.0/24'],
'provider_ranges' => [
'aws' => ['54.240.0.0/12'],
'hetzner' => ['88.198.0.0/16'],
],
],
Operational guidance:
- keep provider ranges in the named
provider_rangesbuckets so the control panel can show per-provider coverage counts - populate ranges only from provider-owned feeds or other trusted sources you maintain internally
- after changing CIDR lists, clear cache if you need immediate effect on hot IPs
Queue and Scheduling
Recent activity scanning runs through:
- command:
php artisan forum:bot-scan - queued job:
BotActivityMonitor - schedule: every 5 minutes in
routes/console.php
Default command behavior dispatches the monitor job onto the configured queue. Use --sync for inline execution.
Admin Operations
Control panel screen:
- route:
admin.forum.security.bot-protection.main
Available actions:
- review recent bot events
- inspect suspicious users
- inspect high-risk fingerprints
- inspect recent rate-limit violations and their limiter metadata
- manually blacklist IPs
- approve or ban flagged users
- confirm current captcha provider, threshold, and required env keys
- confirm configured proxy, datacenter, tor, and provider CIDR coverage counts
- filter analytics by time window and action
- export recent bot events as CSV
- export top bot reasons as JSON
Validation Checklist
Useful commands:
php artisan forum:bot-scan --helpphp artisan forum:bot-scan --sync --minutes=5php artisan route:list --name=admin.forum.security.bot-protection.mainnpm run build
Quick runtime checks:
- confirm new bot events land in
forum_bot_logs - confirm fingerprints land in
forum_bot_device_fingerprints - confirm the jobs table contains
BotActivityMonitorafterforum:bot-scan - confirm the control panel shows the expected captcha provider and action list