Skip to content
Blog

Automated browser detection: evidence and actions

Detect Playwright, Selenium and other automated browsers with request, browser and session evidence, then choose when to observe, challenge or block.

Frederick Jahn
Published Updated
Automated browser detection: evidence and actions

Detect browser automation by combining independent request, browser, and session evidence, then checking it against the action you protect. navigator.webdriver === true reports WebDriver control; false does not prove a human visitor. Neither result establishes abuse.

Start with the decision your team needs to make: stop repeated extraction, protect an interactive workflow, or preserve approved monitoring. Choose one route and record both suspicious activity and legitimate completions before enabling enforcement. Blocking more sessions is not success if the intended users can no longer finish that workflow.

For a vendor evaluation, use the bot management checklist to compare evidence availability, false-positive handling, and rollback. For content extraction, the scraping and AI crawler use case connects these checks to resource policy.

Start with navigator.webdriver

navigator.webdriver is the web platform's standard automation disclosure. The W3C WebDriver specification says the property returns true when the browser's WebDriver-active flag is set. The spec describes it as a way for a cooperating browser to tell a page that WebDriver controls it.

You can inspect it with one expression:

const webdriverDeclared = navigator.webdriver === true;

Interpret the result narrowly:

  • true means this browser reports that it is under WebDriver control;
  • false does not prove that a human controls the browser;
  • either result says nothing about whether the activity is approved or abusive.

A positive value can come from your own regression tests, uptime monitoring, or another legitimate automated workflow. Automation can also use a different control path or alter browser-visible state. Keep the raw value as one named observation. Do not turn it into a universal block rule.

Build a layered evidence model

Use layers that fail differently. Each layer should record an observation, its source, and its confidence rather than writing a final verdict into the field.

Signal layerWhat it observesCommon evasion or driftFalse-positive riskPair it with
Declared identityUser agent, Client Hints, language, referrer, crawler tokenHeaders can be copied, removed, or made internally inconsistentPrivacy tools, embedded browsers, unusual clientsConnection, environment, published crawler verification
Connection and protocolSource path, TLS handshake, negotiated protocol, HTTP/2 behaviorProxies and impersonation libraries change what the server seesCDN changes, browser updates, shared networksDeclared identity, session continuity, traffic history
Browser environmentExposed APIs, viewport, platform, locale, time zone, feature supportProfiles and injected scripts can modify valuesEnterprise policy, extensions, accessibility tools, privacy protectionsDeclared identity, control artifacts, repeated observations
Automation and control artifactsWebDriver disclosure, injected globals, execution contexts, protocol side effectsFramework and browser changes remove or reshape artifactsDeveloper tools, QA harnesses, monitoring, extensionsEnvironment, session behavior, approved-tool inventory
Session behaviorNavigation order, resource graph, interaction sequence, dwell and input timingAutomation can wait, replay, or drive browser input APIsPower users, assistive technology, prefetching, poor networksRoute risk, first-party session, traffic history
Traffic historyRepetition across sessions, accounts, networks, routes, and time windowsDistributed clients rotate identifiers and pace workNAT, shared offices, viral traffic, scheduled jobsStrong first-party identity, per-route budgets, current session evidence

Collect only the fields needed to answer a specific abuse question. A public page, a login form, and an account export need different evidence and response thresholds.

Declared identity

Headers and browser properties are still useful. They establish what the client claims to be and give later layers something concrete to check. Store the claim separately from any inferred identity.

For a named crawler, compare the exact token with the operator's current verification method. Do not treat a plausible browser user agent as verified browser identity. The same rule applies to language, platform, and device claims: an inconsistency can add evidence, but an unusual combination is not a verdict.

Connection and protocol

Connection metadata is observed outside page JavaScript. Useful fields can include the TLS fingerprint, negotiated application protocol, source path, and HTTP version. Collection must happen at the boundary that sees the visitor's connection. A CDN that terminates TLS may expose different metadata to the origin.

