Overview
Bots account for a significant portion of web traffic. While some bots are beneficial (search engine crawlers), others are malicious: scrapers, credential stuffers, inventory hoarders, and DDoS agents. Detecting bots requires a layered approach combining server-side and client-side signals.
Client-Side Detection Techniques
WebDriver API
The simplest check: navigator.webdriver returns true when the browser is controlled by automation tools like Selenium, Puppeteer, or Playwright. Modern bots try to delete this property, but detection is still possible by checking for residual artifacts.
Chrome Object Inspection
Some older headless implementations exposed different window.chrome properties. Modern Chrome shares its headless and headful implementation, so these properties are weak, version-dependent clues. See the Chrome Headless documentation.
Plugin and Permission Anomalies
Modern navigator.plugins commonly reports standardized PDF-viewer entries, or an empty list when inline PDF viewing is unavailable. Plugin counts and permission states are not reliable proof of automation; browser settings and platform differences can affect both. See MDN's plugin API documentation.
Browser Feature Consistency
Bots often fail to fully implement all browser APIs. Checks include: media device enumeration, notification API support, screen dimensions matching viewport, and proper event handling. An inconsistency between claimed capabilities and actual behavior can indicate automation, but can also reflect browser restrictions or unsupported features.
Server-Side Detection Techniques
TLS Fingerprint Mismatch
A default Python requests client commonly uses OpenSSL and can produce a different JA4 profile from Chrome's BoringSSL-based implementation, even when it sends a Chrome User-Agent. TLS-aware clients can imitate browser handshakes, so a mismatch is one clue rather than definitive proof. See the JA4 specification.
Header Order Analysis
Real browsers send HTTP headers in a consistent order specific to each browser engine. Bots using HTTP libraries often have different header orderings or include headers that real browsers don't send.
TCP/IP Fingerprinting
If the UA claims Windows but the TCP stack reveals Linux (common when bots run on cloud servers), the OS mismatch can indicate automation, but TCP-terminating proxies can also expose a different OS stack. See our TCP/IP Fingerprinting guide for details.
HTTP/2 Settings Fingerprinting
Browser HTTP/2 implementations send specific SETTINGS frames with values for HEADER_TABLE_SIZE, MAX_CONCURRENT_STREAMS, INITIAL_WINDOW_SIZE, and MAX_HEADER_LIST_SIZE. These values differ between Chrome, Firefox, Safari, and common HTTP libraries.
Combined Bot Scoring
No single signal is definitive. Zunavek combines 15+ indicators into a weighted bot score:
- Client-side signals are collected via JavaScript
- Server-side signals are extracted from the connection itself
- Weights account for signal reliability and false positive rates
- The final score (0-100) maps to a classification: human, low automation, suspicious, or bot
Test Bot Detection
Visit our Bot Detection page to see how your browser performs against our detection suite. Try it in both a normal browser and a headless/automated one to see the difference.