Elke ochtend staat er weer hetzelfde bericht in je inbox. “Ik ontvang graag meer informatie. Neem contact met mij op via e-mail.” Het komt steeds van een andere naam, met een ander mailadres en een ander telefoonnummer, en toch is het altijd diezelfde zin. Precies zo ging het bij een klant van mij met een contactformulier van Elementor, en misschien herken je het wel. Je opent elk bericht toch even, want er kan zomaar een echte aanvraag tussen zitten, en die wil je natuurlijk niet missen.
Hieronder lees je waar die berichten vandaan komen, waarom de gratis bescherming op de website van mijn klant ze niet tegenhield, en wat wel werkt, ook voor de formulierplugin die jij gebruikt.
Dit haal je uit dit artikel
- De meeste spam komt van bots, automatische programma’s die je formulier overslaan en hun bericht rechtstreeks bij je website afleveren, steeds vanaf een ander adres.
- Een onzichtbare val in je formulier houdt de simpelste bots tegen, bij mijn klant 483 keer in september, maar een slimmere bot loopt er gewoon omheen.
- Een onzichtbare controle die je website bij elk bericht nagaat, houdt ook die slimmere bots tegen, zonder dat je bezoeker een puzzel hoeft op te lossen.
- Ik gebruik zelf mijn eigen gratis antispam plugin, die alles op je eigen website controleert, zonder cookies.
- Per formulierplugin zie je wat er al in zit en wat je zelf toevoegt.
Waarom je contactformulier zoveel spam krijgt
De meeste spam via je contactformulier komt van bots die je pagina helemaal overslaan. Ze sturen hun bericht meteen naar het adres op je server dat het formulier verwerkt. Bij WordPress is dat vaak admin-ajax.php, een vast bestand dat op elke WordPress-website op dezelfde plek staat, en daar stuurt Elementor zijn formulieren ook naartoe. Omdat iedere bezoeker een formulier mag versturen, zit er bewust geen eenmalige beveiligingscode op (in WordPress heet zo’n code een nonce). Een bot hoeft je formulier dus maar één keer te bekijken, en daarna kan hij eindeloos kant-en-klare berichten sturen.
Bij mijn klant zag ik precies dat gebeuren in de serverlog, het logboek waarin de server elk verzoek aan de website bijhoudt. De verzoeken gingen direct naar admin-ajax.php, zonder dat er eerst een pagina werd opgevraagd, en ze kwamen van adressen van hostingbedrijven. De meeste van die adressen deden in de hele log maar één verzoek, en het volgende bericht kwam dan weer van een ander adres.
Je ziet het ook terug in de mail zelf. Elementor zet onder elk bericht het veld Page URL, met de pagina waarop het formulier is ingevuld. Die waarde komt uit een verborgen veld dat het script van het formulier toevoegt zodra iemand de pagina in een browser opent. Bij deze berichten ontbrak dat veld, en dat past bij een bot die de pagina en het script allebei overslaat.
- Naam
- Lotte Vermeer
- l.vermeer84@example.com
- Telefoon
- 06 12 34 56 78
- Bericht
- Ik ontvang graag meer informatie. Neem contact met mij op via e-mail.
- Page URL
- leeg
Hoe je de rest van je website tegen dit soort bots beschermt, lees je in mijn uitleg over je WordPress-website beveiligen. In dit artikel gaat het alleen over je formulieren.
Waarom snelle oplossingen tegen spam tegenvallen
Het is best verleidelijk om het formulier dan maar weg te halen, er een puzzel of rekensom aan toe te voegen of de afzenders te blokkeren op hun IP-adres, het internetadres waar een bericht vandaan komt. Dat voelt als een snelle oplossing, maar uiteindelijk kost het je meer dan het oplevert.
Haal je het formulier weg, dan raak je juist de mensen kwijt die je wilt spreken. Denk aan iemand die ‘s avonds nog een taart wil bestellen bij de bakker of een offerte wil vragen bij de hovenier, en geen zin heeft om de volgende ochtend te bellen.
Een puzzel of rekensom is vooral lastig voor je echte bezoekers. Op een telefoon is het al snel irritant en voor mensen met een visuele beperking soms zelfs onmogelijk, terwijl een bot zo’n eenvoudige rekensom gewoon oplost.
En IP-adressen blokkeren helpt weinig zolang de bot bij elk bericht van een ander adres komt, zoals je hierboven zag. Je loopt dan steeds achter de feiten aan, en met een beetje pech blokkeer je ook een echte klant.
Een honeypot als eerste stap
Een honeypot, Engels voor honingpot, is een verborgen veld in je formulier dat je bezoekers nooit te zien krijgen. Vult een bot dat veld verkeerd in of laat hij het weg, dan verraadt hij zich daarmee. Het is gratis en een prima eerste stap tegen de simpelste bots, maar zodra een bot doorheeft hoe die verborgen velden werken, komt hij er gewoon langs.
Een van de bekendste gratis honeypot-plugins voor WordPress is WP Armour, met meer dan 400.000 actieve installaties, en die stond ook op de website van mijn klant. Zodra iemand de pagina in een browser opent, zet een stukje JavaScript (de code die in je browser meedraait) twee verborgen velden in je formulier. Het ene heeft een vaste naam die uniek is voor jouw website, het andere moet leeg blijven. Je server keurt een bericht goed als het eerste veld er is en het tweede leeg is, dus een bot die geen JavaScript draait, mist die velden en valt meteen door de mand.
- Laadt de pagina met het formulier
- Het script zet de verborgen velden erin
- Verstuurt het bericht
- Slaat de pagina en het script over
- Stuurt een kant-en-klaar bericht
- Zet het verborgen veld er zelf bij
Dat werkte ook, want WP Armour hield bij mijn klant in september, tot en met de 25e, 483 spamberichten tegen. Maar tussen 6 en 24 september kwamen er ook zestien berichten met precies dezelfde tekst gewoon door. In de serverlog, die ik vanaf 14 september kon inzien, kwamen de berichten uit die periode van negen verschillende adressen van hostingbedrijven.
Hoe dat kan, zie je als je kijkt hoe WP Armour controleert. Wat er in het verborgen veld staat maakt niet uit, het gaat er alleen om dat het veld er is. De naam van dat veld ligt vast en staat in de broncode van elke pagina, gecodeerd in een script dat met één regel code te ontcijferen is. Zoekt een bot dat één keer uit, dan stuurt hij beide velden voortaan gewoon mee in zijn kant-en-klare verzoek, en komt hij zonder de pagina te laden en zonder JavaScript langs de honeypot. Wat er precies in die verzoeken stond, is niet in de log vastgelegd, maar dit past precies bij wat ik zag.
Een honeypot kijkt alleen of het verborgen veld er is, dus een bot die de naam van dat veld kent, stuurt het gewoon mee.
- 483keer tegengehouden door de honeypot
- 16spamberichten kwamen er toch doorheen
- 9wisselende adressen van hostingbedrijven
De honeypot die Elementor zelf meelevert, helpt tegen deze bot ook niet. Die weigert een bericht alleen als het verborgen veld is ingevuld, dus een bot die het veld weglaat, komt er gewoon door.
Dan is er nog de betaalde versie, WP Armour Extended, vanaf 19,99 dollar per jaar voor één website. Die voegt een logboek toe, blokkeert IP-adressen die herhaaldelijk spam sturen en heeft een filter op trefwoorden. Die blokkade heeft weinig zin als de bot steeds van adres wisselt, en het trefwoordfilter vangt deze zin alleen zolang de bot hem blijft gebruiken. Ik verwacht daarom dat Extended weinig doet tegen dit type bot, en dus heb je een tweede laag nodig.
Slimmere bots tegenhouden met ALTCHA, Turnstile of reCAPTCHA v3
Die tweede laag is een onzichtbare controle, en daarmee houd je ook de kant-en-klare berichten van slimmere bots tegen. Terwijl je bezoeker het formulier invult, draait er in de browser een korte controle die een token oplevert. Dat is een eenmalig bewijsje dat met het formulier wordt meegestuurd. Voordat het bericht doorgaat, legt je server dat token voor aan de aanbieder, of bij ALTCHA aan je eigen website. Met zo’n token-controle weet je server bij elk bericht of het formulier echt in een browser is ingevuld. Een bot die zijn bericht rechtstreeks naar admin-ajax.php stuurt, heeft geen geldig token en wordt dus geweigerd.
| ALTCHA | Cloudflare Turnstile | reCAPTCHA v3 | |
|---|---|---|---|
| Kosten | Gratis plan onder een eigen licentie, onzichtbare modus en volledige bescherming vanaf 18,90 euro per maand of 499 euro eenmalig | Gratis, zonder limiet op het aantal controles | Gratis tot 10.000 controles per maand per Google Cloud-organisatie, daarboven betaald |
| Waar de data heen gaat | Blijft in de standaardwerking op je eigen server, het bedrijf zit in Tsjechië | Naar Cloudflare, een Amerikaans bedrijf met opslag in de VS en de EER | Naar Google |
| Cookies | Geen tracking-cookies, in de normale stand geen cookies | Cloudflare noemt de gegevens die het verwerkt strikt noodzakelijk | Zet de cookie _GRECAPTCHA |
| Zichtbaar voor je bezoeker | Een vakje in het formulier, onzichtbaar met een betaald plan | Een klein vak waar je bezoeker zelden iets voor hoeft te doen | Een badge in de hoek, of een tekstregel bij je formulier |
| Zo installeer je hem | Zip-bestand van GitHub, handmatig uploaden | Gratis plugin of ingebouwd in je formulierplugin, met sleutels uit je Cloudflare-account | Ingebouwd in de meeste formulierplugins, met sleutels uit Google Cloud |
ALTCHA past het best als je de gegevens van je bezoekers het liefst op je eigen website houdt. De browser van je bezoeker doet dan een klein rekenklusje. Voor één bezoeker merk je daar niks van, maar voor een bot die duizenden berichten wil versturen loopt dat flink op. Massaspam wordt daardoor duur, al kan een enkel gericht bericht er nog steeds doorheen komen. Let wel op, want de oude plugin staat sinds 25 mei 2026 niet meer in de WordPress-pluginbibliotheek. De nieuwe versie haal je van GitHub. Er is een gratis plan, maar voor volledige bescherming van je formulierplugins moet je rekenen op een betaald plan.
Cloudflare Turnstile is voor de meeste websites de makkelijkste stap. De gratis plugin Simple CAPTCHA with Cloudflare Turnstile heeft meer dan 200.000 actieve installaties en werkt met alle formulierplugins in dit artikel. Kijk bij het instellen even naar de failsafe-stand, die bepaalt wat er gebeurt als Cloudflare niet bereikbaar is. Staat die op doorlaten, dan komen berichten in die tijd gewoon zonder controle binnen.
reCAPTCHA v3 geeft elke inzending een score tussen 0 en 1, waarbij 1 vrijwel zeker een mens is, en jij kiest zelf de drempel. Er zit wel een valkuil in die weinig mensen kennen. Het gratis tegoed van 10.000 controles per maand geldt voor al je websites samen binnen één Google Cloud-organisatie. Ga je daaroverheen zonder betaalgegevens, dan keurt Google elke controle goed met een hoge score, en laat je formulier stilletjes alles door. Dan is er nog hCaptcha, dat in een aantal formulierplugins zit en op een vergelijkbare manier werkt.
CleanTalk en Akismet controleren elk bericht op hun eigen servers
CleanTalk en Akismet zijn spamfilters in de cloud. Ze vergelijken elk bericht met een grote database van bekende spambronnen, en herkennen zo ook berichten die iemand met de hand invult. Daarvoor gaan de gegevens uit je formulier naar een bedrijf buiten Nederland.
CleanTalk kost ongeveer tien euro per jaar voor één website. Het is een Amerikaans bedrijf dat de gegevens standaard op servers in de VS en de EU zet. Je kunt dat omzetten naar alleen de EU, maar dan liggen je gegevens nog steeds bij een Amerikaans bedrijf. CleanTalk ontvangt het IP-adres, het mailadres, de tekst en de waarden van elk ingevuld veld, en bewaart die afhankelijk van je abonnement 7 of 45 dagen.
Akismet komt van Automattic, het bedrijf achter WordPress.com. Voor Europese gebruikers is een Iers bedrijf de contractpartij, en je gegevens kunnen ook buiten de EU worden verwerkt. Voor een bedrijfswebsite betaal je, bijvoorbeeld 9,95 euro per maand bij jaarlijkse betaling voor één website en 500 controles per maand.
Omdat de berichten van je bezoekers zo bij een bedrijf buiten Nederland terechtkomen, gebruik ik deze diensten zelf niet meer. Kies je er toch een van, zet de dienst dan in je privacyverklaring.
Wat je per formulierplugin instelt
Bijna elke formulierplugin heeft al iets tegen spam ingebouwd, dus het gaat er vooral om wat je er zelf nog bij zet.
Elementor Pro en PRO Elements
Elementor verstuurt formulieren via admin-ajax.php zonder die eenmalige beveiligingscode, en de ingebouwde honeypot houdt een bot zoals die van mijn klant niet tegen. reCAPTCHA v3 zit er wel in. Je vult de sleutels in onder Elementor, Instellingen, Integraties, en voegt daarna in elk formulier een reCAPTCHA v3-veld toe. Wil je Turnstile, dan gebruik je Simple CAPTCHA with Cloudflare Turnstile, die Elementor Pro-formulieren ondersteunt. Heb je de Akismet-plugin actief met een sleutel, dan zet je Akismet ook in de formulierinstellingen aan. Mijn eigen plugin SK Spamshield werkt direct met formulieren van Elementor Pro en PRO Elements, zonder account bij een ander bedrijf.
Contact Form 7
Contact Form 7 heeft geen eigen honeypot. Wel zitten er een quizvraag, een Akismet-koppeling, reCAPTCHA v3 en sinds versie 6.1 uit juni 2025 ook Turnstile in. SK Spamshield werkt ook direct met Contact Form 7. Wil je liever een dienst van buitenaf, kies dan bij voorkeur Turnstile, want het reCAPTCHA-script van Contact Form 7 laadt op elke pagina van je website, ook waar geen formulier staat.
Gravity Forms
Gravity Forms heeft bij Spam Detection in de formulierinstellingen een Advanced Honeypot en een Submission Speed Check die te snel verstuurde formulieren tegenhoudt. Turnstile, reCAPTCHA en Akismet voeg je toe met add-ons die bij elke licentie horen.
WPForms
WPForms heeft in de gratis versie al een moderne anti-spambescherming met een token en een honeypot. Daarnaast zet je hCaptcha, Turnstile, reCAPTCHA v3 of Akismet aan. Een filter op land of trefwoorden zit alleen in de betaalde versie.
Fluent Forms
In de gratis versie van Fluent Forms zitten een honeypot, reCAPTCHA, hCaptcha, Turnstile, Akismet en CleanTalk. De honeypot heeft een voorspelbare veldnaam, dus zet je er Turnstile bij.
En de spam in je reacties?
Reacties onder je berichten komen via een ander adres binnen dan je formulieren, en daar werkt een andere aanpak. Staan reacties bij jou aan, lees dan hoe je spam in je reacties tegenhoudt met gratis en betaalde opties.
Welke bescherming ik gebruik op de websites die ik beheer
Op de websites die ik beheer gebruik ik mijn eigen antispam plugin, SK Spamshield. Bij mijn klant zat het probleem in de naam van het verborgen veld. Die naam lag vast, dus de bot kon hem één keer uitzoeken en daarna gewoon blijven meesturen. In SK Spamshield is die naam bij elk bezoek anders, dus heeft een bot niks aan een naam die hij eerder heeft opgezocht.
- Laag 1Een veld dat steeds anders heetEen bot kan de naam niet één keer uitzoeken en blijven gebruiken
- Laag 2Een onzichtbare rekensomDe browser rekent op de achtergrond, een bot moet het voor elk bericht opnieuw doen
- Laag 3Een rem per IP-adresEen adres dat blijft proberen, kan een tijd lang geen formulieren versturen
De plugin controleert elk formulier in drie lagen. De eerste is dat verborgen veld met de wisselende naam, samen met een ondertekend tijdstempel. Daardoor valt een formulier dat verdacht snel is ingevuld of veel te lang heeft opengestaan meteen op. De tweede laag is een onzichtbare rekensom die de browser van je bezoeker op de achtergrond oplost. Die techniek, proof-of-work, komt van ALTCHA. Je bezoeker merkt er niks van, terwijl een bot die rekensom voor elk bericht opnieuw moet maken. Wil je liever iets zichtbaars, dan kies je voor een vinkje of een eenvoudige rekensom. En blijft een IP-adres het toch proberen, dan kan dat adres een tijd lang geen formulieren meer versturen.
Alles gebeurt op je eigen website. Er worden geen cookies gezet, er gaat niets naar een ander bedrijf en de plugin is gratis. Van een geweigerd bericht bewaart hij alleen het IP-adres, het tijdstip, het formulier en een ingekorte browsernaam, nooit de inhoud, en na 14 dagen is dat weg. Je begint in een testmodus, en in het logboek zie je bij elke weigering de reden. Voor je privacyverklaring staat er al een tekst klaar.
In de proef bij een klant van mij herkende hij in nog geen vijf dagen 190 spampogingen, allemaal van bots, en er is geen enkel echt bericht onterecht geweigerd.
SK Spamshield werkt met Elementor Pro, PRO Elements, Contact Form 7 en de reacties van WordPress zelf. Gebruik je Gravity Forms, WPForms of Fluent Forms, dan zet je Cloudflare Turnstile naast de bescherming die al in je formulierplugin zit.
Zo test je of je formulier beschermd is
Met deze controles weet je binnen een kwartier of je formulier beschermd is en of echte klanten er nog doorheen komen.
- Vul je eigen formulier in op je telefoon en kijk of het bericht binnenkomt.
- Open je formulier in een privévenster en kijk of het vak van Turnstile of ALTCHA, of de badge van reCAPTCHA, verschijnt.
- Loop al je formulieren na, ook die voor offertes, nieuwsbrieven en terugbelverzoeken, en zet de token-controle op elk formulier aan.
- Kijk onder een spambericht of het veld met de pagina-URL leeg is. Dan is het formulier vrijwel zeker niet door een bezoeker op je website ingevuld.
- Gebruik je Turnstile, controleer dan dat de failsafe-stand niet op doorlaten staat.
- Gebruik je reCAPTCHA op meerdere websites, kijk dan in Google Cloud hoeveel controles je per maand verbruikt.
- Zet de diensten die je gebruikt in je privacyverklaring.
- Houd een week bij hoeveel spam er nog binnenkomt, en zet de volgende laag aan als het blijft doorlopen.
Heb je een ontwikkelaar bij de hand, laat dan een verzoek zonder token rechtstreeks naar het formulier sturen. Wordt dat geweigerd, dan werkt de controle op de server zoals het hoort.
Wil je dat ik dit voor je regel? Dan kun je de spambescherming laten inrichten als onderdeel van mijn WordPress-onderhoud. Ik richt de bescherming in op al je formulieren, met SK Spamshield waar dat kan, test of echte aanvragen gewoon binnenkomen en houd daarna in de gaten of er nog spam doorkomt.
Veelgestelde vragen
Geen enkele controle houdt alle spam tegen, ook reCAPTCHA niet. reCAPTCHA v3 geeft elke inzending een score en stopt vooral de geautomatiseerde berichten, terwijl iemand die het formulier met de hand invult er gewoon doorkomt. Let ook op het gratis tegoed van 10.000 controles per maand, dat geldt voor al je websites samen binnen één Google Cloud-organisatie. Zit je daarboven zonder betaalgegevens, dan laat de controle stilletjes alles door.
Tussen die twee kies ik Cloudflare Turnstile. Die is gratis zonder limiet op het aantal controles, een bezoeker hoeft er zelden iets voor te doen en de gratis plugin Simple CAPTCHA with Cloudflare Turnstile werkt met de bekende formulierplugins. reCAPTCHA v3 zit al ingebouwd in Elementor Pro en Contact Form 7, maar zet een cookie en heeft een gratis grens van 10.000 controles per maand. Zelf gebruik ik op websites met Elementor Pro of Contact Form 7 mijn eigen plugin SK Spamshield, die geen gegevens naar een ander bedrijf stuurt.
Ja, dat kan. Mijn eigen gratis plugin SK Spamshield werkt standaard zonder dat je bezoeker iets hoeft te doen. Hij gebruikt een verborgen veld waarvan de naam bij elk bezoek anders is en een rekensom die de browser van je bezoeker op de achtergrond oplost. Cloudflare Turnstile doet zijn controle ook grotendeels op de achtergrond. Een gewone honeypot alleen houdt de simpelste bots tegen, maar een bot die de verborgen velden meestuurt komt erlangs, dus combineer hem met een controle die je server zelf naloopt.
Meestal heeft een bot je formulier gevonden en stuurt die kant-en-klare berichten rechtstreeks naar het adres op je server dat het formulier verwerkt, vanaf steeds een ander IP-adres. Zolang die berichten doorkomen, kost het de bot niets om door te gaan. Een token-controle die je server bij elk bericht nagaat, zoals Cloudflare Turnstile, houdt dat soort verzoeken tegen.
Ja, als eerste laag werkt een honeypot prima. Bij een klant van mij hield WP Armour in september, tot en met de 25e, 483 spamberichten tegen. In dezelfde weken kwamen er toch zestien berichten door van een bot die de verborgen velden gewoon meestuurde, Dat kon omdat de naam van het verborgen veld vastlag. Bij een honeypot waarvan de naam bij elk bezoek anders is, zoals in SK Spamshield, kan een bot die naam niet één keer uitzoeken en daarna blijven gebruiken.
reCAPTCHA stuurt gegevens van je bezoeker naar Google en zet de cookie _GRECAPTCHA, dus vermeld het in je privacyverklaring. Verberg je de badge, dan vraagt Google een zichtbare vermelding bij je formulier met een link naar hun privacybeleid en voorwaarden. Wil je alles op je eigen website houden, dan gebruik je SK Spamshield. Die zet geen cookies en stuurt geen gegevens naar een ander bedrijf.
Nee, een SMTP-plugin zorgt ervoor dat de mails van je website betrouwbaar in je inbox aankomen, en dat geldt ook voor de spam. Tegen spam heb je een controle nodig die een bericht tegenhoudt voordat het verstuurd wordt, zoals een honeypot of een token-controle.