Terug naar het blog
Techniek Gepubliceerd op 27.08.2026 6 min. leestijd

De CAPTCHA is er – maar beschermt niets

Een zichtbare reCAPTCHA-, hCaptcha- of Turnstile-widget zegt weinig over de vraag of een formulier beschermd is. Dit zijn de typische configuratiefouten en zo controleert u uw eigen formulieren in een paar minuten.

Veel website-eigenaren voegen een CAPTCHA aan hun contactformulier toe, zien het badgeje of vinkje verschijnen en beschouwen het spamprobleem als opgelost. Daarna blijft de rommel binnenkomen. Vaak is de CAPTCHA zelf in orde – hij is alleen nergens op aangesloten dat een bot zou kunnen tegenhouden. Dit artikel loopt de typische manieren langs waarop reCAPTCHA, hCaptcha en Cloudflare Turnstile tot decoratie verworden, en laat zien hoe u uw eigen formulieren controleert.

Waar de bescherming echt plaatsvindt

Alle drie de diensten werken volgens hetzelfde principe. Een script in de browser voert zijn controles uit en geeft het formulier een token – een korte tekenreeks die zegt “deze bezoeker is geslaagd”. Het token reist met de formulierinzending mee naar uw server. Pas daar valt de echte beslissing: uw server stuurt het token samen met een geheime sleutel naar de aanbieder en krijgt een antwoord terug – geslaagd of mislukt, en bij reCAPTCHA v3 ook een score. Ontbreekt er een schakel in deze keten, dan ziet de widget er nog volkomen normaal uit, maar een bot die rechtstreeks naar uw formulierhandler post, gaat er zo doorheen.

De keten waarvan een CAPTCHA afhangt
1Script laadt
Het script van de aanbieder wordt geladen en mag op de formulierpagina draaien.
2Token uitgegeven
De browser ontvangt een kortlevend token dat maar één keer kan worden gebruikt.
3Token verzonden
Het token wordt samen met de formuliervelden naar de server gestuurd.
4Server verifieert
Uw server controleert het token bij de aanbieder met de geheime sleutel.
5Server beslist
De inzending wordt geweigerd tenzij het antwoord positief is (en bij v3 de score hoog genoeg is).
Bescherming bestaat alleen als elke stap werkt – en de beslissende stappen vinden op de server plaats, uit het zicht.

De testsleutel die alles doorlaat

Google, hCaptcha en Cloudflare publiceren speciale testsleutels, zodat ontwikkelaars geautomatiseerde tests kunnen draaien zonder puzzels op te lossen. Met het bijbehorende testgeheim slaagt de verificatie altijd – daar zijn ze juist voor. Ze zijn bedoeld voor lokale en stagingomgevingen, maar overleven regelmatig de overstap naar productie: een ontwikkelaar plakt ze tijdens de bouw in, de site gaat live en niemand vervangt ze. reCAPTCHA toont in de widget tenminste een melding dat hij alleen voor testdoeleinden is, maar bij een onzichtbare configuratie kijkt bijna niemand. Zijn zowel de test-sitesleutel als het testgeheim live, dan komt elke inzending erdoor, of die nu van een mens of van een bot komt; is alleen de sitesleutel een testsleutel, dan mislukt de verificatie juist en kunnen echte berichten worden geweigerd.

Een token dat niemand controleert

De tweede klassieker is een server die de aanbieder nooit raadpleegt. De widget draait, er wordt een token aangemaakt en verzonden, en daarna negeert de formulierhandler het gewoon. Typische bronnen zijn zelfgeschreven formulieren, gekopieerde codefragmenten die alleen de browserkant afdekken, en half afgemaakte pluginsinstellingen. Een naaste verwant: de server roept de verificatiedienst wel aan, maar controleert alleen of het verzoek is gelukt, niet wat het antwoord zegt. Of de scoredrempel voor reCAPTCHA v3 staat op 0, waardoor elke score die de dienst kan teruggeven wordt geaccepteerd. Sommige handlers “falen open”: ontbreekt het token of mislukt de verificatie, dan accepteren ze het bericht toch – en een bot laat het token gewoon weg.

Wanneer de widget nooit echt laadt

