Spam protection for forms: CAPTCHA and form tokens
This page is for website creators who keep spam and forged submissions out of forms. Two layers work together: a form token proves a post came from your own page, and a CAPTCHA asks the visitor to prove they are human.
Contents
Form tokens
The ezformtoken extension adds a secret token to every POST form and refuses posts without it, which stops forged
cross-site posts (CSRF). A refused post gets a 403 and one line in var/log/warning.log
(site.ini [HTMLForms], RefusalLogCollapseSeconds collapses repeats). Set your own
[HTMLForms] Secret in settings/override/site.ini.append.php; the shipped value says to change it. When a
visitor's form has expired, they see a friendly page instead of an error
(Form expired page).
CAPTCHA: reCAPTCHA or hCaptcha
recaptcha | hcaptcha | |
|---|---|---|
| Provider | Google reCAPTCHA (v2; a v3 template for the feedback form) | hCaptcha |
| Extra Composer package | google/recaptcha | none |
| Settings | settings/override/recaptcha.ini.append.php | settings/override/hcaptcha.ini.append.php |
| Docs | recaptcha | hcaptcha |
Both work the same way:
Activate the extension and get keys from the provider.
Put them in the override file (per host as arrays for several sites):
[Keys] PublicKey=<your site key> PrivateKey=<your secret key> [PublishSettings] NewObjectsOnly=falseKeep the secret key out of version control.
Add the CAPTCHA attribute to the class: a contact form class, or the user class for registration.
Clear caches and test the form logged out.
NewObjectsOnly=true checks only new objects (registration yes, editing a profile no).
The CAPTCHA widget loads a script from the provider: allow its host in the site's Content Security Policy when you enforce one (Content Security Policy), and mention the provider in your privacy note.
Which forms to protect
| Form | Protect with |
|---|---|
| Contact and feedback forms | token (automatic) and CAPTCHA |
User registration (user/register) | token and CAPTCHA on the user class |
| Comments | token and CAPTCHA on the comment class |
| Forms for logged-in users only | token is usually enough |
Other measures
- Require e-mail verification for registrations (
site.ini [UserSettings] VerifyUserType=email) (Member registration). - Limit what anonymous visitors may create (
content/createfor comments only where wanted). - Remove spam collections in Setup > Collected information in bulk.
Related pages
- Forms with the information collector
- Security hardening
- Visitor permissions: the Anonymous role
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.