How to Stop Bots Without CAPTCHA
Bot traffic now accounts for nearly half of all internet requests. The default answer - CAPTCHAs - is failing. Here’s a fundamentally different approach.
Want to see it in action? Try the live demo yourself. Open it in a normal browser, then try it with Playwright or Puppeteer and see what happens.

The CAPTCHA problem
CAPTCHAs were designed around a simple assumption: tasks that are easy for humans and hard for machines. That assumption no longer holds.

AI solves them. GPT-4V, Gemini, and purpose-built CAPTCHA-solving models break image and audio challenges with accuracy rates above 90%. Services like 2Captcha and Anti-Captcha offer API-based solving at fractions of a cent per challenge.
Click-farms bypass them. Cheap human labor in CAPTCHA farms solves challenges in bulk. The “human verification” literally uses humans — just not your users.
Users hate them. Every CAPTCHA is friction. Studies consistently show that CAPTCHAs reduce conversion rates, hurt accessibility, and frustrate legitimate users. You’re punishing real customers to slow down attackers who have already found workarounds.
The fundamental issue: CAPTCHAs challenge the user. But the user isn’t the problem - the runtime environment is.
A different question
Instead of asking “Are you human?” you can ask a better question:
“Did this request come from a real, untampered browser?”
This is the idea behind runtime attestation. Rather than interrupting the user with a puzzle, you silently inspect the environment where the request originates. A real browser running on a real device has properties that are structurally difficult to fake - especially when the inspection happens inside an isolated execution context that the attacker cannot easily observe or manipulate.

What runtime attestation looks like in practice
AppiCryptWeb takes this approach. You add a lightweight SDK to your web app - a JavaScript + WebAssembly bundle that runs inside your page, invisible to the user. On every request, it evaluates two layers of signals:
Environment signals
Properties of the runtime that automation tools leave behind. Headless browsers, WebDriver-based frameworks, and scripted environments expose dozens of telltale signs: missing APIs, inconsistent browser objects, absent plugins, zero-size viewports. Individually, each signal is easy to spoof. Combined and evaluated inside an isolated WebAssembly context - where the attacker can’t observe or patch the checks - they become much harder to defeat.
Behavioral signals
How the user actually interacts with the page. Real humans produce messy, variable input: imprecise mouse paths, irregular typing rhythms, natural scroll patterns. Automation tools produce synthetic events with uniform timing and mechanical precision. The SDK analyzes mouse movement, keystrokes, scrolling, and clicks over time, building a behavioral profile that can’t be faked by dispatching a few synthetic events.
The result is a cryptographically signed, encrypted token - a cryptogram - attached to each API request. Your backend validates it. If the token is missing, invalid, or indicates a bot - the request is rejected. No puzzles, no friction, nothing visible to the user.

Why this is hard to bypass
The typical arms race with bot detection goes like this: you add a check, the attacker patches it, you add another check, and so on. Runtime attestation changes the dynamic in a few ways:
Checks run inside WebAssembly. Unlike JavaScript-based detection, the logic runs in compiled WASM modules. An attacker can’t set breakpoints, can’t monkey-patch the functions, and can’t inspect what’s being evaluated. By the time any result touches JavaScript, it’s already encrypted.
Multiple signal layers. Even if a stealth plugin patches the obvious environment signals (like navigator.webdriver), behavioral analysis provides a second, independent layer. Fooling both simultaneously is a much harder problem than fooling either one alone.
Cryptographic binding. Each token is bound to a specific request body and timestamp. Tokens can’t be replayed, can’t be reused across requests, and can’t be forged without the signing key embedded in the WASM. An attacker who intercepts a valid token still can’t use it for a different request.
No cryptogram, no access. A curl request, a Python script, or any call that doesn’t come from a browser running the SDK simply won’t have a token. The request is rejected at the edge before it reaches your application.
The stealth plugin problem
A common objection:
“What about puppeteer-extra-plugin-stealth? It patches all the known bot signals.”
Stealth plugins are good at making headless browsers look like real browsers to JavaScript-based detection. They override navigator.webdriver, fake the plugin array, spoof window.chrome, and more. Against a checklist of environment signals evaluated in JavaScript, they work.
Against runtime attestation, they face two problems:
The checks they can’t see. When the detection logic is inside Wasm and the results are encrypted, the stealth plugin doesn’t know which checks exist, what they evaluate, or what the results are. It’s patching a surface it can only guess at.
Behavior can’t be faked with property overrides. Stealth plugins don’t generate realistic mouse movement, natural typing rhythms, or human-like scroll patterns. They make the environment look right while the behavior remains mechanical. Behavioral analysis catches what stealth plugins don’t address.

What about AI agents?
A newer challenge: AI agents that browse with real Chromium instances — tools like Anthropic’s Computer Use, browser-use, and OpenAI Operator. These aren’t headless scripts; they control actual browser windows.
They still have to produce input events, and those events still have automation characteristics. Whether AppiCryptWeb catches them consistently is an active area of testing. Early results are promising, but we won’t claim coverage we haven’t validated. If this is your concern, reach out - we can run detection tests against your specific threat model.
What this doesn’t do
Transparency matters:
Not a WAF. It doesn’t inspect request payloads for injection attacks. Use it alongside your existing security stack.
Not a rate limiter. It tells you whether a request came from a real browser, not how many requests to allow.
Not infallible. A sufficiently resourced attacker will always find new angles. The goal is to make automated abuse structurally expensive — not theoretically impossible.
Getting started
Add the SDK to your frontend It’s a lightweight JavaScript + WebAssembly bundle. Two function calls: one to initialize, one per request to get a token.
Validate on the backend Use the provided validator library or a ready-made edge adapter for Nginx, Cloudflare Workers, AWS Lambda, Azure, or GCP.
Decide your policy Reject bots outright, flag for review, or apply step-up verification. The cryptogram gives you the signal; what you do with it is up to you.
No UI changes. No user friction. No CAPTCHAs.

Here's the entire frontend integration:
That's it. No UI changes. No user friction. No CAPTCHAs.
AppiCryptWeb is built by Talsec. If you want to try it against your own automation tests, check out the companion demo.
Handle App Security with a Single Solution! Check Out Talsec's Premium Offer & Plan Comparison!
Apps Security Threats Report 2025
https://www.talsec.app/talsec-global-threat-report-2025
Plans Comparison
https://www.talsec.app/plans-comparison
Premium Products:
RASP+ - An advanced security SDK that actively shields your app from reverse engineering, tampering, rooting/jailbreaking, and runtime attacks like hooking or debugging.
AppiCrypt (Android & iOS) & AppiCrypt for Web - A backend defense system that verifies the integrity of the calling app and device to block bots, scripts, and unauthorized clients from accessing your API.
Malware Detection - Scans the user's device for known malicious packages, suspicious "clones," and risky permissions to prevent fraud and data theft.
Dynamic TLS Pinning - Prevents Man-in-the-Middle (MitM) attacks by validating server certificates that can be updated remotely without needing to publish a new app version.
Secret Vault - A secure storage solution that encrypts and obfuscates sensitive data (like API keys or tokens) to prevent them from being extracted during reverse engineering.
Last updated
Was this helpful?

