Sistem deteksi bot TRACIO mengidentifikasi browser otomatis, alat headless, dan serangan berbasis skrip menggunakan arsitektur dua lapis: pengumpulan sinyal sisi klien dan analisis sisi server. Sistem ini mendeteksi framework otomasi umum, browser headless, agen penjelajahan AI, dan browser antidetect dengan false positive nyaris nol, sekaligus secara otomatis menempatkan crawler mesin pencari yang sah ke dalam allowlist.
Agen browser mengumpulkan berbagai sinyal spesifik-bot dan sinyal cross-validation yang menjadi masukan bagi keputusan sisi server. ID sinyal di bawah ini bersifat ilustratif — ID internal bukanlah kontrak publik yang stabil:
| Sinyal | Deskripsi |
|---|---|
s300 (webdriver) | Flag navigator.webdriver — disetel ke true oleh framework otomasi |
s301 (eval length) | eval.toString().length — Chrome/Edge: 33, Firefox: 37. Nilai lain menandakan instrumentasi. |
s305 (bot composite) | Memindai window/document untuk 14 artefak framework otomasi |
s97 (headless markers) | Artefak CDP, izin notifikasi, jumlah plugin, dimensi luar |
s157 (automation scan) | Pemindaian menyeluruh untuk Selenium, Puppeteer, PhantomJS, Playwright, dan 10 lainnya |
s158 (iframe webdriver) | Membuat iframe tersembunyi dan membaca navigator.webdriver di dalamnya. Menangkap alat yang menambal frame utama tetapi melupakan iframe. |
s159 (native function) | Menghapus Function dan Object, menguji apakah getter benar-benar native. Mendeteksi instrumentasi berbasis Proxy. |
s155 (window CRC32) | Pemindaian hash CRC32 pada setiap properti window untuk mendeteksi global otomasi yang disuntikkan |
s163 (devtools trap) | Jebakan getter console — mendeteksi saat DevTools sedang terbuka aktif |
Server menjalankan sekumpulan detektor yang keluaran berbobotnya digabungkan
menjadi bot score. Skor tersebut dipetakan ke sebuah verdict melalui ambang batas — bot saat ≥ 0,70,
suspicious saat ≥ 0,30, selain itu human — dan sinyal hard-fail (seperti
navigator.webdriver) langsung memaksa verdict bot. Verdict bot membawa
label bot_type berbentuk bebas.
Detektor representatif dan efeknya:
| Detektor | Efek |
|---|---|
| Webdriver flag | Hard-fail → bot (tipe webdriver) |
| Composite automation / framework scan | Bobot tinggi → bot (tipe {framework}) |
| Headless markers | Berbobot → bot (tipe headless) |
| Eval-length anomaly | Berbobot → bot (tipe unknown) |
| Bad-bot UA pattern | Berbobot → bot (tipe {label}) |
| Verified good bot (reverse DNS) | Allowlist → human |
| Behavioral (rate / entropy / interaction) | Berbobot → bot (tipe rateBot) |
| VM (Enterprise) · Emulator · DevTools (Business+) | Sinyal perangkat/tamper berbobot |
Tier & ketersediaan. Deteksi DevTools berjalan pada Business dan Enterprise; deteksi VM adalah Enterprise; deteksi emulator berjalan pada semua paket. Semua ini bekerja di web agent. Deteksi root, jailbreak, aplikasi klon/ganda, Frida, dan factory-reset bergantung pada sinyal native-mobile dan tidak efektif pada penerapan web-saja (dalam pengembangan). Andalkan verdict otomasi, headless, agen AI, antidetect, VM/emulator, dan perilaku, yang sepenuhnya aktif di web.
Deteksi bot menuliskan field bot_result pada setiap event (dan bot.result di
payload webhook).
bot_result adalah salah satu dari tiga nilai kanonis:
| Hasil | Deskripsi |
|---|---|
human | Tidak ada indikator otomasi ditemukan. Crawler mesin pencari terverifikasi juga menghasilkan human. |
bot | Akses otomatis atau berbasis skrip terdeteksi. Label bot_type berbentuk bebas menyertainya. |
uncertain | Sinyal campuran atau lemah — tidak jelas manusia maupun jelas otomatis. |
Ini dipetakan ke field bisnis decision (real, fake, atau suspicious)
yang digunakan di seluruh dashboard, dan ke bot.result pada
payload webhook.
"bot")bot_type adalah string berbentuk bebas. Nilai-nilai di bawah ini adalah contoh ilustratif dari
apa yang dikeluarkan detektor, bukan enum yang lengkap:
| Tipe | Metode Deteksi |
|---|---|
webdriver | navigator.webdriver bernilai true |
selenium | Properti window/document spesifik Selenium terdeteksi |
puppeteer | Indikator headless Puppeteer/Chromium cocok |
playwright | Marker spesifik Playwright atau string UA terdeteksi |
headless | 2+ dari 11 marker headless terpicu |
phantomjs | Global PhantomJS terdeteksi (callPhantom, _phantom) |
nightmare | Global NightmareJS terdeteksi |
unknown | Anomali eval length atau indikator otomasi non-spesifik lainnya |
rateBot | Analisis rate perilaku melampaui ambang batas |
Deteksi yang paling langsung. Semua framework otomasi utama menyetel navigator.webdriver = true sesuai spesifikasi WebDriver. Ini diperiksa baik di frame utama (s300) maupun di iframe tersembunyi (s158) untuk menangkap alat yang hanya menambal frame utama.
Pemindaian menyeluruh terhadap properti window dan document untuk artefak spesifik-framework:
| Framework | Properti Terdeteksi |
|---|---|
| Selenium | _Selenium_IDE_Recorder, _selenium, calledSelenium, __selenium_evaluate, $cdc_* (ChromeDriver) |
| Puppeteer | domAutomation, domAutomationController, UA HeadlessChrome |
| Playwright | __playwright, flag automation-controlled |
| PhantomJS | callPhantom, _phantom |
| NightmareJS | __nightmare, nightmare |
| CefSharp | CefSharp |
| Awesomium | awesomium |
| WebDriverIO | wdioElectron |
| Cypress | Properti window __cypress |
Pemindaian juga menggunakan pola regex /^([a-z]){3}_.*_(Array|Promise|Symbol)$/ untuk mendeteksi global helper yang disuntikkan Selenium.
11 marker dievaluasi, dengan ambang batas 2 atau lebih untuk klasifikasi:
| Marker | Sinyal | Kondisi |
|---|---|---|
| webdriver | s300 | = "true" |
| missing vendor flavors | s28 | Tidak ada objek chrome/safari pada window |
| CDP headless chrome | s305 | headlessChrome = true |
| notification denied | s88 | Notification.permission = "denied" pada kunjungan pertama |
| chrome no runtime | s89 | window.chrome ada tetapi chrome.runtime hilang |
| single language | s90 | navigator.languages.length <= 1 |
| default screen 800x600 | s5 | Resolusi default Headless Chrome |
| HeadlessChrome UA | UA | User-Agent mengandung "HeadlessChrome" |
| zero outer dimensions | s97 | outerWidth = 0 dan outerHeight = 0 |
| WebGL SwiftShader | s70 | Renderer mengandung "swiftshader" (GPU perangkat lunak) |
| WebGL llvmpipe | s70 | Renderer mengandung "llvmpipe" (GPU perangkat lunak) |
Bot baik yang dikenal dikenali berdasarkan pola User-Agent. Masing-masing diverifikasi melalui reverse DNS untuk mencegah spoofing:
.googlebot.com)| Bot | Domain yang Diizinkan |
|---|---|
.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 |
Jika sebuah permintaan mengaku sebagai Googlebot tetapi reverse DNS dari IP-nya menyelesaikan ke domain asing (ketidakcocokan PTR yang terkonfirmasi, bukan sekadar lookup yang hilang/timeout), permintaan tersebut diklasifikasikan sebagai bot (tipe spoofed:google).
Deteksi berbasis rate dengan penilaian entropi:
| Rate (req/min) | Ambang Entropi | Aksi |
|---|---|---|
| 120+ | < 0.1 | bot (tipe: rateBot) |
| 60-120 | < 0.3 | bot (tipe: rateBot) |
| 45-60 | < 0.1 | bot (tipe: rateBot) |
| < 45 | Apa pun | Normal |
Aturan tambahan: Tidak adanya event mouse/keyboard setelah usia sesi 30+ detik mengklasifikasikan kunjungan sebagai bot dengan tipe noInteraction.
eval.toString().length menghasilkan nilai yang konsisten per engine:
Nilai lain apa pun menandakan fungsi eval telah di-hook oleh framework otomasi, sehingga mengklasifikasikan kunjungan sebagai bot dengan tipe unknown.
Client SDK menyediakan boolean praktis, 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)Di server Anda, tanggapi pengiriman webhook. Deteksi bot
berada di dalam objek bot — bot.result dan 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")})Deteksi bot TRACIO dirancang untuk false positive nyaris nol. Namun, kasus tepi dapat terjadi:
| Skenario | Risiko | Mitigasi |
|---|---|---|
Ekstensi browser yang memodifikasi navigator | Rendah | Cross-validation banyak sinyal mencegah pemicuan oleh sinyal tunggal |
| Perangkat lunak keamanan korporat | Sangat rendah | Deteksi headless membutuhkan 2+ marker |
| Alat aksesibilitas | Tidak ada | API aksesibilitas tidak memicu sinyal deteksi apa pun |
| Pengguna VPN/proxy | Tidak ada | Penggunaan VPN dilacak terpisah dari deteksi bot |
Jika Anda menemukan false positive, tinjau field bot.type untuk memahami detektor mana yang terpicu dan sesuaikan kebijakan Anda.