All articles Bot detection

Camoufox Detection: Catching Firefox-Based Anti-Detect Automation

Camoufox is an open-source anti-detect browser built on Firefox and driven through Playwright. It’s popular with scrapers and account farmers for one reason: it doesn’t spoof fingerprints the usual way. Instead of injecting JavaScript that overrides navigator.platform or the WebGL renderer after the page loads, it changes those values inside the browser’s own C++ implementation. To the page, every property looks native, because it is.

That defeats a whole class of checks. Here is what still works, and how to layer it.

What Camoufox does

From its documentation, the main features are:

  • Engine-level fingerprint injection. Navigator properties, screen and window metrics, WebGL parameters, fonts, audio, locale and timezone are set in the engine, per profile.
  • Realistic fingerprint generation. Profiles are sampled to resemble real-world device distributions instead of random combinations.
  • Isolated automation. Playwright’s page scripts run apart from the page’s own JavaScript, so the usual automation leftovers are harder to observe.
  • Humanized input. Optional cursor movement that follows human-like paths.
  • Firefox only. It presents itself as Firefox, since posing as Chrome from a Gecko engine would contradict itself in countless ways.

The design goal is a browser that looks like a different, ordinary Firefox user every time. That’s the property you have to work around.

Why the usual checks miss it

Most stealth detection looks for the seams left by JavaScript patching: getters that aren’t native, Function.prototype.toString output that gives away an override, properties defined on the wrong prototype, navigator.webdriver hacks. Camoufox doesn’t leave those seams, because no JavaScript patches are involved.

So the question changes. It stops being “has this property been tampered with?” and becomes “could a real device actually produce this combination of values?” Detecting anti-detect browsers covers that shift in general. Camoufox is the strongest case for it.

Lever 1: consistency across signals

An engine can report any value it likes. It can’t change the hardware it runs on or the operating system underneath. Every spoofed profile is a set of claims, and the reality underneath sometimes contradicts them.

  • Claimed GPU vs rendered output. The profile can report a consumer GPU on Windows while the actual rendering comes from whatever the host machine has. Often that’s a server or VM with a software renderer. The renderer string says one thing, and the pixels and precision of real drawing operations say another. Detecting canvas spoofing explains how rendered output carries the real hardware’s signature.
  • Claimed OS vs platform behavior. Font rendering, available system fonts, scrollbar metrics and certain media capabilities differ between Windows, macOS and Linux. A Windows profile running on a Linux host has to fake all of them consistently, and gaps show up at the edges.
  • Claimed resources vs measured performance. A profile might report eight cores while timing behavior suggests a constrained container.
  • Locale, timezone and IP location. Camoufox can align timezone and locale with the proxy it uses, so this check is weaker against it than against cruder tools. When the alignment is off, it’s a clean signal.

Prynt’s tampering signal covers part of this list: a user agent that disagrees with the platform or with Client Hints, a software GL renderer under an ordinary user agent, a GPU string that doesn’t fit the reported CPU architecture, and canvas reads that disagree with each other. It returns those as flags with an anomaly score. A timezone or locale that doesn’t fit the IP surfaces separately as locationSpoofing, and a virtualized environment underneath as virtualMachine. None of them is a “Camoufox detected” flag. Each says that this device’s story doesn’t hold together, and the other checks in the list above are ones you can add in your own analysis.

Lever 2: TLS versus the claimed browser

Camoufox is real Firefox, so its TLS ClientHello looks like Firefox, and a JA4 fingerprint will agree with a Firefox user agent. That’s the honest starting point: JA4 won’t catch Camoufox on its own the way it catches a Python HTTP client claiming to be Chrome.

JA4 still earns its place in three ways:

  • Engine family. A session whose JavaScript environment claims Firefox while the TLS handshake comes from a different stack is mixing tools, which is common when a farm drives the browser for one step and a lighter HTTP client for the rest.
  • Version drift. Anti-detect builds track particular Firefox releases. A user agent claiming a version whose TLS behavior or feature set doesn’t match what the engine actually supports is a mismatch worth weighting.
  • Clustering. Many “different” devices sharing one uncommon handshake through the same proxy network is a fingerprint of the operation, not of any one device.

Prynt reports this through the tlsFingerprint signal and the TLS_AUTOMATION reason code when the handshake points to automation. TLS fingerprinting with JA4 covers how the fingerprint is built.

Lever 3: behavior

Spoofed hardware doesn’t type or scroll. Even with humanized cursor paths, an automated session has to fill forms, wait for elements and navigate, and it tends to do so with a rhythm real people don’t have: consistent dwell times, perfectly paced keystrokes, no hesitation before the password field, no idle moments. Behavioral signals score that interaction, and AUTOMATION_BEHAVIOR shows up in the reason codes when it looks scripted. Prynt’s form protection (protectForm) adds signals specific to forms for signup and contact pages.

Behavior is the most expensive lever for the attacker to defeat, because faking it convincingly means slowing the whole operation down to human speed.

Lever 4: the operation, not the device

Here’s the uncomfortable truth: a well-configured Camoufox profile will sometimes pass every per-session check. Accept that, and look one level up. Anti-detect tools exist to make each account look like it came from a new device, and that produces patterns no single profile reveals:

  • A stream of brand-new visitorIds, each with exactly one account in accountsOnDevice.
  • Signups clustered in time, through the same residential proxy provider or ASN.
  • Shared JA4 values and similar behavioral timing across supposedly unrelated devices.
  • Identical post-signup behavior: same first actions, same pages, same API calls.

That’s the domain of fraud ring detection and velocity rules rather than device fingerprinting alone. A useful rule of thumb: when per-device recognition is being actively defeated, shift weight to network signals (residentialProxy, datacenter) and to what new accounts do in their first hour.

Putting it together

A practical stack for flows where Camoufox shows up, such as signup, promo redemption and scraping-heavy endpoints:

  1. Identify on the action, then verify server side by requestId.
  2. Weight tampering, virtualMachine, TLS_AUTOMATION and AUTOMATION_BEHAVIOR heavily together, and lightly alone.
  3. Challenge instead of blocking on single signals. A proof-of-work challenge() costs a farm real compute at scale and costs a person nothing.
  4. Watch the cohort. Alert when new-device signups from one network or one JA4 spike, even if each one passed.

Anti-detect tooling moves fast, and any single check will eventually be patched. The layers above hold up because each one forces the attacker to give up speed, money or scale. To see how your own browser scores on these signals, try the playground, and see bot detection for how the signals combine into a decision.

Try it free

Prynt is device intelligence with a free tier — visitor IDs, bot & fraud Smart Signals, and behavioral biometrics, powered by a cross-site network. Start free.

Keep reading