mpm
← the blog
// Security research

Reversing anti-botting solutions has never been easier. Is PACT the solution?

June 2026

PACT, a new proposal from Cloudflare and the major browser makers, says inspecting browsers to catch bots has failed. A recent vendor, TrustSig, bets the other way. I reverse-engineered its SDK to see how much weight fingerprinting can still carry.

The admission behind PACT

Cloudflare, Mozilla, Google, Microsoft, and Shopify announced PACT, short for Private Access Control Tokens. Automated requests are now roughly 58 percent of HTTP traffic against 42 percent from people, and sites respond with paywalls, identity checks, and fingerprinting that all cost real users something. Mozilla’s Bobby Holley put the premise plainly: “An avalanche of automated traffic is pushing sites to adopt blunt defenses.” The notable part of PACT is its starting position: it assumes that inspecting clients to tell humans from bots has failed, and that the inspection itself harms privacy. With the largest browser vendors signed on, this is the browser industry saying it wants to stop fingerprinting.

A website that already knows a visitor’s identity issues an anonymous token; the browser presents it to other sites as proof that a real person is behind the session, which removes repeated identity checks. PACT does not try to block automation. It separates authorised agents from malicious scrapers, on the premise that many AI agents have a human in the loop with a legitimate reason to visit a site.

This article is based on Mozilla’s sketch of a theoretical PACT design, not a shipped product or a ratified standard.

How PACT differs from fingerprinting

PACT builds on the IETF Privacy Pass work and the Private Access Tokens already deployed by Apple and Cloudflare. It moves the trust decision off the request and splits the work across three roles. An anchor vouches for a user from a scarcity signal it already holds: a subscription, a verified account, a phone number. It issues an endorsement, and the user redeems that endorsement at a moderator, which hands back a credential: a stateful token scoped to that moderator, carrying a hidden counter rather than any identity. The browser then presents a credential to a site, which often is its own moderator, and the site learns only whether the credential is valid and under its rate limit. The browser is never inspected at request time, and blinding hides the path: the moderator learns only that an endorsement came from one of the anchors it trusts, not which one, and successive credential presentations cannot be tied to each other or to the original issuance.

Sequence diagram of PACT as Mozilla describes it: an anchor issues an endorsement to the browser from a scarcity signal, the browser redeems it at a moderator for a stateful credential, then presents a credential to the site, which learns only that it is valid and under the rate limit; blinding keeps issuance and use unlinkable
PACT as Mozilla sketches it. An anchor vouches for a user from a scarcity signal and issues an endorsement; a moderator exchanges that for a rate-limited credential; the site learns only that a valid credential is present and under its limit. Blinding keeps issuance, moderation, and use unlinkable.

Whether this is more private than fingerprinting depends on the axis. On cross-site tracking PACT is the more private design. A fingerprint is a stable, high-entropy identifier any site can recompute and correlate; a blinded token carries no device entropy and cannot be linked between issuance and use, so the origin learns one bit instead of a profile. The anchor gains little either, since it already knew the account existed, and blinding hides which site redeems the credential. The costs that remain are not tracking but dependency and centralization: a client needs a relationship with an accepted anchor, and clients that lack one or decline one, including uncommon platforms and users who refuse on principle, get pushed toward the bot bucket. Privacy Pass itself was created partly to help these users, letting a Tor Browser session clear gates without endless CAPTCHAs. The catch is that the user still has to hold a credential from an anchor, and obtaining one, a subscription, a verified account, a phone number, can reattach the real-world identity that Tor exists to shed.

The two approaches also claim different things about human presence. Fingerprinting detects whether a real browser ran, not whether a person is there. PACT carries proof that someone vouched for the user, and is only as strong as that vouching. Under Mozilla’s design the vouching is a scarcity signal, a paid subscription, a verified account, a phone number, things that are awkward to amass by the thousand but not impossible. Apple’s deployed Private Access Tokens go further and bind the token to Secure Enclave hardware, which is harder to forge but puts the device manufacturer in the loop. Either way it is a proxy, not a liveness check, though a stronger one than a fingerprint.

