This documentation always refers to the latest published release.
Live demo: Try this and other plugins live, no installation, no risk: demo.markus-michalski.net
You find the settings in the Shopware Admin under Extensions > My Extensions > ALTCHA Spam Protection. Every setting can be overridden per sales channel. The sections below carry the card titles as they appear in the admin.
| Setting | Default | Description |
|---|---|---|
| Enable Spam Protection | on | Master switch for all protection features. When off, neither checks nor widget output run |
| Protect Newsletter Form | on | Protection for newsletter registration forms |
| Protect Registration Form | on | Protection for customer registration, prevents fake accounts |
The contact form has no switch of its own: it is protected as soon as the master switch is on.
| Setting | Default | Description |
|---|---|---|
| Enable ALTCHA Widget | on | Shows the "I'm not a robot" checkbox that verifies itself. When off, the ALTCHA check is skipped and the other layers stay active |
| Challenge Cost (PBKDF2 iterations) | 2000 | Work per attempt in the visitor's browser, minimum 1. Higher means harder and slower, for bots and visitors alike |
| Challenge Difficulty (max counter) | 2000 | Upper bound of the search, minimum 2. Each challenge needs between half of it and all of it attempts |
| Challenge Expiry (seconds) | 300 | How long a challenge is valid, between 30 and 3600 |
For safety the plugin internally caps the cost at 100000 and the counter at 1000000. A value of 0 or an empty field falls back to the default.
| Setting | Default | Description |
|---|---|---|
| Enable Honeypot Field | on | Adds an invisible field that traps bots. Legitimate visitors do not notice it |
The field is named fax_number, is moved out of the visible area with position:absolute; left:-9999px (not display:none, which some bots skip) and carries tabindex="-1" and autocomplete="off". A submission with a non-empty field is rejected. A value consisting only of whitespace counts as empty and is accepted.
| Setting | Default | Description |
|---|---|---|
| Minimum fill time (seconds) | 3 | Submissions arriving faster than this after the form was shown are treated as bots. 0 disables the check |
The form carries a signed render timestamp for this. If the token is missing or not authentic, the shop skips only this layer; the ALTCHA check is not affected. On uncached pages (for example registration) the check works reliably. On HTTP-cached CMS pages (contact, newsletter) a bot scraping the cached page carries an old token and passes this layer; the other layers still apply.
| Setting | Default | Description |
|---|---|---|
| Enable gibberish detection | off | Scores name, subject, message and address fields from 0 (ordinary text) to 100 (keyboard mashing) |
| Suspicious threshold (log only) | 60 | Scores at or above this value are written to the Shopware log but not blocked |
| Reject threshold | 85 | Scores at or above this value are rejected, allowed range 1 to 101. 101 means observe only: nothing is rejected, suspicious scores are still logged |
The scored fields are firstName, lastName, subject and comment as well as billingAddress.street and billingAddress.city, each taken from whichever form submits them. First and last name are therefore checked on registration, contact and newsletter, subject and message on the contact form, street and city on registration. The worst field decides. Log entries start with "ALTCHA gibberish check" and contain action, sales channel, score and reasons, never the text itself.
Recommended rollout: First set the reject threshold to
101, review the log entries for a few days, and only then lower the value.
How the score is built is described under Technical Details.
| Setting | Default | Description |
|---|---|---|
| Reject disposable e-mail addresses | off | Rejects addresses from known throwaway-inbox providers outright |
| Additional blocked domains | empty | One domain per line, subdomains included. Lines starting with # are ignored. Also used by content validation |
| Always allowed domains | empty | One domain per line. Overrides the list and the blocked domains, subdomains included, for example for privacy relay services your customers use |
foo.mailinator.com matches because mailinator.com is listed, notmailinator.com does not. IDN domains are compared in punycode when the PHP function idn_to_ascii (extension intl) is available. The field email is checked.disposable-email-domains list (CC0) ships with the plugin, plus a few built-in extra domains. A check never calls the network.var/mmd_altcha/. If it is on for a single sales channel only, run bin/console mmd:altcha:update-disposable-domains yourself. A failed download keeps the existing list.Multiple app nodes: The task refreshes the list only on the node that runs it. With several app nodes or a read-only container image, run the command on every node or rebuild the image, otherwise the other nodes keep using the bundled snapshot.
| Setting | Default | Description |
|---|---|---|
| Enable Content Validation | on | Checks first name, last name, street, city and e-mail address for gibberish and disposable domains. Blocks only with two or more suspicious fields |
This older, coarser check is deprecated in favour of gibberish detection and the disposable e-mail check. It is skipped as soon as one of them is on and will be removed in a future major version. Without those two options it keeps running with the defaults.
| Setting | Default | Description |
|---|---|---|
| Enable IP-based Rate Limiting | on | Limits form submissions per IP address |
| Max Requests | 3 | Maximum number per time window |
| Time Window (minutes) | 60 | Length of the sliding time window |
The limit applies separately per form (contact, newsletter, registration) and per IP address. Only submissions that passed all previous checks are counted: a rejected submission does not use up quota.
Behind a reverse proxy or CDN the shop only sees the real visitor IP if the trusted proxies are configured in Symfony. Otherwise all visitors share one address and therefore one limit.
| Setting | Default | Description |
|---|---|---|
| Enable Challenge Rate Limiting | on | Limits requests to /altcha/challenge per IP |
| Max Challenges per IP | 30 | Maximum number per time window |
| Time Window (minutes) | 60 | Time window for the challenge limit |
The limit is deliberately higher than for forms, because a page can load several forms with one challenge each.
Enable Spam Protection: on
Enable ALTCHA Widget: on
Challenge Cost: 4000
Enable gibberish detection: on
Reject threshold: 75
Reject disposable e-mail addresses: on
Max Requests: 2
Minimum fill time: 5
Enable gibberish detection: on
Reject threshold: 101 (observe only, lower after reviewing the log)
Reject disposable e-mail addresses: off
Enable gibberish detection: on
Suspicious threshold: 70
Reject threshold: 90
The trigram table behind gibberish detection covers German, English, French, Spanish, Italian and Dutch, so for many other languages you set the thresholds higher.