HTTP/2 starts with a connection preface followed by a SETTINGS frame from each endpoint. RFC 9113 defines the frame and its parameters. Implementations can choose different valid settings, and those choices can change. Record the raw observation and client version before labeling a value as browser-like or library-like. Avoid copying exact browser values from an undated fingerprint list into a permanent rule.

TLS has the same boundary. A JA3 or JA4 value can help expose a disagreement with the declared client, but it can be shared, changed, or imitated. TLS fingerprinting explained covers the collection and normalization details.

Browser environment

Page JavaScript can inspect a browser's reported environment. Start with coarse, explainable fields that support an actual consistency check. This minimal sample can be run on a staging page or in the browser console:

const sample = {
schemaVersion: 1,
observedAt: new Date().toISOString(),
userAgent: navigator.userAgent,
webdriver: navigator.webdriver,
languages: Array.from(navigator.languages).slice(0, 8),
platform: navigator.userAgentData?.platform ?? navigator.platform,
hardwareConcurrency: navigator.hardwareConcurrency ?? null,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
viewport: { width: innerWidth, height: innerHeight },
coarsePointer: matchMedia("(pointer: coarse)").matches,
};

console.log(JSON.stringify(sample, null, 2));

The output is a lab record, not a score. A narrow viewport on a desktop user agent can be a resized window. A surprising time zone can be travel or a privacy setting. Missing features can come from browser policy. Compare fields with one another and with later sessions before assigning risk.

Canvas, audio, font, and graphics probes expand the fingerprinting surface and the privacy burden. Do not add them merely because they are available. Document the purpose, retention, access, and deletion policy for every field you keep.

Automation and control artifacts

Browser-control protocols can create observable state, but the details are version-specific. The Chrome DevTools Protocol lets tools instrument and inspect Chromium through commands and events. Its documentation also warns that the tip-of-tree protocol changes frequently and does not guarantee backward compatibility.

The CDP Runtime domain supports evaluation and remote objects. Runtime domain documentation Frameworks expose higher-level operations on top of browser control channels. For example, Playwright's evaluation documentation separates the test process from the page's JavaScript environment and shows how page.evaluate() runs code in the page.

Treat any artifact tied to serialization, an injected property, an execution context, or a framework naming convention as a dated detector. Give it a browser version, tool version, fixture, expected result, and expiry date. When the fixture stops reproducing the artifact, retire the detector instead of assuming the automation disappeared.

Some tools exist to remove these artifacts. Playwright Stealth patches values that page JavaScript can read, while Camoufox changes them inside a modified Firefox build. Keep both kinds in your fixtures.

Session behavior

Behavior is a sequence, not a claim about how humans move. Useful observations include which resources were requested, whether navigation follows reachable links, the order of actions, repeated failures, and the time between meaningful steps.

Avoid rules such as “straight mouse movement means bot” or “fast typing means bot.” Browsers expose input APIs to automation, and frameworks can control timing. Selenium's Actions API provides virtualized pointer, keyboard, and wheel input with configurable pauses. Playwright's input documentation includes clicks, sequential key presses, delays, and programmatic event dispatch.

Legitimate readers also use keyboards, assistive technology, password managers, translation tools, and unusual navigation patterns. Prefer signals tied to the protected workflow: impossible state transitions, repeated high-cost actions, missing prerequisites, or a pace that violates an explicit route budget.

Traffic history

History can show patterns that a single page view cannot: repeated account creation, synchronized retrieval, identifier churn, or the same action spread across many sessions. It also creates the greatest risk of linking unrelated people.

Set a bounded window and a documented grouping key. Distinguish account, first-party session, source network, device evidence, and inferred cluster. Keep an “insufficient history” state. A shared IP address is not a shared actor, and a new visitor is not suspicious because the system has never seen them.

Run a controlled browser-automation lab

Test every detector against browsers and tools you approve for the lab. The first run should use default configurations; add one variation at a time only after the baseline is recorded.