DimensionClient-side fingerprintingAnonymous credentials (PACT)
What it determinesWhether the client resembles a genuine browserWhether the user holds a valid credential under the rate limit
Source of the signalDevice and browser entropy observed at request timeA scarcity signal (account, subscription, phone) an anchor already vouched for
What the origin learnsA stable, high-entropy device fingerprintOne bit: a valid credential below the rate limit, or nothing
Cross-site linkabilityHigh; the fingerprint is a shadow identifierLow; credentials are unlinkable across sites and back to issuance
Who decides legitimacyThe site, or the anti-bot vendor it embeds, which can score across its customersAnchors vouch; moderators set and enforce the rate limits
Central observerA shared anti-bot vendor, present on many sites, can re-identify the same device across all of themA moderator, but it adjusts a credential without learning what it is or where else it is used
Typical false positivesPrivacy-hardened or uncommon real browsersUsers with no anchor relationship, or who decline one
Establishes human presenceNo; certifies browser authenticityIndirectly, only as well as the anchor’s scarcity signal tracks a person; not a liveness check
Who knows what about you under fingerprinting versus PACT's anonymous credentials
What the website, any other website, and a moderator or anchor learn about a visitor under client-side fingerprinting and under PACT’s anonymous credentials.

A separate trend works against the fingerprinting column. The stable, high-entropy fingerprint that client-side detection needs is getting harder to collect, because browsers are suppressing it on purpose. Safari injects noise into 2D canvas, WebGL, and WebAudio readback, restricts fonts, and freezes most User-Agent detail. Firefox randomizes canvas readback and blocks known fingerprinters. Brave farbles canvas and Web Audio with a per-session seed. Tor Browser gives every user one uniform profile. Chrome has reduced User-Agent entropy. The fingerprint has high entropy in theory and shrinking entropy in practice, and the same suppression pushes privacy-conscious real users toward the bot bucket, the bind Mozilla’s writeup concedes: the better a user protects their privacy, the more easily a site mistakes them for a bot. The companies doing this, Apple, Mozilla, Google, and Microsoft, are largely the same ones behind PACT and its Private Access Token predecessor: removing the data fingerprinting needs and offering an attestation they control instead.

Who gets to be an anchor

PACT’s assurance is only as strong as whoever vouches for the user, and Mozilla is deliberate about what that vouching rests on. It rejects device attestation, the model behind Apple’s Private Access Tokens, precisely because that rests on “parts of a user’s device that sit within the manufacturer’s control.” In its place, parties Mozilla calls anchors vouch from scarcity signals like a subscription, a verified account, or a phone number, and the credential stays unlinkable from issuance to use.

Avoiding hardware attestation dodges the manufacturer dependency, but not concentration. The parties that can vouch for many users at scale are the same large platforms that already hold the accounts and phone numbers, and PACT’s authors say as much: covering many sites “carries a centralisation risk, similar to the concentration we see today in anti-abuse providers.” Their mitigation is to leave the choice of anchors with each site rather than mandate a list, which does not reverse the web’s existing concentration. Who gets to vouch, and with what recourse for a new entrant, is the governance problem underneath the protocol, at least as hard as the cryptography.

TrustSig enters

TrustSig is a privacy-forward bot-defense platform: invisible protection built in the EU, marketed as “zero challenges, zero cookies, and no fingerprint profile of your visitors,” on “stateless hardware signals” and GDPR-aligned, EU-hosted infrastructure. It chases the same privacy goal PACT does, by the opposite route: PACT never inspects the client, while TrustSig inspects it, computes a device fingerprint, and folds the result into a sealed token. It makes a good concrete example, because everything below was recovered from its public client.

What sent me to TrustSig was a bolder, separate claim in its post “Reverse Once, Run Forever”: that this client-side detection holds up even against an attacker who fully understands it, so that “full understanding buys the attacker nothing durable.” I went in out of genuine interest, not to take the platform down. The design is clever, and the further I pulled it apart the more I wanted to understand how the pieces fit. The claim is also strong and testable, and the SDK is served publicly, so I took it up. Sources and a disclosure are at the end; the work used only publicly available material.

TrustSig draws the privacy line in a particular place. Its EU-CAPTCHA page says it evaluates “hardware-level signals, not identities,” that “no name, email, IP profile or cross-site identifier is processed,” and that the signals are “ephemeral and non-identifying” and “cannot be reversed into a natural person, so they do not constitute personal data under the GDPR.” The no-cookies, no-PII part holds, and I do not dispute the GDPR posture.

