Seatext library / BotRefund evidence

How to Detect Headless Chrome on Your Website: Methods, Signals, and Implementation Steps

Detect headless Chrome by checking for the navigator.webdriver property, analyzing user-agent strings for automation flags, testing for missing browser UI elements like chrome.runtime, and measuring behavioral anomalies such as superhuman input speed or absent...

Built for advertisers who need clear, refund-ready traffic evidence.

Headless Chrome leaves detectable traces because automation frameworks like Puppeteer, Playwright, and Selenium modify browser internals that normal users never trigger. The fastest signal is navigator.webdriver === true, which the Chrome DevTools Protocol sets when a debugging client attaches. However, sophisticated bots patch this property, so you need layered checks: user-agent inconsistencies, missing chrome.runtime or chrome.app objects, abnormal window.outerWidth/innerWidth ratios, and behavioral red flags like linear mouse paths or sub-millisecond click speeds.

Why Headless Chrome Detection Matters for Ad Spend and Analytics

Automated browsers inflate click counts, poison conversion pixels, and skew bidding algorithms. When bots trigger your Google Ads or Meta conversion events, the platforms optimize toward that fake traffic, raising your real cost per acquisition. BotRefund's data shows bot clicks can steal up to 20% of Google and Meta ad budgets, and their client-side audits capture the behavioral evidence needed to win refund disputes. Detecting headless Chrome early protects your pixel data and keeps your optimization algorithms trained on real humans.

Core JavaScript Checks You Can Run Today

  1. Check navigator.webdriver — returns true in uncontrolled headless sessions.
  2. Inspect navigator.userAgent — headless often drops "HeadlessChrome" or shows mismatched version strings.
  3. Test for chrome.runtime and chrome.app — these extension APIs are absent in headless mode.
  4. Measure window.outerWidth vs innerWidth — headless often reports equal values because there is no browser chrome.
  5. Probe navigator.plugins and navigator.mimeTypes — empty or generic lists suggest a stripped-down environment.
  6. Run a WebGL fingerprint — headless renderers often return "Google Inc. (NVIDIA)" or "SwiftShader" instead of a real GPU vendor.

Each check alone produces false positives. Legitimate users on corporate networks or privacy tools can trigger one signal. The reliable approach is scoring multiple signals together, which is what BotRefund's prediction AI does across 106 vectors.

Advanced Behavioral Signals That Catch Patched Bots

Modern bot frameworks patch the obvious JavaScript properties. BotRefund's detection vectors go deeper:

  • CDP Debugger Leak (Signal 16) — detects traces left by the Chrome DevTools Protocol connection that automation tools require.
  • Native Patching (Signal 17) — verifies whether built-in browser APIs behave like a real device or have been monkey-patched.
  • Engine Mismatch (Signal 18) — compares the JavaScript engine's reported capabilities against expected Chrome baselines.
  • Rebrowser Leaks (Signal 19) — catches artifacts from tools that try to make headless look like a full browser.
  • JS Engine Mismatch (Signal 20) — checks for inconsistencies in V8 internal behavior.
  • Automation Properties (Signal 21) — scans for non-standard properties injected by automation frameworks.

These signals are evaluated together with network, geolocation, and hardware vectors (such as WebRTC leaks, DNS routing mismatches, and TCP TTL anomalies) to reach a classification decision. No single signal decides; the pattern does.

Step-by-Step Implementation Framework

  1. Add a lightweight client-side script that collects the core JavaScript checks on page load and on user interaction events.
  2. Send the signal payload to your backend via a beacon or fetch request; keep the payload under 2 KB to avoid slowing the page.
  3. Score the signal bundle using a weighted model: start with the six core checks above, then layer in behavioral telemetry (mouse movement entropy, scroll depth, click timing, form completion speed).
  4. Set a threshold for "suspected automation" and route those sessions to a review queue or a honeypot page that only bots will interact with.
  5. Log Google Click IDs (GCLIDs) and Facebook Click IDs (FBCLIDs) alongside the detection verdict so you can attach behavioral evidence to refund claims.
  6. Verify weekly by running a known headless browser (Puppeteer with --headless=new) through your funnel and confirming your script flags it.