Use this fixture:

  1. Create a staging page with one article link, one text field, and one submit button. Do not use production accounts or reader data.
  2. Log the HTTP request, available connection metadata, the environment sample above, and four server-recognized actions: open, follow link, enter text, submit.
  3. Run 10 clean sessions with a manually operated browser, 10 with current Playwright, and 10 with current Selenium. Use the same browser engine, operating system, network, viewport, and staging route.
  4. Use a fresh browser profile or context for each session. Randomize the order of the three client groups so time-dependent infrastructure changes do not affect only one group.
  5. Record observations without blocking. Repeat on another operating system before drawing a rule from an environment field.

The manual run is a comparison case, not “ground truth” for every legitimate reader. Playwright uses browser contexts as isolated profiles in its test model, as documented in its test guide. Selenium WebDriver is a remote-control interface for browser sessions, as described in the WebDriver documentation.

Keep one row per group and configuration:

FieldManual browserPlaywright defaultSelenium default
Test date and ownerRecordRecordRecord
Browser, tool, OS versionsRecord browser and OSRecord browser, Playwright, and OSRecord browser, driver, Selenium, and OS
Configuration and launch argumentsRecordRecordRecord
Sessions completed / attempted/10/10/10
navigator.webdriver resultsRecord counts by valueRecord counts by valueRecord counts by value
Connection and environment differencesLink raw observationsLink raw observationsLink raw observations
Four-action sequence completedRecord countsRecord countsRecord counts
Candidate signal and exceptionsRecordRecordRecord
Limitation and retest dateRecordRecordRecord

Do not publish a percentage from 10 sessions as an accuracy rate. The lab finds reproducible differences and broken assumptions. Production validation needs a larger, representative sample with reviewed labels and a measured cost for false positives and false negatives.

Turn observations into decisions

Keep classification separate from response. A useful decision record contains:

  • the protected route and action;
  • observations from each available layer;
  • the confidence and reason for the classification;
  • the selected response;
  • the rule and model version;
  • the fallback when evidence is missing;
  • the expiry or review date.

Start new signals in observation mode. Compare them with known QA traffic, approved monitoring, reader sessions, and confirmed abuse. A detector that only works against the default configuration in the lab should remain a weak signal.

Choose the response by risk:

SituationPossible responseGuardrail
Low-risk public article, weak or conflicting evidenceAllow and observeDo not interrupt the reader for one anomaly
Interactive route, several independent concernsStep up with a bounded challenge or re-authenticationPrevent loops and provide an accessible fallback
Expensive action exceeds an explicit account or session budgetRate-limit that actionUse a strong key and return a documented retry path
Restricted action lacks authorizationDeny in the applicationAutomation classification never replaces authorization
High-confidence abusive sequence with reviewed evidenceBlock the scoped action or sessionLog the reason and keep a fast rollback

Monitor challenge completion, reader errors, action success, response codes, and rule reasons after rollout. Break results down by route and client cohort. If a browser update changes a signal, move the affected rule back to observation until the lab is repeated.

For non-browser crawlers, choose controls that fit the client instead of forcing a browser detector onto it. How to block AI crawlers covers robots.txt, verified-client rules, rate limits, authorization, and rollout safety.

If this lab is part of a vendor evaluation, run the same traffic sample through the checklist above so identity, reader impact, integration, and rollback are tested together.

Before evaluating Centinel on this workflow, review the integration options. Ask which observations are available, where the decision runs, how missing evidence is handled, and how a rule is rolled back. Do not assume a browser probe protects a direct API request or that every connection fingerprint describes the visitor's connection to your origin.

If your team needs to establish which automated traffic reaches the affected pages before choosing controls, request a site audit.

What gets past your existing CDN?

You have a detection checklist. Now test your current protection. Request a free site audit: we run real scraping tools against your site, review the results, and email you the report. Your existing CDN stays in place.

Request a free site audit

Sources