Headless Detection Is a Multi-Signal Decision#
A site cannot reliably identify every automated browser from one property. Modern systems combine signals from the browser runtime, rendered output, request metadata, TLS and HTTP behavior, navigation history, cookies, account state, rate, and interaction patterns. A defensive system can use the combined evidence to protect logins, checkout, inventory, forms, and APIs, but each signal has legitimate exceptions.
navigator.webdriver is an explicit automation indicator when present, yet its absence does not prove a human. A canvas or WebGL difference can reflect a virtual machine, accessibility configuration, privacy tool, remote desktop, driver update, or real hardware. A rare TLS fingerprint can belong to a legitimate application. Responsible detection therefore uses layered evidence, calibrated thresholds, monitoring, and a recovery path for false positives.
JavaScript and Runtime Signals#
JavaScript can inspect browser-exposed properties such as navigator.webdriver, languages, plugins, permissions, screen values, user-agent data, WebGL parameters, fonts, media capabilities, and prototype descriptors. Automation frameworks can also leave differences in error stacks, object ownership, function serialization, Chrome-specific namespaces, or the timing of injected scripts.
No individual value is universally suspicious. Plugin counts vary by browser and version. Permission behavior differs across operating systems. Privacy-focused browsers deliberately reduce or alter entropy. Enterprise policies and extensions modify APIs. The useful signal is consistency: do the claimed browser, operating system, rendering engine, feature set, and observed behavior agree with each other?
Defenders should record which checks contributed to a decision and measure their false-positive rate against real users. Avoid rules that block solely because one API is missing or unusual.
Rendering, Graphics, and Environment Consistency#
Canvas, WebGL, font metrics, emoji rendering, audio processing, CSS media queries, and screen geometry expose properties of the rendering environment. Headless or containerized sessions can produce combinations that are rare in ordinary traffic: a claimed desktop browser with no expected fonts, a GPU description inconsistent with the platform, fixed viewport values repeated across every session, or a timezone and locale that do not match the rest of the profile.
These are probabilistic signals, not identity proofs. Cloud desktops, browser isolation, thin clients, test labs, assistive technology, and hardened privacy configurations can look unusual for legitimate reasons. A diagnostic should report the inconsistency it observed rather than label the person behind it. Repeat tests across supported operating systems and accessibility configurations before enforcing a rule.
Automation APIs and Patch Side Effects#
Playwright, Puppeteer, Selenium, and Chrome DevTools Protocol clients are legitimate tools for testing and administration. Their default configurations can expose automation state, while third-party patch libraries attempt to change selected browser properties. A patch can remove one obvious marker yet introduce a descriptor, prototype, timing, or cross-frame inconsistency of its own.
Because browsers and automation libraries release frequently, results tied to one browser binary become stale quickly. A defensible test records the exact framework version, browser build, operating-system build, launch flags, extensions, profile state, and dependency lockfile. It should include an unmodified browser control and rerun after browser upgrades. Avoid permanent claims such as “undetectable” or “always detected”; the observed result belongs to the recorded configuration and date.
Network, Session, and Behavioral Context#
Browser JavaScript is only one layer. The destination can also observe TLS and HTTP characteristics, header order, protocol negotiation, connection reuse, IP network, cookie history, navigation sequence, request rate, and account behavior. A perfectly ordinary JavaScript environment does not erase contradictory network or session evidence, and an unusual browser signal does not automatically make a request abusive.
For account and transaction protection, sequence often matters more than a static fingerprint. Examples include a new session jumping directly to a sensitive action, many accounts sharing one identical client profile, impossible geographic transitions, or repeated failures at machine-like intervals. Use these signals to protect systems you operate, with documented retention, access controls, and appeal or step-up verification for legitimate users.
What CreepJS Can and Cannot Tell You#
CreepJS is an open-source browser-fingerprinting and privacy research project. It inspects high-entropy APIs, prototype tampering, browser lies, resistance features, and inconsistencies. That makes it useful for studying what a browser exposes and whether a modification created detectable contradictions.
A CreepJS percentage is not the probability that Cloudflare, Akamai, DataDome, or a particular website will block a visit. It is not a human-versus-bot probability and does not measure account, rate, navigation, or server-side history. Different CreepJS commits, browser builds, hardware, and page state can change the output. Record the diagnostic commit and raw output, and describe it as a fingerprinting observation rather than a production acceptance rate.
Build a Reproducible Defensive Lab#
Use systems and accounts you control. Define the question before running the test: which signal changed, which browser configuration caused it, and what legitimate users could share it? Pin the operating system, browser binary, framework, dependencies, extensions, flags, locale, timezone, display mode, and hardware or virtual-machine profile.
Run an ordinary supported browser as a control. Repeat every configuration enough times to distinguish stable attributes from random or session-dependent ones. Save raw diagnostic JSON, screenshots, console output, network metadata, UTC timestamps, failures, and the exact aggregation code. Use a versioned manifest with file hashes. If a diagnostic is external, record its commit or retrieval hash because the hosted page can change between runs.
Test false positives with supported accessibility tools, privacy settings, enterprise policies, remote desktops, and low-powered devices. A detector that recognizes a lab configuration but blocks many legitimate users is not a successful production control.
Interpret Results Without Overclaiming#
Report observations at the level the test supports. “This property differed from the control in browser build X” is defensible. “This library is detectable everywhere” is not. Separate a fingerprint inconsistency from a destination decision, and separate a destination decision from proof of malicious intent.
Use counts and uncertainty rather than a single winner. State the number of repetitions, failures, environments, and dates. If several configurations share the same result, do not infer that the diagnostic used the same underlying signal. If a score is undocumented, avoid reverse-engineering a precise meaning from its display label alone.
For public research, publish the harness and sanitized outputs when doing so does not expose user data or weaken a live control. Otherwise describe the evidence boundary clearly and avoid numerical rankings that readers cannot inspect.
Responsible Use#
Browser diagnostics are appropriate for QA, fraud prevention, account security, accessibility testing, privacy research, and monitoring systems you own or are authorized to assess. They should not be used to bypass a third party's access controls, conceal prohibited automation, or continue after a site has denied access.
If an authorized integration is blocked, use the provider's API, feed, allowlist, service account, test environment, or written support channel. On the defensive side, minimize collected data, document the purpose, retain it only as long as needed, and provide a lower-friction recovery path when legitimate users are challenged.



