Een registratieformulier is het goedkoopste doelwit op internet. Er valt geen wachtwoord te raden en geen kaart te stelen, en elk account dat het oplevert is voor iemand iets waard: een gratis trial om door te verkopen, een verwijzingsbonus om te farmen, een inbox voor spam of een slapend account voor latere fraude. Is je aantal registraties van de ene op de andere dag gestegen en je activatiepercentage gedaald, dan vult er waarschijnlijk een script het formulier in.
Wat nepregistraties je kosten
- Geld: gratis credits, trial-compute, kosten voor sms- en e-mailverificatie, uitbetalingen voor verwijzingen.
- Data: een funnel vol accounts die nooit converteren, verbergt wat echte klanten doen.
- Reputatie: verificatiemails naar verzonnen of gestolen adressen bouncen en schaden je sender score.
- Later misbruik: accounts die vandaag worden aangemaakt, worden volgende maand gebruikt voor spam, scraping of kaarttesten.
Waarom een CAPTCHA niet het antwoord is
Diensten die CAPTCHA's oplossen, beantwoorden puzzels voor ver onder een cent per stuk, met mensen of modellen, dus een vastberaden aanvaller betaalt een beetje en loopt zo door. Je echte bezoekers betalen de volle prijs: elke puzzel kost je een deel van hen, op telefoons nog meer. Een CAPTCHA legt de kosten bij de verkeerde kant.
Wat een gescripte registratie verraadt
Geen enkel signaal is op zichzelf bewijs, en alles wat een aanvaller in de hand heeft, zoals de User-Agent, is te vervalsen. Wat scripts moeilijk vinden, is consistent zijn over veel signalen tegelijk, en zich na verloop van tijd als een mens gedragen.
- Automatiseringsvlaggen. Headless en aangestuurde browsers lekken nog steeds:
navigator.webdriver, een software-GPU, ontbrekende browserfuncties. - Inconsistenties. Een User-Agent die Windows claimt op een browser die Linux meldt, een tijdzone die niet bij het netwerk past, client hints die de headers tegenspreken.
- Het netwerk. Registraties vanaf hostingproviders in plaats van thuisverbindingen en telefoons. Op zichzelf is dit zwak bewijs: VPN-gebruikers zijn ook echte mensen.
- Fan-out. Eén apparaat, één token of één subnet dat binnen minuten veel accounts aanmaakt.
- Geen pagina. Een request naar het registratie-endpoint van een client die de registratiepagina nooit heeft geladen.
Beslis op de server, voordat het account bestaat
De beslissing hoort waar het account wordt aangemaakt, niet in de browser waar een script haar kan overslaan. Vraag, voordat je de gebruiker opslaat, om een beslissing over de request, met een korte timeout:
POST /v1/decide
{ "ip": "203.0.113.10", "user_agent": "Mozilla/5.0 …",
"token": "<_kz cookie>", "path": "/signup" }
Handel daarna op de klasse die je terugkrijgt, van de zekerste naar de minst zekere:
- bot high: weiger de registratie.
- bot: maak het account aan maar houd de trial-credits vast tot het e-mailadres is geverifieerd, of vraag om een telefoonnummer.
- unknown, human, human high: laat het zoals gewoonlijk door.
De beloning achterhouden, in plaats van het formulier te blokkeren, is wat nepregistraties de moeite niet meer waard maakt, zonder een echte klant weg te sturen wiens enige fout een VPN was.
Fail open
Als de check traag of down is, laat de registratie dan door. Een paar nepaccounts tijdens een storing kosten veel minder dan een registratiepagina die niet meer werkt. We schreven hier meer over in waarom een botcheck fail-open moet zijn.