Headless-detector — практичний набір сигналів для виявлення headless та automation у браузері

💡 Усі статті, обговорення, новини про тестування — в одному місці. Приєднуйтесь до QA спільноти!

Мене звати Андрій, я працюю з веб-проєктами де є форми, реєстрації, флоу з високою ціною помилки (спам, фрод, накрутки, «прогрів» акаунтів). На словах все просто — «знайди бота і заблокуй». На практиці — ботів стало набагато більше через ШІ-революцію.

Через це мені захотілось мати інструмент, який:

  • не робить магічне bot: true з одного прапорця
  • показує, чому ми вирішили що сесія підозріла
  • дає більш-менш стабільний скоринг, який можна підкрутити під свою логіку

Так з’явився headless-detector — невелика JS-бібліотека для клієнтської діагностики automation/headless середовища.

Репозиторій: github.com/...​vchenko/headless-detector

Демо: headless-detector.vercel.app

NPM: www.npmjs.com/...​package/headless-detector

Що саме перевіряється

1) WebDriver та automation flags

Перевірки на зразок navigator.webdriver плюс типові глобальні змінні/ознаки, які лишають Selenium, Playwright, Puppeteer, PhantomJS та інші фреймворки.

2) CDP артефакти (Chrome DevTools Protocol)

В детекторі є перевірки на характерні сліди ChromeDriver/CDP.

3) Headless індикатори середовища

Наприклад, нетипові розміри вікна, поведінка outer/inner dimensions, деякі ньюанси з permissions.

4) WebGL renderer

Виконує складний рендеринг 3D-сцен для виявлення програмних рендерів у порівнянні з реальними графічними процесорами.

5) Media/WebRTC та базові API

У headless режимі або в сильно обмежених профілях інколи відсутні mediaDevices, getUserMedia, або WebRTC працює не так як очікується. Важливо розуміти, що тут можуть бути false positives через приватність, корпоративні політики, sandboxing.

6) Fingerprinting-блок (canvas/audio/fonts)

Це не спроба «вирахувати користувача». Ідея простіша — знайти аномалії середовища, які часто корелюють з headless/automation або з агресивним spoofing’ом.

7) Системна інформація

  • Battery API, Hardware concurrency, memory, etc
  • Locale, Timezone

8) Audio Context fingerprinting

Headless-браузери можуть по-іншому обробляти аудіо

9) Font detection

Headless-браузери зазвичай мають менше трьох доступних шрифтів

10) Playwright Detection (Castle.io 2026)

Виявлення специфічних об’єктів та exposed functions Playwright
11) 🔧Worker UA Check
Порівнює User-Agent між основним потоком та Web Worker для виявлення невідповідностей
12) 😀 Emoji OS Consistency Check

Перевіряє відповідність відображення емодзі заявленій операційній системі

Найкорисніше — не score, а пояснення

Детектор повертає не тільки цифру, а ще два важливі поля:

  • explanations — короткий опис кожного методу: що він шукає, навіщо, і який у нього impact
  • summary — агрегований звіт: класифікація, risk level, список детекцій та попереджень, плюс рекомендація

Як це виглядає у коді

Найпростіший сценарій — підключити файл детектора і викликати detectHeadless():

// 1) Запустити детекцію
const result = detectHeadless(true); // true — щоб прикріпити результат до window для дебага

// 2) Числовий скор (0..1)
console.log("score:", result.isHeadless);

// 3) Пояснення
console.log(result.summary.classification);
console.log(result.summary.riskLevel);
console.log(result.summary.detections);
console.log(result.summary.warnings);

// 4) Детальні «що і навіщо»
console.log(result.explanations);

Обмеження (без цього було б нечесно)

  • Деякі сигнали легко спуфяться
  • Частина сигналів може спрацьовувати в легітимних користувачів (VM, privacy browsers, корпоративні політики, нестандартні профілі).
  • Якщо атакуюча сторона має мотивацію, це завжди гра в Том і Джеррі
👍ПодобаєтьсяСподобалось5
До обраногоВ обраному2
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Як кайфово заходить з відіайки і бачить, що ти заблокований, бо схожий на бота. Дякую (жарт, звісно)

завтра буду працювати — чекну )

Software renderer, Number of fonts, Webdriver getter modifier ;)

