Sistemul de detectare a boților din TRACIO identifică browsere automatizate, instrumente headless și atacuri scriptate folosind o arhitectură pe două straturi: colectarea semnalelor pe partea de client și analiza pe partea de server. Detectează framework-uri de automatizare uzuale, browsere headless, agenți AI de navigare și browsere antidetect cu falsuri pozitive aproape de zero, punând automat pe lista de permisiuni crawlerele legitime ale motoarelor de căutare.
Agentul de browser colectează o serie de semnale specifice boților și de validare încrucișată, care alimentează deciziile de pe partea de server. ID-urile de semnal de mai jos sunt ilustrative — ID-urile interne nu constituie un contract public stabil:
| Semnal | Descriere |
|---|---|
s300 (webdriver) | Flagul navigator.webdriver — setat la true de framework-urile de automatizare |
s301 (eval length) | eval.toString().length — Chrome/Edge: 33, Firefox: 37. Alte valori indică instrumentare. |
s305 (bot composite) | Scanează window/document pentru 14 artefacte de framework-uri de automatizare |
s97 (headless markers) | Artefacte CDP, permisiuni de notificare, numărul de pluginuri, dimensiuni exterioare |
s157 (automation scan) | Scanare cuprinzătoare pentru Selenium, Puppeteer, PhantomJS, Playwright și încă 10 |
s158 (iframe webdriver) | Creează un iframe ascuns și citește navigator.webdriver în interiorul lui. Prinde instrumentele care corectează cadrul principal, dar uită de iframe-uri. |
s159 (native function) | Șterge Function și Object și testează dacă getterele sunt cu adevărat native. Detectează instrumentarea bazată pe Proxy. |
s155 (window CRC32) | Scanare cu hash CRC32 a fiecărei proprietăți window pentru a detecta globalele de automatizare injectate |
s163 (devtools trap) | Capcană cu getter în consolă — detectează când DevTools sunt deschise activ |
Serverul rulează un set de detectoare ale căror ieșiri ponderate se combină
într-un scor de bot. Scorul este mapat la un verdict prin praguri — bot când
este ≥ 0,70, suspicious când ≥ 0,30, altfel human — iar un semnal de eșec
categoric (precum navigator.webdriver) forțează direct un verdict bot.
Verdictele de bot poartă o etichetă bot_type în format liber.
Detectoare reprezentative și efectul lor:
| Detector | Efect |
|---|---|
| Flagul webdriver | Eșec categoric → bot (tip webdriver) |
| Scanare compozită de automatizare / framework | Pondere mare → bot (tip {framework}) |
| Markeri headless | Ponderat → bot (tip headless) |
| Anomalie de lungime eval | Ponderat → bot (tip unknown) |
| Tipar UA de bot rău-intenționat | Ponderat → bot (tip {label}) |
| Bot bun verificat (reverse DNS) | Listă de permisiuni → human |
| Comportamental (rată / entropie / interacțiune) | Ponderat → bot (tip rateBot) |
| VM (Enterprise) · Emulator · DevTools (Business+) | Semnale ponderate de dispozitiv/manipulare |
Nivel și disponibilitate. Detectarea DevTools rulează pe Business și Enterprise; detectarea VM este Enterprise; detectarea de emulator rulează pe toate planurile. Toate acestea funcționează în agentul web. Detectarea de root, jailbreak, aplicații clonate/duale, Frida și resetare din fabrică depinde de semnale native de mobil și nu este eficientă în implementarea exclusiv web (în dezvoltare). Bazați-vă pe verdictele de automatizare, headless, agenți AI, antidetect, VM/emulator și comportamentale, care sunt pe deplin active pe web.
Detectarea boților scrie un câmp bot_result la fiecare eveniment (și bot.result în
payload-ul webhook-ului).
bot_result este una dintre trei valori canonice:
| Rezultat | Descriere |
|---|---|
human | Niciun indicator de automatizare găsit. Crawlerele verificate ale motoarelor de căutare se rezolvă tot la human. |
bot | Acces automatizat sau scriptat detectat. Îl însoțește o etichetă bot_type în format liber. |
uncertain | Semnale mixte sau slabe — nici clar uman, nici clar automatizat. |
Aceasta se mapează la câmpul de business decision (real, fake sau suspicious)
folosit în tot dashboard-ul, precum și la bot.result din
payload-ul webhook-ului.
"bot")bot_type este un șir în format liber. Valorile de mai jos sunt exemple ilustrative
ale a ceea ce emit detectoarele, nu un enum exhaustiv:
| Tip | Metodă de detectare |
|---|---|
webdriver | navigator.webdriver este true |
selenium | Proprietăți window/document specifice Selenium detectate |
puppeteer | Indicatori headless Puppeteer/Chromium corespunzători |
playwright | Markeri specifici Playwright sau șir UA detectat |
headless | 2+ din 11 markeri headless declanșați |
phantomjs | Globale PhantomJS detectate (callPhantom, _phantom) |
nightmare | Globale NightmareJS detectate |
unknown | Anomalie de lungime eval sau alți indicatori de automatizare nespecifici |
rateBot | Analiza comportamentală a ratei a depășit pragurile |
Cea mai directă detectare. Toate framework-urile majore de automatizare setează navigator.webdriver = true conform specificației WebDriver. Acest lucru este verificat atât în cadrul principal (s300), cât și într-un iframe ascuns (s158) pentru a prinde instrumentele care corectează doar cadrul principal.
Scanare cuprinzătoare a proprietăților window și document pentru artefacte specifice framework-urilor:
| Framework | Proprietăți detectate |
|---|---|
| Selenium | _Selenium_IDE_Recorder, _selenium, calledSelenium, __selenium_evaluate, $cdc_* (ChromeDriver) |
| Puppeteer | domAutomation, domAutomationController, HeadlessChrome UA |
| Playwright | __playwright, flagul automation-controlled |
| PhantomJS | callPhantom, _phantom |
| NightmareJS | __nightmare, nightmare |
| CefSharp | CefSharp |
| Awesomium | awesomium |
| WebDriverIO | wdioElectron |
| Cypress | proprietatea __cypress de pe window |
Scanarea folosește și un tipar regex /^([a-z]){3}_.*_(Array|Promise|Symbol)$/ pentru a detecta globalele auxiliare injectate de Selenium.
Se evaluează 11 markeri, cu un prag de 2 sau mai mulți pentru clasificare:
| Marker | Semnal | Condiție |
|---|---|---|
| webdriver | s300 | = "true" |
| vendor flavors lipsă | s28 | Niciun obiect chrome/safari pe window |
| CDP headless chrome | s305 | headlessChrome = true |
| notification denied | s88 | Notification.permission = "denied" la prima vizită |
| chrome no runtime | s89 | window.chrome există, dar chrome.runtime lipsește |
| o singură limbă | s90 | navigator.languages.length <= 1 |
| ecran implicit 800x600 | s5 | Rezoluția implicită a Headless Chrome |
| HeadlessChrome UA | UA | User-Agent conține "HeadlessChrome" |
| dimensiuni exterioare zero | s97 | outerWidth = 0 și outerHeight = 0 |
| WebGL SwiftShader | s70 | Renderer-ul conține "swiftshader" (GPU software) |
| WebGL llvmpipe | s70 | Renderer-ul conține "llvmpipe" (GPU software) |
Boții buni cunoscuți sunt recunoscuți după tiparul User-Agent. Fiecare este verificat prin reverse DNS pentru a preveni falsificarea:
.googlebot.com)| Bot | Domenii permise |
|---|---|
.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 |
Dacă o cerere pretinde că este Googlebot, dar reverse DNS-ul IP-ului său se rezolvă la un domeniu străin (o nepotrivire PTR confirmată, nu doar o căutare lipsă/expirată), este clasificată ca bot (tip spoofed:google).
Detectare bazată pe rată cu scor de entropie:
| Rată (req/min) | Prag de entropie | Acțiune |
|---|---|---|
| 120+ | < 0.1 | bot (tip: rateBot) |
| 60-120 | < 0.3 | bot (tip: rateBot) |
| 45-60 | < 0.1 | bot (tip: rateBot) |
| < 45 | Oricare | Normal |
Regulă suplimentară: Absența evenimentelor de mouse/tastatură după 30+ secunde de vechime a sesiunii clasifică vizita drept bot cu tipul noInteraction.
eval.toString().length produce valori consistente per motor:
Orice altă valoare indică faptul că funcția eval a fost interceptată de un framework de automatizare, clasificând vizita drept bot cu tipul unknown.
SDK-ul de client expune un boolean practic, result.bot.detected:
const result = await tracio.getResult()
if (result.bot.detected) { // Log and block console.warn(`Bot detected (confidence ${result.bot.confidence})`) showCaptcha() return}
// Proceed with loginawait login(credentials)Pe serverul dvs., acționați asupra livrării prin webhook. Detectarea boților
se află în obiectul bot — bot.result și 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")})Detectarea boților din TRACIO este concepută pentru falsuri pozitive aproape de zero. Cu toate acestea, pot apărea cazuri limită:
| Scenariu | Risc | Atenuare |
|---|---|---|
Extensii de browser care modifică navigator | Scăzut | Validarea încrucișată a mai multor semnale previne declanșarea de un singur semnal |
| Software corporativ de securitate | Foarte scăzut | Detectarea headless necesită 2+ markeri |
| Instrumente de accesibilitate | Niciunul | API-urile de accesibilitate nu declanșează niciun semnal de detectare |
| Utilizatori de VPN/proxy | Niciunul | Utilizarea VPN este urmărită separat de detectarea boților |
Dacă întâmpinați falsuri pozitive, examinați câmpul bot.type pentru a înțelege ce detector a fost declanșat și ajustați-vă politica în consecință.