← All reports

Detection run, August 2026 - one of the four checks blocked us

12 min read detection-reportwhoercreepjsdatadomekasadaplaywright-stealth

This is the first of a monthly series. The point of publishing it is that it is dated and repeatable, not that it is flattering. One of the four checks blocked us, and that is in the table with the rest.

Conditions

Run started 2026-08-02 00:18 UTC
Run finished 2026-08-02 00:21 UTC
Kernel Chrome 150
Profile freshly created, default settings, nothing tuned
Proxy managed residential, exit 149.52.102.108, Houston US
Host macOS, headful

The profile was created and used once. No warming, no history, no per-site tuning. That is deliberately the weakest realistic case.

What the profile presented

User-Agent    Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/150.0.0.0
platform      Win32
languages     en-US, en
timezone      America/Chicago
webdriver     false
hardware      8 cores, 16 GB, 1536x864
WebGL vendor  Google Inc. (Intel)
WebGL render  ANGLE (Intel, Intel(R) UHD Graphics 620 Direct3D11 vs_5_0 ps_5_0, D3D11-27.20.100.9316)

The proxy exits in Houston and the browser reported America/Chicago. That binding is automatic, and it is the single most common thing to get wrong by hand.

Results

Check Result Detail
whoer.net Pass Disguise 100%. Proxy: No. Anonymizer: No. Blacklist: No. OS read as Win10.0, browser as Chrome 150.0
CreepJS Inconclusive Page loaded (HTTP 200) and produced a fingerprint ID, but our harness failed to read its score fields. Our fault, not a result
DataDome (leboncoin.fr) Blocked HTTP 403, CAPTCHA challenge served, 1,206-byte body. No listings reached
Kasada (footlocker.com) Pass HTTP 200, real storefront rendered, 1.59 MB body, no interstitial

The obvious question about that table is what the free alternative scores on the same checks. We measured that later in the month, against the same targets through the same proxy, and it is in the "Baseline" section at the bottom of this page.

An incidental observation: STUN did not resolve

Not one of the four checks, but it showed up in the kernel log repeatedly during the run and is worth recording:

Failed to resolve address for stun.l.google.com., errorcode: -105

STUN resolution failed through this proxy for the whole session, so WebRTC gathered no server-reflexive (srflx) candidate. That is not a leak, which is the failure mode people usually worry about, and it is not a clean pass either. A browser that produces no srflx candidate at all is its own small signal, and we are recording it rather than filing it under "no WebRTC leak detected".

We did not design the run to measure this and have not characterised how often it happens, so treat it as an observation, not a result. It is on the list for the September run.

Update, 2026-08-13: that observation did not survive being measured. The harness now probes WebRTC deliberately instead of reading the kernel log, and on every run since, the browser did gather a srflx candidate and it was the proxy exit address, with the host's own address appearing nowhere. The resolver error still shows up in the log. Whatever it costs, it is not the absence of a candidate, so treat the paragraph above as describing one session rather than this proxy in general.

About the DataDome failure

Read that row again, because it is the interesting one.

leboncoin.fr returned 403 with a CAPTCHA. The profile did not get through. A previous capture of this same target, taken weeks earlier and still shown on our homepage at the time of writing, showed it passing. Today it does not.

We went and measured it rather than leaving it at a guess. The rerun at the bottom of this page put twelve exit addresses through the same target on 2026-08-13, our kernel and a stealth-plugin Playwright paired inside each address neighbourhood: the exit address decided five rounds out of six, and the browser decided at most one. The general answer is that a 403 here is first a question about the address and only after that a question about the browser.

What that does not do is explain this particular run backwards. A different address in the same 149.52.* block passed eleven days later, so we cannot point at the address we used on 2026-08-02 and call it burned. The observations below are what we could honestly say at the time, before any of it was measured, and they stay as written:

What we can say is narrower and more useful: the fingerprint layer looked coherent (whoer 100%, proxy undetected, no automation tells), and one commercial wall let it through while another did not.

The CreepJS gap, and a correction to what we first said here

CreepJS loaded and returned a fingerprint ID, so the browser reached it. Our extraction script failed to pull the score fields out of the rendered page, so we have no numbers to publish and we are not going to estimate them.

The first version of this page called that a harness bug and said it would be fixed for the September run. That was too confident, and this is the correction. We went and tried. The extraction was genuinely wrong, CreepJS renders its scores into shadow roots rather than the document body, but fixing that exposed a larger problem: on our test host, CreepJS reliably takes the renderer down with it, and when the renderer dies the debugging connection and the whole run die too. Nine attempts, several distinct failure modes, no numbers.

CreepJS now runs in its own isolated invocation so that when it crashes it costs only itself instead of every check after it. Whether we can capture its scores at all in September is genuinely open. If we cannot, that row will say so again rather than quietly disappear.

Method, so you can repeat it

  1. Create a profile in the desktop app or via openProfile(). Change nothing.
  2. Bind a residential proxy. Timezone, locale and geolocation follow the exit IP automatically.
  3. Open, in one session: whoer.net, abrahamjuliot.github.io/creepjs, leboncoin.fr, footlocker.com.
  4. Record HTTP status and the on-page result for each.

Every target is public and none of them require our cooperation. The free tier is unlimited local profiles with no card, so running this yourself costs an afternoon.

If your result differs from ours, ours is the one to distrust: we ran one profile through one proxy from one machine.

What we changed because of this run

Our homepage carries a DataDome screenshot from an earlier capture showing a pass, and this run contradicted it, so we labelled that screenshot as stale and pointed it here.

We have since put the label back to a plain pass, and that deserves an explanation rather than a quiet edit. The rerun at the bottom of this page found the exit address deciding five rounds out of six, with the same address blocking both browsers and a different address letting both through. Under that reading, one 403 from one address is not evidence that the capture was wrong, and marking it stale implied a certainty in the other direction that we did not have either. The screenshot still shows one good day, and it still links here.

