Anti-Bot

What Is Kasada Bot Defense?

What Is Kasada Bot Defense? — conceptual illustration
On this page

Kasada is a bot-defense system that big retailers, ticketing sites, and sneaker drops put in front of their servers to manage automated traffic. It works as a gatekeeper proxy: it sits between the visitor and the origin (the real application server), so every request passes through it first. Unlike Cloudflare or DataDome, it does not show a CAPTCHA. Instead, it makes the browser solve a JavaScript proof-of-work challenge — a small puzzle that costs real CPU time — before letting anything through. A request that does not pass receives a silent 403 or 429 error with no explanation. A notable 2026 detail: Kasada identifies playwright-stealth by running Function.prototype.toString() on native browser functions to see whether they have been modified. The patterns those patches leave behind are already catalogued.

Quick facts

Detection cookiesx-kpsdk-ct, x-kpsdk-cd
Challenge fileips.js — polymorphic, renamed every deployment
Distinct signalFunction.prototype.toString() inspection on patched APIs
Block styleSilent 403 / 429 — no challenge page, no explanation
Notable compatible toolPatchRight (Python source patches, not runtime JS)

How Kasada scores requests

Kasada is a gatekeeper proxy: every request flows through it before it reaches the origin (the real server). It serves a JavaScript file — named ips.js, but renamed on each deployment so its name keeps changing (polymorphic). That file hands the browser a proof-of-work challenge: a math puzzle that needs real CPU cycles and real browser APIs to solve. When the browser finishes, it gets a token (x-kpsdk-ct). Each token works only once — sending the same one twice is an instant red flag.

The standout 2026 detection trick: Kasada runs Function.prototype.toString() on dozens of built-in browser functions (such as navigator.webdriver, WebGLRenderingContext.getParameter, and HTMLCanvasElement.toDataURL). Calling toString() on a genuine browser function returns function () { [native code] }. But if a stealth tool like playwright-stealth has rewritten that function in JavaScript to hide automation, toString() returns function () { [custom code] } instead — and Kasada has the full set of these patched signatures on file.

Signals Kasada weighs

playwright-stealth — every patch it applies leaves a toString() trail. Those signatures are catalogued, which is why JavaScript-layer patching is detectable here.

undetected-chromedriver on its own — it changes the webdriver flag, but not the wider set of functions Kasada inspects with toString().

Datacenter proxies — Kasada weighs IP reputation heavily. Addresses from cloud providers (AWS, GCP, DigitalOcean ASNs — the network blocks a hosting company owns) carry low trust regardless of the browser configuration.

Token replayx-kpsdk-ct tokens are single-use, so a repeated token is itself a signal.

How tools interact with it

PatchRight is frequently referenced in 2026 because it edits the Playwright Python source before Chrome starts, so its changes never exist as JavaScript inside the running browser. With nothing modified in the JS runtime, there is nothing for toString() to read at that layer.

SeleniumBase UC mode is another option that adjusts the WebDriver flag and can complete the proof-of-work challenge automatically.

Context that affects outcomes: IP reputation (residential or ISP static IPs versus datacenter addresses), token handling (each challenge token is single-use), and session distribution all factor into how Kasada scores traffic, on top of the browser configuration itself.

Code example

python
# PatchRight patches the Playwright Python source before Chrome starts,
# so there are no JS-runtime changes for toString() inspection to read.

from patchright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context(
        proxy={"server": "http://user:pass@residential:port"}
    )
    page = context.new_page()
    page.goto("https://kasada-protected.com/")
    # PoW solved automatically by real browser execution
    html = page.content()

Related terms

Concept map

How Kasada connects

The terms most directly tied to this one. Hover a node to see its neighbours, click to preview, drag to rearrange.

0 terms · 0 connections
You are here · Anti-Bot
Building map…

Frequently asked questions

Why does playwright-stealth fail on Kasada?

Because Kasada runs Function.prototype.toString() on the browser's native functions to read their source. playwright-stealth rewrites those functions in JavaScript to hide automation, so toString() hands back the patched source — which is exactly the signal Kasada is hunting for. The patch that was meant to hide you is what gives you away.

What is ips.js and why is it renamed?

ips.js is the JavaScript file that delivers Kasada's challenge. It is renamed on every deployment so blockers cannot match it by filename (it is polymorphic). The challenge logic inside also keeps changing shape, so static deobfuscation tools — which try to unscramble the code automatically — cannot keep up.

Does Kasada's challenge require a real browser?

Generally yes. The proof-of-work challenge relies on real browser features (the Crypto API, performance.now() timing, a live page execution context), which is why HTTP-only clients struggle with it and why the challenge logic changes every time ips.js rotates.

When should I use a managed scraping API instead?

When your team spends more than about 2 engineer-days a month maintaining browser automation against Kasada-protected sites you are authorized to access. The challenge rotation, the toString() surface, and the proxy-reputation upkeep add up fast. Above that point, a managed API such as Scrappey or Bright Data Web Unlocker is usually cheaper than doing it yourself.

Last updated: 2026-05-31