Common Mistakes and Limitations

  • Relying on one signalnavigator.webdriver alone misses patched bots and flags some privacy tools.
  • Blocking on first detection — aggressive blocking hurts real users behind corporate proxies; use challenge pages or silent scoring instead.
  • Ignoring behavioral context — a visitor with a clean browser fingerprint but superhuman click speed (<1 ms) is still a bot.
  • No evidence capture for refunds — ad platforms require click IDs linked to behavioral proof; logging only the verdict loses the refund path.
  • Maintenance burden — browser updates change fingerprints quarterly; a static script rots fast. BotRefund updates its 106-signal model continuously.

Key Facts

FactDetailSource
Total detection signals106 browser, network, hardware, and behavior signals evaluated togetherS1
Classification accuracy99% accuracy claimed for human vs. bot classificationS1
Headless-specific signalsSignals 16–21 cover CDP debugger leaks, native patching, engine mismatch, rebrowser leaks, JS engine mismatch, automation propertiesS1
Bot click budget impactUp to 20% of Google and Meta ad budgets lost to bot clicksS2
Refund success rate83% refund success rate for high-volume advertisersS2
Behavioral evidence typesMouse tremor absence, linear paths, grid-aligned movement, superhuman input speed, session duration anomaliesS2
Installation timeAdd to website in about one minute, no credit card requiredS2
Historical refund reachRecover Google Ads spend dating back to 2017S2

Terminology Quick Reference

  • Headless Chrome — Chrome running without a visible UI, typically driven by Puppeteer, Playwright, or Selenium.
  • CDP (Chrome DevTools Protocol) — The debugging interface automation tools use to control Chrome; its presence leaks automation.
  • Native patching — Overwriting built-in browser APIs (e.g., navigator.webdriver) to hide automation traces.
  • GCLID / FBCLID — Google Click ID and Facebook Click ID; required identifiers for ad-platform refund disputes.
  • Pixel poisoning — Invalid traffic triggering conversion pixels, causing bidding algorithms to optimize for bots.

Frequently Asked Questions

Can I detect headless Chrome with just a few lines of JavaScript?

You can catch naive bots with navigator.webdriver and user-agent checks, but any serious bot framework patches those. Reliable detection needs behavioral telemetry (mouse, scroll, timing) and multiple browser-internals signals scored together.

Will these checks break legitimate users on privacy browsers or corporate networks?

Some privacy tools and corporate proxies strip or modify the same properties bots patch. Score signals instead of blocking on one flag; use a challenge page or silent review for borderline sessions.

How do I use detection results to get ad refunds from Google or Meta?

Capture the GCLID or FBCLID on landing, link it to your behavioral verdict (e.g., "superhuman click speed, no mouse tremor, CDP leak detected"), and submit the evidence package through the platform's invalid-click dispute process. BotRefund automates this evidence capture and report generation.

What is the difference between server-side and client-side bot detection?

Server-side looks at IP reputation, headers, and request patterns — good for basic scrapers but blind to residential proxy botnets. Client-side runs in the browser and sees automation fingerprints, behavioral biometrics, and hardware signals that never reach the server.

How often do detection signatures need updating?

Chrome releases a new stable version roughly every four weeks. Each release can change WebGL strings, plugin enumerations, and internal V8 behavior. A maintained service updates signatures continuously; a DIY script needs monthly review.

Does BotRefund block bots or just detect them?

BotRefund detects and provides the evidence for refund claims. It also offers real-time pixel protection to stop invalid sessions from firing conversion events, which prevents pixel poisoning while you pursue refunds.

What ad spend levels make refund recovery worthwhile?

BotRefund's pricing tiers start at under $10,000/mo ad spend and scale to over $5M/mo. The 83% refund success rate is reported for high-volume advertisers, but the free bot audit works at any spend level to quantify the problem first.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Learn more

Visit the website for more information.

Learn more