What is harder to square is “non-identifying.” TrustSig also ships a device-fingerprint tool whose whole purpose is to show how stable those same hardware signals are: “the same ID appears in incognito, in private windows, and across most browsers on the same machine,” and “a VPN changes your IP address, not your device fingerprint.” A signal that reproduces the same ID across browsers and private windows is a persistent identifier. “Ephemeral” describes how it is handled, that nothing is stored, not whether it can pick out a device; it does not need to be stored, because it can be recomputed on demand. A stable fingerprint is precisely the cross-session, cross-site identifier the browser vendors are working to suppress. TrustSig says it does not use it that way, that you are “protected, never the product.” Based on the reversing, that is a promise you take on trust, not something the design prevents.

TrustSig can read the token even though the website cannot, because it is sealed with TrustSig’s own keys and reaches its edge at verification. So TrustSig holds a derived representation of the device, and if that representation is stable, TrustSig, which sits on every site that embeds it, can recognize the same browser across all of them and tie your login on one site to your login on another. That is the cross-site tracking “no fingerprint profile” is meant to rule out, and TrustSig’s design makes it available even if it never uses it. PACT’s blinded tokens are unlinkable by construction, so no party can tie one visit to another. TrustSig could; PACT cannot.

A detailed flowchart of the TrustSig token-construction pipeline recovered by reverse engineering: handshake and session-key derivation, a server-driven challenge VM that collects GPU, navigator, screen, network, and behavioral signals, per-component reduction to fixed-width scalars by keyed hashing, packing into a register vector with an integrity digest, encryption with the session key, and a server-side verify that returns allow or block
The TrustSig token-construction pipeline, recovered by reverse engineering and shown redacted: handshake, a challenge VM that collects device and behavioral signals, reduction of each component to a fixed-width scalar by keyed hashing, encryption with the session key, then server-side verify. The point of showing it is the completeness. This much detail was recoverable from the public client.

The claim I tested is the other one, about durability. “Reverse Once, Run Forever” argues that client-side detection can be made durable through cryptographic design instead of secrecy, so that “even full understanding buys the attacker nothing durable.” The asymmetry is real: client code runs on hardware the attacker controls, so hiding logic cannot work. In place of secrecy the post leans on a moving-target build, sealing decisions instead of branching on them, minting sensitive tables on the server per session, and refusing to trust offline work. The aim is to make reverse engineering unprofitable, and so defeat the pattern in the title: reverse the detector once, then run an offline replica forever.

What the reverse engineering found

I deobfuscated the loader, iframe, core, and worker scripts. I recovered the WASM-backed string tables by executing the genuine code. I decompiled the WebAssembly module and catalogued its 41 environment probes. The build follows a fairly standard pattern for anti-bot platforms.

Component observedPublicly observed practice
Obfuscated loader: string-array, property, and numeric decoders, with per-build identifier renamingoutput typical of javascript-obfuscator and similar tools
Loader behavioral capture: pointer, keyboard, and touch listeners with telemetry beaconspassive behavioral collection, publicly associated with HUMAN, Akamai, and reCAPTCHA v3
Hidden iframe with a postMessage RPC bridge (INIT, SCAN, CONTVM)publicly observed in reCAPTCHA, hCaptcha, Turnstile, and DataDome
Rust and wasm-bindgen WebAssembly moduleWASM modules are widely reported across the field, for example Kasada, DataDome, Akamai, and HUMAN
Server-driven challenge VM (decide(prog, regs), a per-session program)publicly documented examples include Kasada’s ips.js and Akamai’s sensor_data, among a long interpreter-challenge lineage
Canvas, WebGL, and audio fingerprinting (toDataURL, readPixels, UNMASKED_RENDERER, OfflineAudioContext)the FingerprintJS-era signal set
navigator, screen, instanceof Window, webdriver, and software-renderer probesthe standard automation tells
AEAD transport, rolling keys, single-use nonce, origin allowlistconventional authenticated transport and origin binding

Generating a token by running the client

None of that reverse engineering was needed to generate tokens. The procedure runs the vendor’s own client in a real browser on an allowed origin and reads the token it issues, treating the client as a black box.