Reproduced later the same day

We re-ran the same profile and proxy against the same targets a few hours after the run above. whoer returned 100% disguise again, and leboncoin.fr returned 403 with a CAPTCHA a second time. A twice-reproduced block on the same day with the same exit IP is weak evidence about DataDome in general and reasonable evidence that this specific result was not a fluke.

The repeat run did not finish: the Kasada target, which completed in the first run, took the process down in the second. These pages are heavy and our harness is not yet robust against that. Recorded here because a report that only mentions the runs that worked is the thing we are trying not to publish.

Baseline: playwright plus a stealth plugin

The comparison worth publishing is not another paid vendor. It is Playwright with a stealth plugin, which is free, and which is what most people weigh us against. So we ran it through the same four checks.

This part was measured on 2026-08-13, not on 2026-08-02, so it does not compare with the table above. It compares with itself.

Both arms ran on the same host, minutes apart, through the same residential exit. The stateless checks are below; DataDome needed a different design and has its own section after it.

AntiBrow Playwright + stealth plugin
Engine our kernel, Chrome 151 Playwright's bundled Chromium, Chrome 148
Fingerprint applied in the engine from injected JavaScript
whoer.net disguise 90% 90%
whoer read the OS as Win10.0, matching the UA Mac OS X, the host
whoer proxy detected No No
Kasada (footlocker.com) Pass, 200, storefront rendered Pass, 200, storefront rendered
WebRTC srflx candidate the exit address 202.66.x.x, the host's own address
Timezone vs exit America/Los_Angeles, matches Asia/Shanghai, the host's
navigator.languages en-US, en zh-CN, zh, the host's

Whoer's headline number did not separate them, and Kasada let both through. If you came here for a chart where the paid product passes and the free one fails, this is not it.

The separation is in the bottom three rows, and it is not a score, it is coherence. The baseline announced a Las Vegas exit address while reporting the timezone of a machine in Asia, the language of that machine, and a WebRTC candidate carrying its real address. Any one of those is a single query for a site that cares. The plugin did its job, which is hiding the automation tells: webdriver was false and whoer read it as an ordinary Chrome on macOS.

One detail says the rest. whoer served the baseline its Chinese page, because Accept-Language was the host's. We noticed because the score extraction, which looks for the English label, came back empty.

What this does and does not show:

The exact packages: playwright-extra with puppeteer-extra-plugin-stealth, current versions, default configuration, headful, same residential exit.

DataDome needed a different experiment, and the first one was wrong

DataDome is stateful per exit address, which makes it the one check that cannot be run the way the rest of this page was run. Our first attempt put both arms through the same exit a few minutes apart, both were blocked, and we nearly published that as a tie. It is not a result: the second visitor from an address that has just been used on the same target is in a different situation from the first, and a shared address also means a shared reputation, so a single bad address blocks both arms and looks like agreement.

The redesign, one round per address neighbourhood:

Six rounds, twelve addresses, leboncoin.fr:

Address block AntiBrow Playwright + stealth
149.40.* Pass Pass
149.87.* Pass Pass
149.52.* Pass Pass
149.88.* Pass Pass
148.135.* Blocked Blocked
192.200.* Pass Blocked
5 / 6 4 / 6

The address decided five of the six rounds, and the browser decided at most one. Five pairs agreed with each other and disagreed with each other's neighbourhoods. One pair split, in our favour. One split out of six is not evidence of anything; if we published 5/6 against 4/6 as a win, the next round could reverse it and we would deserve to be quoted on it.

What this does establish is the thing worth knowing before you spend a day debugging a fingerprint: on this check, the exit address dominated everything else we varied. A 403 with a CAPTCHA is first a question about the address, and only after that a question about the browser.

Two limits on reading it further. This is the homepage only, and login, search and checkout endpoints are scored far more harshly. And the baseline here is Playwright with the stealth plugin, which specifically hides the automation tells; unpatched automation is a weaker opponent and would not have done this well.

A note on our own number

Our arm scored whoer 90% on 2026-08-13 and 100% on 2026-08-02. Same product, different exit address, and the baseline scored the same 90% through that same exit on the same afternoon. We do not know which check whoer docked, and we are not going to guess at it in a direction that flatters us. It is the reason this series publishes the exit address next to the score.

The kernel also differs between the two runs, Chrome 150 in August and Chrome 151 in the baseline pair, because new profiles bind to the newest published build rather than a frozen one.

Next run: 2026-09-01. Same method, now with the baseline arm alongside. CreepJS isolated so it cannot cost the other checks, and no promise that it will produce a number.

See what a profile actually is or check yours against the same list.

How to cite this run

The results on this page are CC BY 4.0. Attribution is the licence condition, and a link is how attribution is normally given - so here it is, ready to paste.

AntiBrow, “Detection run, August 2026,” 2026-08-02.
<a href="https://antibrow.com/reports/detection-2026-08">antibrow.com/reports/detection-2026-08</a>
(CC BY 4.0)
AntiBrow. Detection run, August 2026 (2026-08-02). https://antibrow.com/reports/detection-2026-08. CC BY 4.0.
@misc{antibrow_2026_08,
  title  = {Detection run, August 2026},
  author = {AntiBrow},
  year   = {2026}, month = {8},
  url    = {https://antibrow.com/reports/detection-2026-08},
  note   = {CC BY 4.0}
}
Machine-readable JSON CSV Method

Both files are served with Access-Control-Allow-Origin: *, so they can be fetched straight from your own page.

Try it on the free tier.

Unlimited local profiles, no credit card. Check it against the detectors yourself.