Система виявлення ботів TRACIO ідентифікує автоматизовані браузери, headless-інструменти та скриптовані атаки за допомогою дворівневої архітектури: збір сигналів на боці клієнта та аналіз на боці сервера. Вона виявляє поширені фреймворки автоматизації, headless-браузери, ШІ-агентів для веб-серфінгу та antidetect-браузери з майже нульовою кількістю хибних спрацювань, автоматично додаючи легітимні кроулери пошукових систем до allowlist.
Браузерний агент збирає низку специфічних для ботів та крос-валідаційних сигналів, які живлять рішення на боці сервера. Наведені нижче ID сигналів є ілюстративними — внутрішні ID не є стабільним публічним контрактом:
| Сигнал | Опис |
|---|---|
s300 (webdriver) | Прапорець navigator.webdriver — встановлюється у true фреймворками автоматизації |
s301 (eval length) | eval.toString().length — Chrome/Edge: 33, Firefox: 37. Інші значення вказують на інструментування. |
s305 (bot composite) | Сканує window/document на 14 артефактів фреймворків автоматизації |
s97 (headless markers) | CDP-артефакти, дозволи на сповіщення, кількість плагінів, зовнішні розміри |
s157 (automation scan) | Комплексне сканування на Selenium, Puppeteer, PhantomJS, Playwright та ще 10 |
s158 (iframe webdriver) | Створює прихований iframe і читає в ньому navigator.webdriver. Виявляє інструменти, що патчать головний фрейм, але забувають про iframe. |
s159 (native function) | Видаляє Function та Object і перевіряє, чи справді нативні getter'и. Виявляє інструментування на основі Proxy. |
s155 (window CRC32) | CRC32-хеш-сканування кожної властивості window для виявлення впроваджених глобальних об'єктів автоматизації |
s163 (devtools trap) | Пастка на console-getter — виявляє, коли DevTools активно відкриті |
Сервер запускає набір детекторів, чиї зважені результати комбінуються у
bot-score. Score зіставляється з вердиктом через порогові значення — bot, коли він ≥ 0,70,
suspicious, коли ≥ 0,30, інакше human — а hard-fail-сигнал (наприклад,
navigator.webdriver) одразу примусово встановлює вердикт bot. Вердикти bot несуть
довільну мітку bot_type.
Репрезентативні детектори та їхній ефект:
| Детектор | Ефект |
|---|---|
| Прапорець webdriver | Hard-fail → bot (тип webdriver) |
| Композитне сканування автоматизації / фреймворків | Висока вага → bot (тип {framework}) |
| Headless-маркери | Зважено → bot (тип headless) |
| Аномалія eval-length | Зважено → bot (тип unknown) |
| Патерн UA поганого бота | Зважено → bot (тип {label}) |
| Верифікований хороший бот (reverse DNS) | Allowlist → human |
| Поведінкове (rate / entropy / interaction) | Зважено → bot (тип rateBot) |
| VM (Enterprise) · Emulator · DevTools (Business+) | Зважені сигнали пристрою/tamper |
Тариф і доступність. Виявлення DevTools працює на Business та Enterprise; виявлення VM — Enterprise; виявлення емулятора працює на всіх планах. Усе це працює у веб-агенті. Виявлення root, jailbreak, клонованих/dual-app, Frida та скидання до заводських налаштувань залежить від нативних мобільних сигналів і не є ефективним у веб-розгортанні (у розробці). Покладайтеся на вердикти щодо автоматизації, headless, ШІ-агентів, antidetect, VM/емулятора та поведінки, які повністю активні у веб.
Виявлення ботів записує поле bot_result у кожній події (та bot.result у
payload вебхука).
bot_result — одне з трьох канонічних значень:
| Результат | Опис |
|---|---|
human | Індикаторів автоматизації не знайдено. Верифіковані кроулери пошукових систем також дають human. |
bot | Виявлено автоматизований або скриптований доступ. Його супроводжує довільна мітка bot_type. |
uncertain | Змішані або слабкі сигнали — ані явно людина, ані явно автоматизація. |
Це зіставляється з бізнес-полем decision (real, fake або suspicious),
що використовується у всьому dashboard, і з bot.result у
payload вебхука.
"bot")bot_type — довільний рядок. Наведені нижче значення є ілюстративними прикладами того,
що видають детектори, а не вичерпним enum:
| Тип | Метод виявлення |
|---|---|
webdriver | navigator.webdriver дорівнює true |
selenium | Виявлено специфічні для Selenium властивості window/document |
puppeteer | Збіг за Puppeteer/Chromium headless-індикаторами |
playwright | Виявлено специфічні для Playwright маркери або UA-рядок |
headless | Спрацювало 2+ з 11 headless-маркерів |
phantomjs | Виявлено глобальні об'єкти PhantomJS (callPhantom, _phantom) |
nightmare | Виявлено глобальні об'єкти NightmareJS |
unknown | Аномалія eval-length або інші неспецифічні індикатори автоматизації |
rateBot | Поведінковий аналіз rate перевищив порогові значення |
Найпряміше виявлення. Усі основні фреймворки автоматизації встановлюють navigator.webdriver = true згідно зі специфікацією WebDriver. Це перевіряється як у головному фреймі (s300), так і в прихованому iframe (s158), щоб виявити інструменти, які патчать лише головний фрейм.
Комплексне сканування властивостей window та document на специфічні для фреймворків артефакти:
| Фреймворк | Виявлені властивості |
|---|---|
| Selenium | _Selenium_IDE_Recorder, _selenium, calledSelenium, __selenium_evaluate, $cdc_* (ChromeDriver) |
| Puppeteer | domAutomation, domAutomationController, HeadlessChrome UA |
| Playwright | __playwright, automation-controlled flag |
| PhantomJS | callPhantom, _phantom |
| NightmareJS | __nightmare, nightmare |
| CefSharp | CefSharp |
| Awesomium | awesomium |
| WebDriverIO | wdioElectron |
| Cypress | Властивість window __cypress |
Сканування також використовує regex-патерн /^([a-z]){3}_.*_(Array|Promise|Symbol)$/ для виявлення впроваджених Selenium допоміжних глобальних об'єктів.
Оцінюється 11 маркерів, з порогом 2 або більше для класифікації:
| Маркер | Сигнал | Умова |
|---|---|---|
| webdriver | s300 | = "true" |
| відсутні vendor-flavor | s28 | Немає об'єктів chrome/safari на window |
| CDP headless chrome | s305 | headlessChrome = true |
| notification denied | s88 | Notification.permission = "denied" при першому візиті |
| chrome no runtime | s89 | window.chrome існує, але chrome.runtime відсутній |
| single language | s90 | navigator.languages.length <= 1 |
| default screen 800x600 | s5 | Роздільна здатність headless Chrome за замовчуванням |
| HeadlessChrome UA | UA | User-Agent містить "HeadlessChrome" |
| zero outer dimensions | s97 | outerWidth = 0 та outerHeight = 0 |
| WebGL SwiftShader | s70 | Renderer містить "swiftshader" (програмний GPU) |
| WebGL llvmpipe | s70 | Renderer містить "llvmpipe" (програмний GPU) |
Відомі хороші боти розпізнаються за патерном User-Agent. Кожен верифікується через reverse DNS, щоб запобігти spoofing:
.googlebot.com)| Бот | Дозволені домени |
|---|---|
.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 |
Якщо запит стверджує, що він Googlebot, але reverse DNS його IP розв'язується у сторонній домен (підтверджена невідповідність PTR, а не просто відсутній/протермінований запит), він класифікується як bot (тип spoofed:google).
Виявлення на основі rate з entropy-scoring:
| Частота (запитів/хв) | Поріг ентропії | Дія |
|---|---|---|
| 120+ | < 0.1 | bot (тип: rateBot) |
| 60-120 | < 0.3 | bot (тип: rateBot) |
| 45-60 | < 0.1 | bot (тип: rateBot) |
| < 45 | Будь-яка | Норма |
Додаткове правило: відсутність подій миші/клавіатури після 30+ секунд тривалості сесії класифікує візит як bot з типом noInteraction.
eval.toString().length дає узгоджені значення для кожного engine:
Будь-яке інше значення вказує на те, що функцію eval перехопив фреймворк автоматизації, що класифікує візит як bot з типом unknown.
Клієнтський SDK надає зручний boolean, 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)На своєму сервері реагуйте на доставку вебхука. Виявлення ботів
міститься в об'єкті bot — bot.result та 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")})Виявлення ботів TRACIO спроєктоване для майже нульової кількості хибних спрацювань. Проте можливі граничні випадки:
| Сценарій | Ризик | Пом'якшення |
|---|---|---|
Розширення браузера, що змінюють navigator | Низький | Множинна крос-валідація сигналів запобігає спрацюванню від одного сигналу |
| Корпоративне ПЗ безпеки | Дуже низький | Виявлення headless вимагає 2+ маркерів |
| Інструменти доступності | Немає | API доступності не активують жодного сигналу виявлення |
| Користувачі VPN/proxy | Немає | Використання VPN відстежується окремо від виявлення ботів |
Якщо ви натрапите на хибні спрацювання, перегляньте поле bot.type, щоб зрозуміти, який детектор спрацював, і відповідно скоригуйте свою політику.