# Schematic. Not runnable code. Operational details are omitted on purpose.
function get_token(site_key, build, origin):
    browser = open_real_browser(origin)            # real GPU, an origin the site key allows
    client  = browser.load_vendor_sdk(origin, build)   # fetch and run the genuine client script
    client.init(site_key, origin, wasm_url)        # the SDK runs its own server handshake
    client.scan()                                  # the SDK's WASM fingerprints the real browser
    return client.read_issued_token()              # the header value the SDK produces

A working bypass is not the objective here, and the implementation is withheld. The steps need no understanding of the client, only the ability to run it. Depending on the attacker’s objective, that can already be a sufficient harness for abuse: the browser mints valid tokens, and those tokens can be carried into whatever context the attack runs in.

I measured this against a live endpoint. I minted twenty tokens in sequence in one browser and posted each to POST /api/auth/login.

MeasureResult
Tokens accepted20 of 20; 0 blocked; 0 errored
Generation rateabout 1.2 s per token; roughly 50 per minute generate-only, 30 per minute with verification
Negative controla missing token returns “Bot protection token missing”; garbage or one-byte-tampered tokens return “Access Denied by TrustSig (BLOCK)”; a genuine token reaches authentication

The negative control rules out a false positive: garbage and tampered tokens are blocked, mine reach auth. No human input was involved, and I stopped at twenty without pursuing scale or rotation.

A vendor could instead flag the automation itself by its tells: navigator.webdriver, an attached debugger, injected functions. I defeated none of that; the client took my tokens with no evasion. But that signal is fading. The same automation protocols now drive browser-use agents acting for a person, the exact traffic PACT wants to admit, so flagging hooked browsers flags those agents too.

What the token certifies

A TrustSig token shows that a browser-like client stack ran the client and cleared the challenge. It does not prove a real browser, let alone a person, was there, and that gap is what PACT’s backers are reacting to: client-side detection treats browser authenticity as a stand-in for human presence, and automation has pulled the two apart. Going invisible, with no CAPTCHA, also gives up the one controlled human-behavior sample a challenge would force. What narrows the gap is the behavioral signal TrustSig collects next, and it is substantial.

The behavioral channel

A second branch of bot detection watches behavior rather than the device: mouse trajectories, keystroke timing, scroll cadence. reCAPTCHA v3, HUMAN, Akamai, and DataDome all score it. TrustSig collects it too, and in depth.

The loader records pointer and keyboard activity, a worker hands it to the WASM, and the WASM turns it into the kind of motion and timing features a bot detector uses. I am deliberately not enumerating the specific features or thresholds. Each one becomes a fixed-width scalar, and those scalars are sealed into the same token as the device fingerprint.

A redacted diagram of the TrustSig behavioral signal pipeline recovered by reverse engineering: capture of pointer and keyboard events, transport through the iframe and worker into the WASM, behavioral analysis with the feature set, methods, and thresholds blacked out, and embedding into the encrypted token that the server scores
TrustSig’s behavioral pipeline, recovered by reverse engineering and shown redacted: pointer and keyboard events are captured, transported into the WASM, analyzed, and sealed into the token, which the server scores. The feature set, analysis methods, and thresholds are deliberately omitted.

This reframes the twenty-token result. My tokens carried no mouse movement and no keystrokes, which to these features is the most obvious bot there is. They were still issued and reached the application, but a token issued is not a human scored: the verdict comes later, server-side, and TrustSig may well have seen the automation and let twenty quiet requests through as not worth blocking. So the finding is narrow: a real browser can mint structurally valid tokens with no human present, cheaply and repeatably, but whether they survive TrustSig’s behavioral and volumetric scoring at scale is a question a twenty-request test cannot answer. Behavioral scoring is one strong candidate for where that pushback would come from, and probably not the only signal in play.

There is still a real tension with where PACT points. PACT is built to admit agents acting for a human, and behavior-based scoring is at odds with that: an AI assistant filling a form does not move a cursor like a person, if it uses one at all. A defense tuned to human motion flags the legitimate agent and the abusive bot alike. That problem is not TrustSig’s alone; it belongs to the whole category.

What this does and does not show

