Application layer bot protection for Shopware 6. Protects forms and endpoints against automated abuse as a complement to network level protection (for example Cloudflare), focused on what the network layer cannot see.
- Honeypot field - invisible form field in contact form, newsletter signup, registration and login. Hidden via off-screen positioning instead of display:none, which simple bots detect. If the field is filled, the request is treated as a bot and discarded.
- Rate limiting per endpoint - configurable limits per endpoint (contact form, newsletter, login, registration). Checks IP and session combined, so a single abusive client is blocked without punishing a whole NAT or company network. Cookie-less bots are caught by a wider IP scoped limit.
- Time based form validation - blocks forms that are submitted faster than a configurable threshold (typical bot behaviour). The render timestamp travels inside the form as an HMAC signed token, so it works together with HTTP caching and needs no session storage.
- Admin dashboard - statistics, a 14 day chart, the most recent blocked attempts (time, IP, endpoint, reason) and the full plugin configuration on one page under Settings.
- AI threat analysis (optional) - one click summary of the last 7 days of blocked requests, powered by Claude. Only aggregated counts are transferred, never IP addresses or user agents.
- GDPR compliant logging - blocked attempts are stored in a dedicated table. A daily scheduled task removes IP addresses after 7 days and deletes whole entries after 30 days (both configurable). Session IDs are only stored as SHA-256 hashes.
- No CAPTCHA and no third party services - everything runs self-hosted inside Shopware
- No firewall or network level IP blocking - application layer only
- Blocked requests receive a clean error message (JSON alert or flash message plus redirect), never a hard 403
| Admin dashboard | Live configuration |
|---|---|
![]() |
![]() |
(Screenshots are in docs/screenshots/. See the section below for how they were produced.)
This plugin was tested end to end against a running Shopware 6.7.1.1 instance, not just unit tested in isolation. Three attack scenarios were triggered live and confirmed to appear in the admin dashboard within seconds:
1. Honeypot - hidden field filled (contact form)
$ curl -X POST https://shop.example/form/contact \
-H "X-Requested-With: XMLHttpRequest" \
-d "micha_bp_website=http://spam-bot.example" \
-d "email=bot@spam.example"
[{"type":"danger","alert":"<div class=\"alert alert-danger\">Your request could
not be processed. Please reload the page and try again.</div>"}]
2. Time validation - no signed token (login)
$ curl -o /dev/null -w "status: %{http_code}\n" -X POST https://shop.example/account/login \
-d "email=bot2@spam.example" -d "password=irrelevant123"
status: 302 # redirected back to the login page with a flash message
3. Rate limit - 6 requests in the same session, limit is 5 (newsletter)
Request 1: "type":"success"
Request 2: "type":"success"
Request 3: "type":"success"
Request 4: "type":"success"
Request 5: "type":"success"
Request 6: "type":"danger" <- blocked, limit exceeded
False positive check: a normal, human-speed form submission (real browser, realistic typing delay, valid session) was not blocked in any of these tests - only the deliberately bot-like requests were caught.
All three attempts above show up immediately in Settings -> Bot Protection, each tagged with the correct reason (Honeypot / Time validation / Rate limit), timestamp and IP:
Additionally verified:
vendor/bin/phpunit- 20 tests, 126 assertions, all green (rate limiter, time validator, honeypot)phpstan analyse --level 8- no errors- Admin JS builds cleanly via
bin/build-administration.shand loads without console errors bin/console dal:validate- no errors for this plugin's entity
- Shopware 6.7.x
- PHP 8.2+
# Copy plugin to custom/plugins/
cp -r MichaBotProtection /var/www/html/custom/plugins/
# Install and activate
bin/console plugin:refresh
bin/console plugin:install --activate MichaBotProtection
bin/console cache:clearThen rebuild the admin JS:
bin/build-administration.sh
bin/console assets:installAll settings are available in the admin under Settings -> Bot Protection (or via the plugin configuration):
| Setting | Default | Description |
|---|---|---|
| Honeypot field active | on | Invisible field, filled means bot |
| Time based validation active | on | Minimum seconds between page load and submit |
| Minimum time in seconds | 3 | Faster submissions are treated as bots |
| Rate limiting active | on | Fixed window rate limiting |
| Time window in minutes | 15 | Window length and duration of the temporary block |
| Contact form limit | 5 | Max requests per window |
| Newsletter limit | 5 | Max requests per window |
| Login limit | 10 | Max attempts per window |
| Registration limit | 5 | Max requests per window |
| Delete log entries after | 30 days | Full deletion of blocked attempt entries |
| Remove IP addresses after | 7 days | IPs are removed earlier than the rest of the entry |
| Anthropic API Key | empty | Optional, enables the AI threat analysis |
# from the Shopware root
vendor/bin/phpunit -c custom/plugins/MichaBotProtection/phpunit.xmlThe unit tests cover the core detection logic (rate limiter, time validation, honeypot) and run without a database or kernel.
Subscriber/FormProtectionSubscriber- hooks into the kernel request after routing and checks the four protected routesService/HoneypotValidator,Service/TimeValidator,Service/RateLimiter- pure detection logic, unit testedService/BlockedAttemptLogger- writes blocked attempts through the DAL repositoryCore/Content/BlockedAttempt- DAL entity for the log tableScheduledTask/CleanupTaskHandler- daily GDPR cleanupService/AiThreatAnalyzerplusController/ThreatAnalysisController- optional AI analysis via admin API
Michael Barabanov - mbara.net


