Privacy-friendly spam protection for OXID eShop 7.x contact and newsletter forms using ALTCHA proof-of-work, honeypot fields, and IP-based rate limiting.
ALTCHA is a self-hosted, privacy-friendly CAPTCHA alternative. Unlike Google reCAPTCHA or hCaptcha:
Instead of image puzzles, ALTCHA uses Proof-of-Work - the user's browser must solve a small computational challenge (SHA-256 hashing). This takes about 1-2 seconds and happens automatically in the background. Bots would need significant computing power to bypass this at scale.
/kontakt/)/newsletter/)Add the private Composer repository to your shop's composer.json:
{
"repositories": [
{
"type": "composer",
"url": "https://packeton.markus-michalski.net"
}
]
}
Note: Repository credentials will be provided upon license purchase. Private repositories are managed via Packeton.
composer require mmd/oxid7-altcha-integration
When prompted for authentication, enter the credentials provided with your license.
vendor/bin/oe-console oe:module:activate mmd_altcha
vendor/bin/oe-console oe:cache:clear
Note: When installed via Composer, OXID automatically registers the module from
vendor/. Theoe:module:installcommand is only needed for modules insource/modules/.
Update to the latest version:
composer update mmd/oxid7-altcha
vendor/bin/oe-console oe:cache:clear
Module configuration in OXID Admin:
Extensions > Modules > ALTCHA Spam Protection > Settings
| Setting | Default | Description |
|---|---|---|
| Enable Module | On | Master switch for all protection features |
| Setting | Default | Description |
|---|---|---|
| Enable ALTCHA | On | Shows "I'm not a robot" checkbox that auto-verifies |
| Max Number (Difficulty) | 50000 | Higher = harder challenge, more CPU time required |
| Expiry Seconds | 300 | How long a challenge is valid (5 minutes default) |
| HMAC Secret | (auto) | Auto-generated if empty. Secret key for signing challenges |
About Challenge Difficulty:
| Setting | Default | Description |
|---|---|---|
| Enable Honeypot | On | Adds invisible trap field that catches bots |
| Field Name | website | Name of the honeypot input field |
The honeypot is a hidden form field that legitimate users never see or fill out. Bots that automatically fill all form fields will trigger this trap.
| Setting | Default | Description |
|---|---|---|
| Enable Rate Limiting | On | Limits form submissions per IP address |
| Max Requests | 5 | Maximum submissions per time window |
| Window Minutes | 60 | Rate limit window (1 hour default) |
Note: IP addresses are stored as SHA-256 hashes with HMAC in the database for GDPR compliance. The original IP cannot be reconstructed from the hash.
| Setting | Default | Description |
|---|---|---|
| Enable Challenge Rate Limit | On | Protects challenge endpoint from DoS attacks |
| Max Challenges | 30 | Maximum challenges per IP per window |
| Window Minutes | 60 | Rate limit window for challenges |
The module validates submissions in this order (optimized for performance):
A submission must pass ALL enabled checks to be accepted.
The module creates two database tables:
Stores rate limiting data:
ip_hash - HMAC-SHA256 hash of IP addressaction - Action identifier (e.g., "contact_form", "newsletter", "challenge")request_count - Number of requests in current windowwindow_start - Start of current rate limit windowStores used ALTCHA challenges to prevent replay attacks:
challenge_hash - Hash of the used challengeused_at - When the challenge was usedexpires_at - When to delete this entry (automatic cleanup)Returns a new ALTCHA challenge for the widget:
{
"algorithm": "SHA-256",
"challenge": "abc123...",
"maxnumber": 50000,
"salt": "xyz789...",
"signature": "sig..."
}
This endpoint is automatically called by the ALTCHA widget when the form loads.
The module uses OXID 7 Template Extensions to inject the ALTCHA widget and honeypot fields into forms. Templates are located in:
views/twig/extensions/themes/apex/
├── form/
│ ├── contact.html.twig # Contact form integration
│ └── newsletter.html.twig # Newsletter form integration
└── layout/
└── base.html.twig # JavaScript/CSS injection
For custom template integrations, these methods are available on oViewConf:
{# Check if features are enabled #}
{% if oViewConf.getAltchaEnabled() %}
{# ALTCHA is active #}
{% endif %}
{% if oViewConf.getHoneypotEnabled() %}
{# Honeypot is active #}
{% endif %}
{# Get configuration values #}
{{ oViewConf.getChallengeUrl() }} {# Challenge endpoint URL #}
{{ oViewConf.getHoneypotFieldName() }} {# Honeypot field name #}
{{ oViewConf.getAltchaStrings() }} {# Localized widget strings #}
This module is designed with privacy in mind:
| Aspect | Implementation |
|---|---|
| External Services | None - fully self-hosted |
| Cookies | None |
| User Tracking | None |
| IP Storage | HMAC-SHA256 hashed only |
| Data Retention | Automatic cleanup of expired entries |
| Consent Required | No - no personal data processing |
Important: Since no cookies are set and no data is sent to third parties, you do NOT need to add this module to your cookie consent banner.
| Feature | ALTCHA (this module) | Google reCAPTCHA | hCaptcha |
|---|---|---|---|
| Self-hosted | ✅ Yes | ❌ No | ❌ No |
| GDPR without consent | ✅ Yes | ❌ No | ❌ No |
| No cookies | ✅ Yes | ❌ No | ❌ No |
| No external requests | ✅ Yes | ❌ No | ❌ No |
| User experience | ✅ Auto-verify | ⚠️ Image puzzles | ⚠️ Image puzzles |
| Accessibility | ✅ WCAG 2.2 AA | ⚠️ Limited | ⚠️ Limited |
| Server load | ⚠️ Minimal | ✅ External | ✅ External |
vendor/bin/oe-console oe:cache:clearvendor/bin/oe-console oe:module:listsource/log/ for detailed error messagesIncrease "Max Requests" or "Window Minutes" in module configuration.
The honeypot relies on bots filling hidden fields. Sophisticated bots might skip hidden fields. Use ALTCHA as primary protection.
vendor/bin/oe-console oe:module:deactivate mmd_altcha
rm -rf var/cache/* source/tmp/*
vendor/bin/oe-console oe:module:activate mmd_altcha
Commercial License - Single installation license:
Development and staging environments included. 12 months free updates.
See LICENSE file for full terms.
For questions and support:
Markus Michalski
Email: support@markus-michalski.net