Markus Michalski FAQ

ALTCHA Spam Protection

ALTCHA proof-of-work spam protection for Sylius forms and the Shop API - channel-configurable protection targets, honeypot, rate limiting, disposable-mail and gibberish checks

Deutsche Version

Back to Sylius Plugins

ALTCHA Spam Protection

Sylius
PHP
License

This documentation always describes the latest published version.

Live Demo: Try this and other plugins live — no installation, no risk: demo.markus-michalski.net

Overview

Privacy-friendly spam protection for Sylius storefront forms and the Shop API, based on ALTCHA proof-of-work. No cookies, no fingerprinting, no third-party requests - the visitor's browser solves a small computational puzzle automatically on submit, without visitor input, instead of clicking tiles or reading distorted text.

Which forms are protected is decided per channel in the admin, not globally.

Privacy: Every check runs on your own server. Nothing is sent to an external service, and no cookie or fingerprint is set.

Built-in targets: registration, contact, login, forgotten password, and the checkout sign-in (rate-limit only). The support form (mmd/sylius-support-form-plugin) and the newsletter signup (mmd/sylius-newsletter-management-plugin) are detected automatically when installed and appear in the same admin list. Any other form - from a custom plugin or your own code - can be added through the admin.

graph LR
    A["Storefront (Twig hook)"] --> C["ALTCHA check chain"]
    B["Shop API (header X-Altcha-Payload)"] --> C
    C --> D["Channel settings"]
    D --> E{"Result"}
    E -->|"accepted"| F["Form / API request is processed"]
    E -->|"rejected"| G["Form error / HTTP 422"]

Documentation

Page Contents
Installation and Operations Installation, update, cron jobs, uninstall
Configuration Per-channel settings, admin grids, practical examples
Content Checks Disposable-mail and gibberish checks in detail: scope, matching, scoring, rollout
Storefront Integration Placing the widget, Twig function and hooks, theme notes
Shop API / Headless Challenge endpoint, requests, error format
Extensibility and Compatibility Custom targets, service tags, backward compatibility
Troubleshooting and FAQ Common problems, known limitations, frequent questions
Technical Details How the checks run, plugin structure, entities

Features

Feature Description
Proof-of-work challenge PBKDF2 challenge the browser solves automatically on submit without visitor input, signed with a per-channel HMAC secret
Single-use proofs A solved challenge is accepted exactly once (replay protection)
Rate limiting Per form and client address, checked before a challenge is consumed
Honeypot field Invisible field that only a bot fills in
Minimum fill time Signed timestamp rejects submissions sent faster than a human could type
Disposable-mail check Opt-in: rejects addresses from known throwaway-inbox providers, with operator allow/deny overrides
Gibberish check Opt-in: scores free-text fields and rejects keyboard mashing and nonsense text
Dual mode Works identically in the Twig storefront and headless through the Shop API
Per-channel configuration Every setting - targets, difficulty, rate limit, content checks - is scoped to one channel

Requirements

Requirement Version Notes
Sylius ^2.2 Developed against 2.3; CI runs the full test suite on Sylius 2.2 and 2.3
PHP ^8.3 With the sodium extension
Symfony ^7.4 Symfony 8 is not supported by Sylius 2.x and is therefore excluded
Database MySQL 8 or MariaDB PostgreSQL is not supported. The migrations are written in MySQL syntax and deliberately abort on other databases. Do not install the plugin in a PostgreSQL project, because the abort would also block all subsequent migrations of your project. Tested against MySQL 8.4, MariaDB is not verified (on DBAL 3 the target_overrides JSON column may additionally need a (DC2Type:json) comment there).
APP_SECRET non-empty Channel secrets are encrypted with a key derived from it; all application servers must share the same value
doctrine/dbal ^3.9 or ^4.0 Sylius 2.2 pins DBAL 3, Sylius 2.3 allows 4; both run the full test suite. On DBAL 3 the three DATETIME columns carry a (DC2Type:datetime_immutable) comment. Moving that database to DBAL 4 (Sylius 2.2 to 2.3) makes your host's next schema diff list those three columns once, like the Sylius core tables; running the generated migration clears it.
altcha-org/altcha ~2.1.0 Pinned - the bundled widget script and this library speak one protocol

License

License

Commercial license: one Sylius installation (all channels, plus its development and staging environments) per license, no redistribution, updates for 12 months from purchase. The bundled ALTCHA widget scripts and the disposable-domain list keep their own licenses (MIT and CC0 respectively).

Support

For licensing, technical questions or bug reports, contact support@markus-michalski.net.