It would be easy to read twenty accepted tokens as proof that TrustSig is broken. That is not the point; the point is cost. Two things undercut the durability the post promises. First, minting tokens never required understanding the client, only running it. Second, the understanding the layered defense is meant to keep expensive, the obfuscation, the WASM, the per-session challenge program, is no longer expensive. A few years ago peeling those layers back was human labor, and that labor cost was part of the defense: rebuild often enough and reverse engineering never pays off. Generative AI removed most of it, doing the deobfuscation, string-table recovery, decompilation, and probe enumeration in hours for almost nothing. The incremental layers TrustSig adds to stay ahead still cost an attacker something, but far less than they used to, and far less than “Reverse Once, Run Forever” assumes.

What I did not do is evaluate TrustSig as a bot-mitigation product. The behavioral channel is exactly the kind of defense that catches naive automation, and twenty quiet requests are not a test of it. A vendor can see an attack, score it, and let it through, and from the outside that is indistinguishable from a miss. A handful of findings against the public client says little about how well the system protects real customers from real campaigns. Dismissing a vendor on that basis would be a mistake.

The fairer takeaway is the difficulty of the problem TrustSig has taken on: bot mitigation that is invisible, cookieless, privacy-forward, EU-compliant, and durable against an attacker who can read all of it. That is a genuinely hard combination, and the cleverness in the design, the sealing, the keyed reduction, the behavioral feature extraction, is a response to real constraints rather than marketing. The honest critique is not that this is weak. It is that the part of the pitch promising durability against full understanding does not hold, while the parts that actually protect customers, server-side scoring of device and behavioral signals, are conventional and not unique to TrustSig.

PACT, fingerprints, and the camera

Step back and the field is choosing a point on a spectrum, trading privacy and friction against how confidently a server can tell a human from a bot.

At one end is PACT and the attestation-token family. The site inspects nothing; it trusts a credential that traces back to an anchor vouching from a relationship it already had. Most private, least friction, but it leans on a few large anchors, and it answers whether a client is vouched for, not whether a human is present.

In the middle sit fingerprint systems like TrustSig and most of the incumbents. They inspect the client, but the better ones, TrustSig included, reduce what they collect to a sealed, derived representation rather than a shipped profile. More signal for the server, a genuine arms race against automation, and a privacy story that rests on trusting the vendor about what it derives and keeps.

At the far end is something like Google’s hand-gesture verification, where reCAPTCHA asks you to move your hand in front of the camera and reads twenty-one hand-landmark coordinates per frame. It is the most intrusive, it needs camera access and active participation, and Google says the video is deleted after the challenge. It is also the closest any of these comes to actually testing for a live human, because it asks for something an automated browser still cannot easily produce on demand.

Sequence diagram: the website invokes a gesture challenge, reCAPTCHA asks for camera access, the camera records the hand and extracts 21 hand-landmark coordinates per frame with no face or audio, the landmark data goes to Google which confirms a live human and deletes the video, then returns allow or block
The intrusive end of the spectrum. reCAPTCHA hand-gesture verification reads twenty-one hand-landmark points from the camera, deletes the video after the challenge, and is the closest of the three to actually testing for a live human.

There is no free option. PACT buys privacy by moving trust to anchors. Fingerprinting buys invisibility by collecting signal and asking you to trust the collector. Gesture checks buy a real liveness signal by spending privacy and friction. So is PACT the solution? It solves one face of the problem, privacy and cross-site tracking, and pays for it on another, a dependency on anchors and the unsolved question of human versus authorized agent. The others make the opposite trade. The one thing not improving for any defender is the value of a passing signal that a real browser, driven by software, can now produce on demand, which by now is most of them.

Sources

Disclosure

I am a former employee of HUMAN Security. This paper relies on strictly publicly available information: TrustSig’s publicly served code, its public endpoints, its publicly embedded site key, and the published vendor documentation cited above. I present it with no current affiliation with any party named here.

I have redacted specifics of TrustSig’s design throughout. The diagrams are shown with the feature set, methods, and thresholds blacked out, and I do not enumerate the behavioral indicators or the token internals. Despite TrustSig’s position that full understanding buys an attacker nothing durable, what the reversing recovered does reveal a great deal about how to defeat the solution. This article is about the privacy tradeoffs of bot detection. It is not a playbook for attacking TrustSig’s customers, and the operational detail is left out for that reason.