Але що більш цікаво, скриптик який я накодив за 2 хвилини, показує нойз рейт вже 0.1 і каже, що це нормальний браузер )

(Playwright, stealth_playwright, few js script dummies, like “window.chrome = {runtime: {}, app: {}}”, “navigator.permissions”)

Все вірно, це легко спуфиться. Це була версія 1.0, зараз майже готова 2.0, де додав BehaviorMonitor з просунутими метриками (Mouse Movement Entropy, Keyboard Biometrics, Scroll Behavior, WebGL Shader Timing, Sensor API Entropy, Audio Fingerprint, Touch Pressure/Radius, Event Timing Consistency, Timing Resolution, Iframe Sandbox)

а що воно таке, оця

відіайка

?

трішки додам ідей —
— перевіряйте юзер агент в воркері, в хромі недавно баг виправили (chromiumdash.appspot.com/...​8952c81eedde553dfeb746ff3),
але мабуть, мабуть ще когось зловите на цьому.
— на канвасі можна малювати емодзі які мають відповідати ОС з юзер агента.
— WebGl — VENDOR та RENDERER підміняються, а ось реальну картинку ніяк.
Потрібно на WebGl намалювати щось ± складне, покрутити по осях і т.д., взяти хеш з картинки —
в бота буде або шум, або типова картинка для програмного рендера,
але ніяк не вийде типова для Win11 + RTX3050 як вказано в VENDOR та RENDERER
— час реакції на діалог типу windows.confirm але для користувачів це не дуже(

Цікаво, спробую реалізувати

Готово, додав worker, рендеринг куба з освітленням через WebGL та рендеринг емодзі через Canvas

трошки по іншому я мав на увазі — потрібно мати на сервері БД з хешами (картинками) емодзі та webgl + ОС, версія браузера, gl_vendor, gl_renderer, і якщо у 1000 людей win + rtx3050 = хеш, а бот підмінив юзер агент + відеокарту (win + rtx3050), але по хешу ми бачимо софтверний рендер = бот. І з емодзі на канвасі така ж логіка.

Зрозумів, дякую. Так як пакет суто для фронтенду, тоді в цих перевірках немає сенсу, так як хеші можна легко витягнути.

Це прикольно, але є і зворотня сторона медалі.

Наприклад я, за для розваги, написав на python + selenium скрипти які я натравлюю на усякого рода шахраїв по типу «повернемо грощі», «ChatGPT/WhatsApp/Facebook traiding», «Orlovsky» (наш інфоциган), і тому подібного. Вони на своїх сайтиках пропонують залишити ім’я, телефон, e-mail і потім кол центри передзвонюють по тим номерам і починають дурити.
Короче звичайні собі шахраї.
Так от мої скрипти використовуючи ще Tor. Кожен раз змінюючи шлях (у Tor є таке API, control port 9151), тупо заповнюють ці анкетки рандомними телефонами іменами.
Тим самим ускладнюючи кол центрам можливість пробитися до реального «лоха» який повірив у швидкий заробіток, та залишив свої данні на такому сайті.

З появою таких бібліотек як Ваша, вони можуть почати вбудовувати це в свої сайтики.

Якщо є сильна мотивація, більшість цих перевірок можна обійти.

Код в відкритому доступі, ChatGPT в поміч 😌

Помітив що великі компанії, такі як LinkedIn протидіють ботам по іншому: вони не банять користувача напряму, в використовують «shadow ban» замість прямого блокування і Machine Learning для виявлення таких ботів.

Якщо що, комерційні рішення такого плану існують вже не перший рік. Ні в якому разі не знецінюю працю автора, бо написати таке самотужки — це нефігова така експертиза, плюс автор ще й виклав свої напрацювання в open source. Але, з іншого боку, всі, кому треба — вже давно впровадили подібні bot management рішення. Навіть CloudFlare має таке майже «з коробки».

Дякую за допис! Було б ще файно побачити приклад того, що виводять ті логи коли знайшли бота і на скільки взагалі ця тема вийшла успішна. І загалом цікаво подивитися на статистику того, скільки ботів вийшло зловити, а скільки — ні :)

Дякую за коментар. На сторінці демо є логи і пояснення

Підписатись на коментарі