De bot-detectie van TRACIO identificeert geautomatiseerde browsers, headless tools en scriptmatige aanvallen met behulp van een tweelaagse architectuur: verzameling aan de clientzijde in de browser-agent en analyse aan de serverzijde. Ze dekt gangbare automatiseringsframeworks, headless browsers, AI-browsingagents en antidetect-browsers met vrijwel nul false positives, en plaatst legitieme zoekmachine-crawlers automatisch op de allowlist.
De browser-agent voert een brede reeks controles uit en rapporteert de uitkomsten
daarvan. Op de server worden die uitkomsten gewogen tot een bot-score, en de score
wordt toegewezen aan een verdict. Een klein aantal ondubbelzinnige indicatoren is op
zichzelf doorslaggevend en dwingt een bot-verdict af, ongeacht de rest.
Welke controles draaien, hoe ze worden gewogen en waar de drempels liggen, wordt niet gepubliceerd — op geen enkel abonnement. Dat vastleggen zou bot-operators precies vertellen wat ze moeten aanpassen om langs de bescherming te komen. Wat u in plaats daarvan ontvangt, is het verdict, een bot-typelabel en — vanaf Business — reason codes die de klasse van de waarneming achter de beslissing benoemen.
Elke identificatie draagt een bot-verdict. Het bereikt u als bot.result in de
webhook-payload en als result.bot in de client-SDK.
| Resultaat | Beschrijving |
|---|---|
human | Geen automatiseringsindicatoren gevonden. Geverifieerde crawlers resulteren eveneens in human. |
bot | Automatisering of scriptmatige toegang gedetecteerd. Een bot.type-label vergezelt dit. |
uncertain | Gemengde of zwakke signalen — noch duidelijk menselijk, noch duidelijk geautomatiseerd. |
Dit wordt toegewezen aan het zakelijke veld decision.action (real, fake of
suspicious) dat overal in het dashboard en in de webhook-payload wordt gebruikt.
bot.score vergezelt het verdict. In webhook-payloadversie 2 is het een decimaal
getal van 0..100 — hetzelfde getal dat het dashboard voor dat bezoek toont. (In het
bevroren schema van versie 1 is het een breuk 0..1; zie
Webhooks.)
bot.type is aanwezig wanneer het resultaat bot is. Het is ofwel de naam van een
herkende bot of runtime, ofwel een familie, wanneer het benoemen van de
specifieke controle interne werking van de detector zou prijsgeven:
bot.type | Betekenis |
|---|---|
playwright, jsdom, electron | De genoemde automatiseringsruntime is geïdentificeerd |
browser_use, claude_computer_use, skyvern, genspark, fellou | De genoemde AI-browsingagent is geïdentificeerd |
automation | Automatiseringstooling, zonder de specifieke controle te benoemen |
headless | Een browser die zonder gebruikersinterface draait |
antidetect | Een antidetect-build of een build die de fingerprint vervalst |
extension | Een browserextensie die automatisering, proxying of VPN aanstuurt |
privacy_browser | Een privacygeharde browserbuild (bijvoorbeeld Mullvad Browser) |
other | Gedetecteerd, maar buiten het gepubliceerde vocabulaire |
De lijst is bewust gesloten: een controle die morgen aan de detector wordt toegevoegd,
verschijnt als other in plaats van haar interne naam te lekken. Behandel bot.type
als een label om op te vertakken, niet als een uitputtende enum om tegen te valideren
— er komen na verloop van tijd nieuwe benoemde runtimes bij.
Op de abonnementen Business en Enterprise bevat de webhook-payload een
reasons-array — maximaal acht items, gesorteerd op belang. Een code benoemt de
klasse van de waarneming, nooit de controle erachter:
| Code | Wat het betekent |
|---|---|
automation_signature | Sporen van automatiseringstooling |
headless_browser | Een browser zonder gebruikersinterface |
anonymous_browser | Een privacygeharde of antidetect-build die er alledaags uit moet zien |
privacy_hardening | Agressieve privacy-instellingen |
behavior_anomaly | Niet-menselijke interactiepatronen |
fingerprint_tampering | Waarden die met elkaar zouden moeten overeenkomen, doen dat niet |
environment_anomaly | De runtime-omgeving is intern inconsistent |
identity_mismatch | De opgegeven identiteit strookt niet met wat wordt waargenomen |
virtual_environment | Een emulator in plaats van fysieke hardware |
strong_automation_evidence | Ondubbelzinnige bot-indicatoren — op zichzelf doorslaggevend |
detection_signal | Overige controles die zijn afgegaan |
severity is high, medium of low, en het is het aandeel van het verdict dat
deze klasse bij dit bezoek voor haar rekening neemt — geen vaste eigenschap van de
code. Dezelfde code kan bij het ene bezoek als high binnenkomen en bij het andere
als low; cache hem dus niet als een constante.
privacy_hardening verdient bijzondere aandacht: hij gaat net zo goed af bij gewone
privacybewuste bezoekers als bij ontwijking. Weeg hem samen met de rest in plaats van
er alleen op te handelen.
virtual_environment komt uit de emulatordetectie. Op het web bestaat er geen apart
verdict “draait onder een hypervisor”: de aanwijzingen die een browser kan zien — een
generieke softwarerenderer, een ongewoon laag aantal cores — komen net zo vaak voor op
gewone machines zonder GPU-driver en in remotedesktopsessies, dus maken we er geen
verdict van waaraan u telkens zou moeten twijfelen.
| Mogelijkheid | Beschikbaarheid |
|---|---|
| Detectie van automatisering, headless en AI-agents | Alle abonnementen |
| Allowlist voor geverifieerde crawlers | Alle abonnementen |
| Emulatordetectie | Alle abonnementen |
Antidetect-indicatoren (bot.antidetectScore, 0..100) | Vanaf Pro |
| Reason codes, gedragsblok | Vanaf Business |
| DevTools-detectie | Vanaf Business |
De antidetect-scoring wordt nog gekalibreerd.
bot.antidetectScorewordt gerapporteerd zodat u hem kunt observeren en uw eigen beleid kunt bijstellen — behandel hem als invoer voor uw risicobeslissing en niet als op zichzelf staande reden om te blokkeren.
Controles die alleen voor mobiel gelden, zijn niet effectief op het web. Detectie van root, jailbreak, gekloonde/dual-apps en Frida is afhankelijk van native-mobielsignalen die een browser niet kan verzamelen. TRACIO levert uitsluitend browser-SDK's, dus vertrouw op de verdicts voor automatisering, headless, AI-agents, antidetect, emulator en gedrag, die op het web volledig actief zijn.
Bekende goede bots worden herkend aan hun user-agent en vervolgens geverifieerd tegen het verbindende IP-adres — een reverse-DNS-lookup op het IP-adres, een controle dat de resulterende hostname bij het domein van de operator hoort, en een forward lookup die bevestigt dat die weer naar hetzelfde IP-adres verwijst. Dit is de verificatieprocedure die de crawler-operators zelf publiceren.
| Crawler | Geverifieerde domeinen |
|---|---|
.googlebot.com, .google.com | |
| Bing | .search.msn.com |
| Apple | .applebot.apple.com |
| Yahoo | .crawl.yahoo.net |
| Yandex | .yandex.com, .yandex.net, .yandex.ru |
| DuckDuckGo | .duckduckgo.com |
Een geverifieerde crawler resulteert in human. Een verzoek dat beweert Googlebot te
zijn terwijl het IP-adres aantoonbaar aan iemand anders toebehoort, wordt als bot
geclassificeerd — een lookup die enkel ontbreekt of in een time-out loopt, geldt niet
als bewijs van vervalsing.
Interactiedynamiek — aanwijzerbeweging, toetsenbordcadans, scrollen — voedt het
verdict als bewijs van of er een mens aanwezig is, niet van welke mens het is.
Vanaf Business wordt het geaggregeerde resultaat geleverd in het behavior-blok van
de webhook:
{ "behavior": { "score": 87, "verdict": "human", "confidence": 0.92 }}score loopt van 0..100 (hoger = menselijker), verdict is human, uncertain of
bot, en confidence (0..1) geeft aan op hoeveel bewijs het verdict rust — een
kort bezoek met twee aanwijzerbewegingen scoort hier laag, zelfs wanneer het verdict
doorslaggevend lijkt.
Het blok is alleen aanwezig wanneer de gedragsscoring voor dat bezoek daadwerkelijk is uitgevoerd. Een ontbrekend blok betekent “geen data”, nooit “niets verdachts” — lees de afwezigheid ervan niet als een schoon signaal.
De client-SDK biedt een handige boolean, result.bot.detected, plus een confidence
op een schaal van 0..100:
const result = await tracio.getResult()
if (result.bot.detected) { console.warn(`Bot detected (confidence ${result.bot.confidence})`) showCaptcha() return}
await login(credentials)Handel op uw server naar de bezorging van de webhook. Het
bot-verdict bevindt zich in het object bot — bot.result en bot.type:
// `event` is the webhook delivery body (/docs/webhooks)app.post("/webhook/tracio", async (req, res) => { const event = req.body
if (event.bot?.result === "bot") { await db.blockedRequests.insert({ visitorId: event.visitorId, botType: event.bot.type, ip: event.ip, timestamp: new Date(), }) }
res.status(200).send("OK")})Nul- en lege waarden worden uit de payload weggelaten, dus lees bot.type defensief
in plaats van het in uw schema verplicht te stellen.
De bot-detectie van TRACIO is ontworpen op vrijwel nul false positives, maar randgevallen bestaan:
| Scenario | Risico | Mitigatie |
|---|---|---|
Browserextensies die navigator aanpassen | Laag | Kruisvalidatie over veel controles voorkomt dat één controle het verdict trekt |
| Zakelijke beveiligingssoftware | Zeer laag | Classificatie als headless vereist bevestigend bewijs |
| Toegankelijkheidshulpmiddelen | Geen | Accessibility-API's voeden de bot-detectie niet |
| VPN-/proxygebruikers | Geen | Netwerkvlaggen worden los van het bot-verdict bijgehouden |
Ziet u false positives, bekijk dan bot.type (en vanaf Business reasons) om te
begrijpen welke klasse van waarneming is afgegaan, en pas vervolgens uw beleid aan.
Zie Problemen oplossen voor de gebruikelijke oorzaken.