Honeypots Werken Nog Steeds: 3 Manieren om Spam-aanmeldingen te Stoppen Zonder CAPTCHAs
Vorige week viel me iets verdachts op in mijn SEO Friend wachtlijst-aanmeldingen. Tientallen e-mailadressen van wegwerp-domeinen, allemaal ingediend binnen milliseconden van elkaar, afkomstig van IP-adressen in Rusland en Nederland. Klassiek botfarm-gedrag.
De voor de hand liggende oplossing? Plak een CAPTCHA op het formulier. Maar CAPTCHAs zijn irritant. Ze frustreren echte gebruikers, schaden conversieratio's en eerlijk gezegd—moderne bots worden behoorlijk goed in het oplossen ervan. Ik wilde iets dat onzichtbaar is voor mensen maar dodelijk voor bots.
Maak kennis met de honeypot.
Wat is een Honeypot?
Een honeypot is een val ontworpen om geautomatiseerde systemen te vangen door hun voorspelbare gedrag uit te buiten. In webbeveiliging werkt een formulier-honeypot op een eenvoudig principe: bots vullen automatisch elk formulierveld dat ze vinden in, terwijl mensen alleen de velden invullen die ze kunnen zien.
Als je een verborgen veld toevoegt dat mensen niet kunnen zien, en dat veld wordt ingevuld—heb je een bot gevangen.
Het is een oude techniek, maar het werkt nog steeds opmerkelijk goed in 2025. Gecombineerd met timingcontroles kun je de overgrote meerderheid van spam-aanmeldingen stoppen zonder enige gebruikersfrictie.
Het Probleem: Botfarm-aanmeldingen
Voordat ik mijn honeypot implementeerde, had ik dit te maken. IP's van datacenters in Rusland, Nederland en Duitsland raakten mijn wachtlijstformulier. De inzendingen kwamen binnen op onmenselijke snelheid—0,2 tot 0,5 seconden nadat de pagina laadde. De e-mailadressen waren allemaal van wegwerp-domeinen zoals tempmail en guerrillamail. En ze vulden elk formulierveld in dat ze konden vinden, wat hun ondergang zou worden.
Waarom doen bots dit? Ze oogsten e-mailsystemen—formulieren indienen om te zien of bevestigingsmails terugstuiteren, valideren dat je e-mailpijplijn werkt. Ze vervuilen databases met rommeldata om je tijd en e-mailquota te verspillen. Ze testen e-mailadressen voor credential stuffing-aanvallen later. Soms is het concurrent-sabotage—je metrics opblazen met afvaldata zodat je je cijfers niet kunt vertrouwen.
De bots kwamen van dezelfde /24 IP-blokken, dienden in binnen fracties van seconden en gebruikten duidelijke wegwerp-e-mails. Perfecte kandidaten voor honeypot-detectie.
Voorbeeld 1: De Verborgen Veldval
Dit is de klassieke honeypot-techniek die bots stopt sinds de vroege jaren 2000. Het concept is prachtig eenvoudig: voeg een formulierveld toe dat onzichtbaar is voor mensen maar zichtbaar voor bots. Wanneer een bot elk veld op de pagina automatisch invult (wat ze altijd doen), vullen ze ook je verborgen veld in—en je hebt ze gevangen.
Hier is de HTML die je aan je formulier toevoegt, direct naast je echte e-mailinvoer:
<form id="waitlist-form" action="/api/signup" method="POST">
<!-- Het echte veld dat mensen invullen -->
<label for="email">E-mailadres</label>
<input type="email" id="email" name="email" required>
<!-- Het honeypot-veld - volledig onzichtbaar voor mensen -->
<input
type="text"
name="website"
style="position:absolute;left:-9999px"
tabindex="-1"
autocomplete="off"
aria-hidden="true"
>
<button type="submit">Aanmelden voor Wachtlijst</button>
</form>Elk attribuut op dat honeypot-veld dient een specifiek doel. De type="text" laat het eruitzien als een normaal tekstveld voor elke bot die je HTML parset. De name="website" is opzettelijk onopvallend—bots zijn geprogrammeerd om veelvoorkomende velden in te vullen zoals "website", "url", "company" en "phone", dus het gebruiken van een van deze namen zorgt ervoor dat ze het aas nemen. Vermijd voor de hand liggende namen zoals "honeypot" of "trap" omdat sommige geavanceerde bots naar die patronen zoeken.
De style="position:absolute;left:-9999px" is de sleutel tot onzichtbaarheid. Door het element 9999 pixels buiten de linkerkant van het scherm te positioneren, zal geen mens het ooit zien, maar bots die de DOM parsen vinden het prima. De tabindex="-1" voorkomt dat toetsenbordgebruikers per ongeluk in het veld tabben tijdens het navigeren door je formulier. De autocomplete="off" stopt browser-autofill om het aan te raken—je wilt niet dat Chrome behulpzaam je honeypot invult met de opgeslagen gegevens van een legitieme gebruiker. Ten slotte vertelt aria-hidden="true" schermlezers om dit veld volledig te negeren, waardoor toegankelijkheid voor visueel gehandicapte gebruikers behouden blijft.
Aan de serverzijde is de controle triviaal. Als het website-veld enige waarde bevat, heb je een bot gevangen:
app.post('/api/signup', async (c) => {
const { email, website } = await c.req.parseBody();
// Als het honeypot-veld enige waarde heeft, heeft een bot het ingevuld
if (website) {
console.log('Bot gedetecteerd via honeypot:', email);
// Retourneer nep succes - de bot denkt dat het werkte
return c.json({
success: true,
message: 'Bedankt voor je aanmelding!'
});
}
// Echte mens - verwerk normaal
await saveToDatabase(email);
return c.json({ success: true, message: 'Welkom!' });
});Het kritieke detail hier: retourneer een nep-succesrespons in plaats van een fout. Als je een foutbericht retourneert, kunnen geavanceerde bots detecteren dat ze gepakt zijn en andere benaderingen proberen—misschien velden overslaan, misschien een ander IP gebruiken. Door succes te retourneren, ziet de operator van de bot groene vinkjes in hun logs en gaat verder naar makkelijkere doelwitten. Je database blijft schoon en ze weten nooit wat ze raakte.
Voorbeeld 2: De Timingcontrole
Mensen hebben tijd nodig om een pagina te lezen en een formulier in te vullen. Zelfs de snelste typer heeft meerdere seconden nodig om het formulier te scannen, in het e-mailveld te klikken, hun adres te typen en op verzenden te drukken. Een echt persoon kan simpelweg geen pagina laden en een formulier indienen in 300 milliseconden.
Bots kunnen dat wel. En dat doen ze, constant.
Deze honeypot-techniek meet de tijd tussen paginalading en formulierinzending. Alles onder de 3 seconden is bijna zeker geautomatiseerd.
Voeg eerst een verborgen veld toe aan je formulier dat de laadtijdstempel opslaat:
<form id="waitlist-form" action="/api/signup" method="POST">
<label for="email">E-mailadres</label>
<input type="email" id="email" name="email" required>
<!-- Timingcontroleveld - legt vast wanneer de pagina laadde -->
<input type="hidden" name="loadedAt" id="loadedAtField">
<button type="submit">Aanmelden voor Wachtlijst</button>
</form>
<script>
// Zodra de pagina laadt, leg de tijdstempel vast
document.getElementById('loadedAtField').value = Date.now();
</script>Wanneer de pagina laadt, stelt JavaScript onmiddellijk de waarde van het verborgen veld in op de huidige Unix-tijdstempel in milliseconden. Deze waarde wordt ingediend samen met de rest van de formuliergegevens. De gebruiker ziet het nooit, interacteert er nooit mee—het is volledig onzichtbaar.
Op de server vergelijk je de inzendtijd met de laadtijd:
app.post('/api/signup', async (c) => {
const { email, loadedAt } = await c.req.parseBody();
// Bereken hoe lang de gebruiker erover deed om in te dienen
if (loadedAt) {
const elapsed = Date.now() - parseInt(loadedAt, 10);
// Minder dan 3 seconden? Geen mens typt zo snel.
if (elapsed < 3000) {
console.log(`Bot gedetecteerd: ingediend in ${elapsed}ms`);
// Retourneer rate limit-fout - iets geloofwaardiger
return c.json({
error: 'Wacht even voordat je indient.'
}, 429);
}
}
// Deed er redelijk lang over - waarschijnlijk mens
await saveToDatabase(email);
return c.json({ success: true, message: 'Welkom!' });
});Ik gebruik 3 seconden (3000 milliseconden) als drempel. In tests ontdekte ik dat zelfs snelle gebruikers met autofill ingeschakeld minstens 4-5 seconden nodig hebben om in te dienen. De langzaamste bots die ik ving waren rond de 800 milliseconden. Drie seconden geeft comfortabele marge voor beide.
Voorbeeld 3: Het Complete Tweedelige Systeem
In de praktijk wil je beide technieken samenwerken. Het verborgen veld vangt bots die formulieren automatisch invullen. De timingcontrole vangt bots die proberen slim te zijn en verborgen velden overslaan. Samen vormen ze een bijna ondoordringbare barrière tegen geautomatiseerde inzendingen.
Resultaten
Na het implementeren van dit tweedelige honeypot-systeem daalde spam-aanmeldingen van 20-50 per dag naar vrijwel nul. De bots proberen het nog steeds—ik zie ze in mijn serverlogs—maar ze worden allemaal gevangen en krijgen nep-succesresponsen. Ze denken dat ze winnen. Mijn database blijft schoon.
Echte gebruikers hebben niets gemerkt. Er is geen CAPTCHA om op te lossen, geen frictie toegevoegd aan de aanmeldflow. Ze vullen hun e-mail in, klikken op verzenden en ze zijn klaar. De honeypot-controles gebeuren onzichtbaar op de achtergrond.
De implementatie duurde ongeveer 30 minuten—het meeste daarvan was het opzetten van logging zodat ik kon monitoren wat werd geblokkeerd. Er is geen lopend onderhoud, geen maandelijkse kosten voor anti-spamservices, geen API-sleutels om te beheren.
Soms zijn de eenvoudigste oplossingen de beste. Honeypots bestaan al decennia omdat ze werken. In een tijdperk van steeds geavanceerdere AI en machine learning, is er iets bevredigends aan het stoppen van bots met een verborgen tekstveld en een tijdstempel.
Veelgestelde Vragen
Werken honeypots tegen alle bots?
Nee. Geavanceerde bots die specifiek zijn ontworpen om honeypots te omzeilen, kunnen verborgen velden overslaan of kunstmatige vertragingen toevoegen. Echter, deze zijn zeldzaam. De overgrote meerderheid van bots zijn eenvoudige scrapers die alles automatisch invullen en direct indienen. Honeypots vangen 95%+ van geautomatiseerde spam, wat meestal genoeg is om je spamprobleem beheersbaar te maken.
Breekt dit de toegankelijkheid?
Niet als het correct is geïmplementeerd. Het aria-hidden="true" attribuut vertelt schermlezers om het honeypot-veld volledig te negeren, zodat visueel gehandicapte gebruikers niet verward raken door een veld waarmee ze niet kunnen interacteren. De tabindex="-1" voorkomt dat toetsenbordgebruikers erin tabben. Gebruikers die navigeren met ondersteunende technologie ervaren het formulier precies zoals bedoeld.
Wat als een legitieme gebruiker op de een of andere manier de honeypot invult?
Dit is bijna onmogelijk met correcte implementatie. Het veld is 9999 pixels buiten de linkerkant van het scherm gepositioneerd—gebruikers kunnen het letterlijk niet zien of erin klikken. Browser-autofill is uitgeschakeld met autocomplete="off". In twee weken productiegebruik met duizenden bezoekers heb ik nul false positives gehad.
Moet ik in plaats daarvan CAPTCHA gebruiken?
CAPTCHAs voegen frictie toe. Studies tonen aan dat ze conversieratio's met 3-8% kunnen verminderen. Gebruikers haten ze—ik haat ze. Honeypots zijn onzichtbaar; gebruikers weten niet eens dat ze bestaan. Begin met honeypots. Voeg alleen CAPTCHAs toe als je nog steeds significante spam krijgt na het implementeren van juiste honeypot-bescherming, wat onwaarschijnlijk is voor de meeste sites.
Fred
AUTHORFull-stack developer with 10+ years building production applications. I've built frontends that users actually enjoy using (and that don't break in IE).
Need a developer who gets it?
POC builds, vibe-coded fixes, and real engineering. Let's talk.
Hire Me →