Andere configuratiefouten breken juist de browserkant. Is de sitesleutel niet voor het domein geregistreerd – typisch na een verhuizing van staging naar productie, een domeinwijziging of een nieuw subdomein – dan weigert de aanbieder tokens uit te geven en toont hij een fout in de widget of de browserconsole. Na een themawissel of een plug-inupdate kan de widgetmarkup nog in de pagina staan, terwijl het script dat hem tot leven brengt verdwenen is. Een cookietoestemmingstool kan hetzelfde effect hebben als hij het CAPTCHA-script blokkeert tot de bezoeker toestemming geeft. Wat er daarna gebeurt, hangt af van de server: eist die een geldig token, dan kunnen echte bezoekers geen berichten meer versturen en merkt niemand de verloren aanvragen op; doet hij dat niet, dan komen bots vrij door.

Twee andere gevallen worden makkelijk over het hoofd gezien. Bij reCAPTCHA v3 laat de badge in de hoek alleen zien dat het script ergens op de pagina is geladen – misschien door het thema of een andere plug-in – terwijl de integratie in de formulierplug-in zelf is uitgeschakeld. En cachingplug-ins kunnen een pagina opslaan samen met een in de HTML ingebed token. CAPTCHA-tokens zijn maar een paar minuten geldig en kunnen maar één keer worden geverifieerd, dus een gecachet token mislukt voor echte bezoekers; de verleidelijke “oplossing” om de controle uit te zetten, verwijdert de bescherming ongemerkt.

Schijn versus werkelijkheid
Wat u ziet
  • De widget toont een melding “alleen voor testdoeleinden”
  • De v3-badge staat in de hoek
  • De widget wordt weergegeven en levert een token
  • De spam is gestopt – maar de echte aanvragen ook
Wat er mogelijk aan de hand is
  • Er worden openbare testsleutels gebruikt en elke verificatie slaagt
  • De reCAPTCHA-integratie van de formulierplug-in is uitgeschakeld
  • De server stuurt het token nooit ter verificatie op, of negeert het resultaat
  • Sitesleutel niet voor het domein geregistreerd, of gecachete tokens verlopen

Een korte zelfcontrole

  1. 1Open de formulierpagina in een privévenster, open de ontwikkelaarstools van de browser en zoek in de console naar fouten van het CAPTCHA-script.
  2. 2Controleer of de widget daadwerkelijk verschijnt – één keer vóór en één keer na het accepteren van de cookiebanner – en of het formulier niet kan worden verzonden zolang hij ontbreekt.
  3. 3Controleer in de beheerconsole van de aanbieder of de sitesleutel uw livedomein vermeldt (inclusief varianten zoals www), en of de sleutels in uw formulierplug-in of code daarmee overeenkomen – geen sleutels uit documentatie of een stagingomgeving.
  4. 4Zorg er in de instellingen van de formulierplug-in voor dat de CAPTCHA-integratie voor dit specifieke formulier is ingeschakeld; controleer bij reCAPTCHA v3 of de scoredrempel boven 0 ligt.
  5. 5Hebt u toegang tot de code, zoek dan de verificatie aan de serverkant op en controleer of die de inzending weigert als het antwoord negatief is of het token ontbreekt.
  6. 6Sluit de formulierpagina uit van full-page caching, of zorg ervoor dat het token vers in de browser wordt aangemaakt.
  7. 7Verstuur een echt testbericht en controleer of het aankomt; herhaal de controle na wijzigingen aan het thema, de plug-ins of de toestemmingstool.
Wat een controle van buitenaf wel en niet kan zien
Testsleutels, widgetmarkup zonder script, consolefouten en geblokkeerde scripts zijn van buitenaf zichtbaar – een gratis controle op formexposed.com zoekt precies naar deze signalen zonder iets te verzenden. Of uw server het token echt verifieert, is niet in de pagina te zien; dat blijkt alleen uit uw servercode of uit een echte inzending.

Een CAPTCHA is één laag, niet de hele bescherming. In combinatie met een honeypotveld, een tijdcontrole en filtering aan de serverkant laat een configuratiefout op één plek het formulier niet wagenwijd openstaan. Wilt u snel zien hoe uw formulieren ervoor staan, voer dan uw domein in op formexposed.com – het rapport laat zien of de van buitenaf zichtbare onderdelen van uw CAPTCHA-configuratie in orde zijn.