What Apostate changes
Each launch presents one composed machine of a persona, the platform you choose. TheUser-Agent and Sec-CH-UA-* headers, navigator, navigator.userAgentData, the screen and the WebGL renderer all describe the same Windows, macOS or Linux machine, so the checks a backend runs between headers and JavaScript agree. A seed selects the machine, and a run with the same seed presents the same values. Host mode (fingerprint="host") presents the host’s own values from the same browser build, which gives you a baseline. Personas lists every value a persona sets.
Set up
apostate fonts install windows is for Linux and macOS hosts (Fonts). The folder holds two files:
signup_site.pyserves a signup page on127.0.0.1. The page’s own script collects a probe and posts it with the form. The server appends the request headers and the probe toout/visits.jsonl.compare.pysubmits the form once per run and prints what the server recorded.
The probe
The page reads values that bot protection scripts commonly read:The runs
compare.py launches one browser per run, fills in the form and waits for the server’s answer:
Run it
- Every persona passes every check. Its headers and its JavaScript values name the same platform.
- Seeds 42 and 7 are two different Windows machines, with different memory, screens and GPUs.
- The
hostrow is the Mac itself. Headless host mode reports Chrome’s headless 800x600 screen with no taskbar, and the last check flags it. A persona reports its own screen in headless mode too. - Core and memory counts depend on the host as well as the seed. The host cap explains how.
out/visits.jsonl is one signup as your backend would log it. The windows-42 record:
architecture is arm because a Windows or Linux persona reports the host’s CPU architecture, and this host is an Apple silicon Mac. No real Windows machine pairs arm with a desktop Intel GPU, and some detectors flag the pair. To test a Windows persona without it, run the script on an x86-64 host. ARM hosts covers the gap.
Test your staging site
Pass your own page with--url. The script opens it once per run with ?run=<name> added to the URL, waits until the network is idle so that your detection script has run, and prints the time in UTC and what the browser presented:
run parameter or its time. Read the score, the bot flag and the rule that fired for each visit, and compare the persona runs with the host run. Runs start 10 to 15 seconds apart. --delay changes the 10 seconds.
--url only loads the page. To submit your real form, copy sign_up() and change its selectors to your form’s, with a test address your backend can clean up.
Cloudflare Turnstile’s test sitekey
1x00000000000000000000AA passes every browser, and 2x00000000000000000000AB fails every browser. To see how Turnstile treats a persona, use your real sitekey on a staging hostname that you added to the widget.Points for this job
- Seeds. Fixed seeds make each run repeatable, so a change in your rules shows as a different verdict for the same machine. To sample new machines instead, leave out
fingerprint, and each launch draws one. Seeds and identity covers both. - Proxies. These runs come from
127.0.0.1or from your own network. Bot protection scores the IP address too (Detection). To include it in a test, addproxyto a run and removeREGIONfrom its launch, so the package sets locale and timezone from the proxy’s exit. Proxies covers proxy URLs. - Behaviour.
page.fill()andpage.click()send input with no mouse path and no typing rhythm. A product that scores behaviour sees that. Detection covers what is up to your script. - Headless or headed. The runs are headless, the packages’ default. On a Linux server,
headless=Falseneeds Xvfb installed (Linux servers). - Public test pages. Verify lists public pages that report what a detector sees.
- Measured results. Latest results has the dated results of Apostate’s test suite per host, public detector pages included. Measure with FingerprintJS Pro reads that detector’s suspect score and flags for a persona.