Wat een formulier echt beschermt: CAPTCHA, honeypot, tijdval, CSRF
De meeste contactformulieren vertrouwen op één enkele truc tegen spam, en veel van die trucs houden alleen de eenvoudigste bots tegen. Wat elke beschermingslaag tegenhoudt, wat ze kost en welke combinatie zinvol is.
Spam via contactformulieren komt zelden van iemand die met de hand typt. Meestal is het software die formulieren vindt, elk veld invult en het resultaat verstuurt – duizenden keren. Er bestaan meerdere verdedigingen, en die grijpen op heel verschillende punten in. Wie weet wat elke verdediging werkelijk doet, vermijdt twee fouten: een formulier zonder echte bescherming, en een formulier dat zo zwaar bewaakt is dat echte mensen het opgeven.
- Honeypot: eenvoudige bots die elk veld invullen
- Tijdval: scripts die direct na het laden verzenden
- CAPTCHA: de meeste generieke automatisering
- CSRF-token: verzoeken die rechtstreeks naar het eindpunt worden gestuurd
- Rate limit: stortvloeden vanuit één bron
- Proof-of-work: goedkope massa-inzendingen, zonder tracking of puzzels
- Controles aan de serverkant: alles wat de browser omzeilt
- Gerichte bots slaan hem over; slecht verborgen wordt hij door schermlezers voorgelezen
- Bots die wachten; zonder handtekening aan de serverkant makkelijk te vervalsen
- Een drempel voor iedereen, toegankelijkheidsbarrières, vaak van derden; er bestaan oplosdiensten
- Bots die eerst de pagina laden, krijgen ook een geldig token
- Spam verspreid over veel IP-adressen
- Een vastberaden verzender met rekenkracht; vereist JavaScript
- Op zichzelf niets – maar zonder deze controles is elke andere laag decoratie
Honeypot en tijdval: onzichtbare filters
Een honeypot is een extra veld dat mensen nooit zien, zoals een veld met de naam “website” dat met CSS is verborgen. Eenvoudige bots vullen elk veld in, dus een ingevulde honeypot wijst op automatisering en de server kan het bericht stilletjes weggooien. Bots die voor uw site zijn geschreven, of die de pagina als een browser weergeven, slaan hem over. Verberg hem goed: een veld dat alleen buiten beeld is geschoven, kan door schermlezers worden voorgelezen, met de Tab-toets worden bereikt of door automatisch aanvullen worden ingevuld. Gebruik aria-hidden, tabindex -1 en autocomplete off, plus een neutraal label dat iedereen die er terechtkomt vraagt het leeg te laten.
Een tijdval registreert wanneer het formulier is geleverd en weigert inzendingen die onwaarschijnlijk snel binnenkomen. Mensen hebben een paar seconden nodig om te lezen en te typen; veel scripts verzenden binnen een fractie van een seconde. Het tijdstempel moet op de server worden gecontroleerd en tegen manipulatie zijn beschermd, bijvoorbeeld ondertekend of in de sessie bewaard – een gewoon verborgen tijdveld wordt door de bot simpelweg overschreven. Houd de drempel laag, want door automatisch aanvullen zijn ook echte mensen snel. Bots die gewoon wachten, komen erdoor: een tijdval is een filter, geen muur.
CAPTCHA: effectief, maar niet gratis
Een CAPTCHA vraagt om bewijs dat er geen bot aan het werk is – van beeldpuzzels tot controles die op de achtergrond draaien; bekende diensten zijn reCAPTCHA, hCaptcha, Cloudflare Turnstile en Friendly Captcha. Een CAPTCHA houdt de meeste generieke automatisering tegen en is daarom zo populair. Maar elke zichtbare puzzel is een drempel waarbij sommige bezoekers afhaken, en de meeste diensten laden een script van derden, wat vragen over privacy en toestemming oproept. Een CAPTCHA helpt bovendien alleen als hij correct is ingesteld: een openbare test-sitesleutel, een widget zonder script of een token dat de server nooit verifieert, ziet eruit als bescherming maar is het niet. Een gratis controle op formexposed.com wijst zulke fouten van buitenaf aan.
Toegankelijkheid hoort bij die kosten. Beeldpuzzels sluiten blinde mensen en veel slechtziende mensen buiten, audioalternatieven helpen doofblinde mensen niet, en lastige logische opgaven belasten mensen met een cognitieve beperking. WCAG 2.2-succescriterium 1.1.1 vereist een tekstalternatief dat het doel van de CAPTCHA beschrijft, en alternatieve vormen voor verschillende zintuigen. Achtergrondcontroles vermijden het meeste hiervan, maar als ze argwaan krijgen, is de terugvaloptie vaak weer een visuele puzzel – test dat pad met een toetsenbord en een schermlezer.
CSRF-token: bescherming tegen vervalsing, niet tegen spam
Een CSRF-token is een willekeurige waarde die de server in het formulier zet en terug verwacht. Het is ontworpen tegen cross-site request forgery, waarbij een andere website de browser van een bezoeker een verzoek laat versturen dat de bezoeker nooit heeft bedoeld. Bij een openbaar contactformulier heeft het een neveneffect: bots die rechtstreeks naar het formulieradres posten zonder de pagina te laden, worden geweigerd. Elke bot die de pagina ophaalt en het token terugstuurt, komt erdoor. De meeste frameworks en formulierplug-ins hebben sowieso CSRF-tokens – laat ze aan, maar reken ze niet tot de spambescherming.
Wat er op de server moet gebeuren
- Valideer elk veld opnieuw op de server: verplichte velden, lengte, e-mailformaat, en geen regeleinden in velden die in mailheaders terechtkomen.
- Verifieer CAPTCHA- en proof-of-work-tokens bij elke inzending, bij de uitgevende dienst of in uw eigen code, en weiger tokens die opnieuw worden gebruikt.
- Beperk inzendingen per IP-adres en tijdvenster. Dat stopt stortvloeden vanuit één bron; spam die over veel adressen is verspreid, vraagt om andere lagen.
- Overweeg proof-of-work: vóór het verzenden lost de browser een kleine rekenopgave op. Bezoekers zien geen puzzel en er wordt niets gevolgd, maar massaal verzenden wordt duur.
Een zinvolle combinatie: twee of drie lagen
- 1Begin met de onzichtbare lagen: een toegankelijke honeypot en een ondertekende tijdval, beide op de server gecontroleerd.
- 2Voeg een rate limit per IP-adres toe, zodat één bron het formulier niet kan overspoelen.
- 3Komt er nog steeds gerichte spam door, voeg dan proof-of-work of een CAPTCHA toe – bij voorkeur een zonder zichtbare puzzel en met een toegankelijk alternatief.
- 4Behoud het CSRF-token dat uw framework biedt – als bonus, niet als verdediging.
- 5Test het resultaat als bezoeker – alleen met het toetsenbord, met een schermlezer, op een telefoon – en controleer of echte berichten nog aankomen.
Op veel sites houden honeypot, tijdval en rate limit samen al de meeste generieke spam tegen zonder enige zichtbare drempel; een CAPTCHA is de reserve voor als dat niet genoeg is. Op WordPress combineert de gratis plug-in van formexposed honeypot, tijdcontrole en proof-of-work zonder Google nodig te hebben. Om te zien wat uw formulier van buitenaf laat zien – welke lagen aanwezig zijn, of een CAPTCHA effectief is geconfigureerd – heeft een gratis controle op formexposed.com alleen een domein nodig, geen account. De controle kan uw servercode niet zien, dus het deel aan de serverkant blijft uw taak.