Se gestisci infrastrutture di scraping o fai ricerca anti-bot, hai probabilmente incontrato Kasada Anti-Bot. Kasada Anti-Bot spiegato in una frase: è una piattaforma di rilevazione lato-client che combina un bytecode VM offuscato, fingerprinting TLS/HTTP2 e IP reputation scoring per bloccare l'automazione prima ancora che il JavaScript challenge venga eseguito. Questo articolo è una guida pratica per ingegneri senior che devono capire come funziona Kasada e come configurare l'automazione autorizzata per passare pulita.
Cos'è Kasada Anti-Bot: spiegato l'architettura di rilevazione
Kasada non è un semplice WAF che filtra header HTTP. È un sistema di client-side proof-of-work combinato con fingerprinting a più livelli. L'architettura si compone di tre strati che operano in sequenza:
- Pre-challenge network layer: TLS fingerprinting (JA3/JA4), HTTP/2 fingerprinting, e IP reputation scoring basato su ASN. Questo avviene prima che qualsiasi JavaScript venga eseguito.
- JS challenge layer: il script
ips.jsviene caricato nel browser reale, esegue un bytecode VM personalizzato, raccoglie un fingerprint del dispositivo e produce un token crittografato. - Token validation layer: il token viene inviato al backend Kasada via header
x-kpsdk-cte validato lato server. Se il token è assente, scaduto o invalido, il server risponde con429 Too Many Requests.
La complessità sta nel fatto che ogni strato può bloccare la richiesta indipendentemente dagli altri. Puoi superare il TLS fingerprinting e fallire comunque al challenge JS, oppure passare il challenge JS ma essere bloccato dall'IP reputation. Questo rende Kasada significativamente più difficile da gestire rispetto a sistemi che si basano solo su CAPTCHA o rate limiting.
Il challenge script ips.js: il bytecode VM da 449KB
Il cuore del sistema Kasada è il file ips.js, un script di circa 449 KB che implementa una macchina virtuale custom. Questo non è JavaScript leggibile: è un bytecode offuscato che viene decodificato a runtime da un interpreter embedded.
Struttura interna del VM
Il VM di ips.js contiene diversi componenti chiave:
- Encoded string table: una tabella di stringhe codificate che viene decifrata a runtime usando chiavi derivate da timestamp e parametri di sessione. Le stringhe contengono nomi di API del browser, proprietà del navigator, e valori attesi per il fingerprinting.
- Time-based seeds: il VM usa
performance.now()eDate.now()per generare semi crittografici. Questo significa che il payload crittografato cambia ad ogni esecuzione e non può essere semplicemente riutilizzato. - Integrity checksums: il VM calcola checksum di integrità sul proprio codice e sull'ambiente di esecuzione. Se rileva modifiche al DOM, hooking di funzioni native, o la presenza di strumenti come Selenium/Playwright driver, invalida il challenge.
- Opcode dispatcher: un loop principale che interpreta bytecode personalizzato. Ogni opcode mappa a operazioni che raccolgono dati dal browser (canvas fingerprint, WebGL renderer, audio context, font enumeration, ecc.).
Il punto cruciale per chi fa automazione autorizzata è che ips.js deve essere eseguito in un browser reale. Non è possibile estrarre l'algoritmo di generazione del token e replicarlo in Python o Node.js: il VM dipende da centinaia di signal del browser reale che cambiano in base al runtime.
Il cookie KP_UIDz e gli header x-kpsdk
Quando ips.js completa il challenge con successo, il risultato viene memorizzato nel cookie KP_UIDz. Questo cookie contiene il token di sessione che Kasada usa per validare le richieste successive. Gli header della famiglia x-kpsdk trasportano i dati del challenge:
| Header | Funzione | Quando appare |
|---|---|---|
x-kpsdk-ct | Challenge token — payload crittografato principale | Ad ogni richiesta dopo il challenge iniziale |
x-kpsdk-cd | Challenge data — dati di contesto aggiuntivi | Insieme al token principale |
x-kpsdk-dv | Device verification — hash del fingerprint del dispositivo | Per validare la coerenza del dispositivo |
Quando ricevi una risposta 429 che include x-kpsdk-ct nell'header di risposta, significa che il token inviato è stato rifiutato. Le cause più comuni sono: token scaduto (il time-to-live è breve, tipicamente nell'ordine di minuti), fingerprint del dispositivo cambiato tra la generazione del token e la richiesta, o IP che ha cambiato ASN tra il challenge e la richiesta successiva.
Nota pratica: Se vedi
429conx-kpsdk-ctnella risposta, non è un rate limit classico. È Kasada che dice "il tuo token non è valido". Aumentare il delay tra le richieste non risolve il problema; devi rigenerare il token eseguendo nuovamenteips.js.
Come il VM raccoglie il fingerprint e genera payload rotanti
Il fingerprinting di Kasada è estensivo e tocca decine di signal del browser. Ecco i principali segnali che il VM raccoglie durante l'esecuzione di ips.js:
Browser fingerprint signals
- Canvas fingerprint: rendering di testo e forme su un canvas off-screen, poi hashing dei pixel risultanti. Il rendering varia in base a GPU, driver, sistema operativo e versione del browser.
- WebGL renderer string:
WEBGL_debug_renderer_infoespone il vendor e il modello della GPU. Headless browser spesso mostrano valori comeSwiftShaderoMesache sono immediatamente riconoscibili. - AudioContext fingerprint: l'output di
OfflineAudioContextproduce un fingerprint basato sull'implementazione DSP del browser. - Font enumeration: misurazione della larghezza di stringhe renderizzate con vari font per determinare quali sono installati. I headless browser hanno un set di font tipicamente diverso da un browser reale.
- Navigator properties:
userAgent,platform,hardwareConcurrency,deviceMemory,languages,plugins,webdriverflag. - Screen properties:
screen.width,screen.height,screen.colorDepth,window.devicePixelRatio,screen.availWidth/Height.
Perché i payload sono crittografati e rotanti
Il payload finale che finisce in x-kpsdk-ct non è un semplice hash del fingerprint. È un blob crittografato che contiene:
- Il fingerprint del dispositivo, hashato e codificato.
- Un timestamp di generazione (per validare il TTL).
- Un nonce univoco per prevenire replay attack.
- Una firma HMAC che lega tutti i campi precedenti a una chiave di sessione derivata dal seed temporale.
Questo significa che anche se catturi un payload valido, non puoi riutilizzarlo dopo che il TTL scade (tipicamente pochi minuti) e non puoi modificarlo perché la firma HMAC non combacerà. Il seed basato sul tempo fa sì che la chiave di cifratura cambi ad ogni esecuzione, rendendo i payload effettivamente rotanti.
TLS (JA3/JA4) e HTTP/2 fingerprinting prima del challenge JS
Una delle caratteristiche più importanti di Kasada è che filtra a livello di rete prima ancora di servire il JavaScript. Questo avviene tramite due tecniche complementari: TLS fingerprinting e HTTP/2 fingerprinting.
JA3 e JA4: il fingerprint TLS
JA3 è un metodo per creare un fingerprint della connessione TLS basato sui parametri del ClientHello. Il fingerprint è calcolato come hash MD5 della concatenazione di: versione TLS, cipher suites (in ordine), estensioni, elliptic curves, e elliptic curve point formats. Puoi leggere la specifica originale di JA3 sul repository GitHub di Salesforce, dove è stato originariamente pubblicato.
JA4 è l'evoluzione che separa i componenti del fingerprint in campi distinti per facilitare il confronto e l'analisi. Il punto chiave è questo: ogni client HTTP (browser, libreria, strumento CLI) ha un JA3/JA4 caratteristico. curl ha un fingerprint diverso da Chrome, che è diverso da Firefox, che è diverso da requests in Python. Kasada mantiene un database di fingerprint noti e blocca quelli associati a librerie di automazione.
Secondo l'analisi di Cloudflare sul fingerprinting TLS, il JA3 fingerprint è stabile per una data combinazione di browser+versione+OS, ma cambia quando si aggiorna il browser o si usa una libreria diversa. Questo rende il fingerprinting TLS un signal molto affidabile per distinguere browser reali da automazione.
HTTP/2 fingerprinting
Kasada va oltre il TLS e analizza anche il fingerprint HTTP/2. La specifica HTTP/2 (RFC 7540) permette molta flessibilità nei parametri del client, e questa flessibilità crea fingerprint distinguibili:
- SETTINGS frame: i valori dei parametri SETTINGS (HEADER_TABLE_SIZE, INITIAL_WINDOW_SIZE, MAX_CONCURRENT_STREAMS, ecc.) variano tra client.
- WINDOW_UPDATE: la dimensione della finestra iniziale è caratteristica del client.
- PRIORITY frames: l'ordine e i pesi dei frame PRIORITY differiscono tra implementazioni.
- Pseudo-header order: l'ordine degli pseudo-header (
:method,:authority,:scheme,:path) nel HEADERS frame è specifico del client.
Un browser Chrome reale ha un fingerprint HTTP/2 diverso da requests, axios, o httpx. Kasada usa questa differenza per bloccare richieste che arrivano da librerie HTTP prima ancora di servire il challenge JavaScript.
IP reputation scoring
Il terzo livello pre-challenge è l'IP reputation. Kasada assegna un punteggio di fiducia a ogni IP basato su:
- ASN type: datacenter ASN (AWS, GCP, Azure, DigitalOcean, OVH, ecc.) ricevono un punteggio basso. ASN residenziali (ISP domestici) ricevono un punteggio alto.
- Geographic consistency: se l'IP geolocalizza in un paese diverso dall'header
Accept-Language, il punteggio scende. - Historical behavior: IP che hanno generato pattern di traffico bot-like in passato vengono penalizzati.
- Proxy detection: Kasada rileva proxy noti usando database commerciali e tecniche di active probing.
L'IP reputation scoring avviene prima del challenge JS. Se il punteggio è troppo basso, Kasada può servire direttamente un 403 o un challenge insuperabile senza nemmeno inviare ips.js.
Perché i proxy residenziali sono essenziali per Kasada
Dato che Kasada pre-blocca gli ASN datacenter e pesa pesantemente l'IP trust, i proxy datacenter sono praticamente inutilizzabili contro Kasada. Anche se superassi il TLS fingerprinting e il challenge JS (il che richiederebbe un browser reale), l'IP reputation scoring bloccherebbe la richiesta perché l'IP proviene da un ASN noto come datacenter.
I proxy residenziali sono essenziali perché forniscono IP che appartengono a ISP domestici reali. Kasada non può pre-bloccare un IP residenziale senza rischiare di bloccare utenti reali, quindi deve servire il challenge JS e valutare il fingerprint del browser. Questo dà all'automazione autorizzata la possibilità di passare pulita.
| Tipo di proxy | ASN type | IP trust score | Funziona con Kasada? |
|---|---|---|---|
| Datacenter | Cloud/hosting provider | Basso | No — pre-bloccato |
| Mobile | Carrier mobile | Alto | Sì, ma costoso e limitato |
| Residenziale | ISP domestico | Alto | Sì — la scelta migliore |
I proxy mobili hanno un trust score ancora più alto dei residenziali, ma sono significativamente più costosi e hanno una pool di IP più limitata. Per la maggior parte dei casi d'uso di automazione autorizzata, i proxy residenziali offrono il miglior rapporto qualità-prezzo.
Implementazione pratica: ProxyHat residential + browser reale
L'approccio corretto per passare Kasada con automazione autorizzata combina due elementi: proxy residenziali per l'IP reputation e un browser reale per eseguire ips.js e generare un token valido. Ecco come configurare ProxyHat per questo scenario.
Step 1: Configurare il proxy residenziale
ProxyHat fornisce proxy residenziali tramite il gateway gate.proxyhat.com. Per Kasada, raccomandiamo SOCKS5 sulla porta 1080 perché supporta meglio il traffico WebSocket e le connessioni persistenti tipiche dei browser headless.
Per il geo-targeting, scegli un paese coerente con l'header Accept-Language del browser. Se il browser è configurato in tedesco, usa un IP tedesco:
# SOCKS5 con geo-targeting Germania
socks5://user-country-DE:password@gate.proxyhat.com:1080
Per sessioni sticky (necessarie perché Kasada lega il token all'IP), usa il parametro session:
# Sessione sticky con IP tedesco
socks5://user-country-DE-session-mySession01:password@gate.proxyhat.com:1080
La sessione sticky mantiene lo stesso IP per la durata della sessione. Questo è critico: se l'IP cambia tra la generazione del token e la richiesta successiva, Kasada invalida il token.
Step 2: Avviare un browser reale tramite il proxy
Usa Playwright o Puppeteer con un browser Chromium non patchato. L'errore più comune è usare playwright-extra con stealth plugin: Kasada rileva le patch di stealth perché modificano funzioni native del browser, e il VM di ips.js verifica l'integrità di queste funzioni.
from playwright.sync_api import sync_playwright
PROXY = "gate.proxyhat.com:1080"
PROXY_USER = "user-country-DE-session-mySession01"
PROXY_PASS = "password"
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False, # headless viene rilevato più facilmente
proxy={
"server": f"socks5://{PROXY}",
"username": PROXY_USER,
"password": PROXY_PASS,
},
args=[
"--disable-blink-features=AutomationControlled",
"--no-sandbox",
],
)
context = browser.new_context(
locale="de-DE",
timezone_id="Europe/Berlin",
viewport={"width": 1920, "height": 1080},
)
page = context.new_page()
page.goto("https://example.com")
# ips.js viene eseguito automaticamente dal browser
# attendi che KP_UIDz cookie appaia
page.wait_for_cookie("KP_UIDz", timeout=30000)
# Ora il browser ha un token valido
page.goto("https://example.com/protected-page")
content = page.content()
browser.close()
Step 3: Mantenere la coerenza del fingerprint
Per passare Kasada pulitamente, ogni aspetto del browser deve essere coerente:
- User-Agent: deve combaciare con la versione reale di Chromium che stai usando. Non usare UA string arbitrari.
- Accept-Language: deve combaciare con il geo-targeting del proxy. IP tedesco +
Accept-Language: en-USè una red flag. - Timezone:
timezone_iddeve essere coerente con il paese dell'IP. IP a Berlino + timezoneAmerica/New_Yorkviene rilevato. - Viewport: usa dimensioni realistiche.
1920x1080o1536x864vanno bene;800x600è sospetto. - WebGL: non disabilitare WebGL. Kasada controlla il renderer string e un valore vuoto è immediatamente bloccato.
Step 4: Gestire la rotazione delle sessioni
Quando devi ruotare le sessioni (ad esempio per distribuire il carico), crea una nuova sessione ProxyHat e un nuovo context del browser. Non riutilizzare lo stesso context con un IP diverso: il cookie KP_UIDz è legato al fingerprint del dispositivo e all'IP della sessione originale.
# curl test per verificare che il proxy residenziale funzioni
curl -x socks5://user-country-DE-session-test01:password@gate.proxyhat.com:1080 \
https://httpbin.org/ip
Verifica che l'IP restituito sia un IP residenziale tedesco (non un IP datacenter). Puoi controllare l'ASN usando un servizio come ipinfo.io.
Errori comuni e casi limite
Errore 1: Usare librerie HTTP invece di un browser
Il errore più frequente è cercare di fare richieste con requests, httpx, o curl contro un sito protetto da Kasada. Questi client hanno JA3/JA4 fingerprint che non combaciano con nessun browser reale, e Kasada li blocca al livello TLS prima ancora di servire ips.js. Non c'è proxy che tenga: il fingerprint TLS tradisce la libreria.
Errore 2: Headless browser senza stealth adeguato
Un browser headless "nudo" ha segnali rilevabili: navigator.webdriver === true, assenza di GPU rendering, font di sistema minimi, WebGL renderer che mostra SwiftShader o Mesa. Kasada rileva questi segnali nel VM e invalida il challenge. La soluzione non è usare plugin stealth (che Kasada rileva tramite integrity check), ma usare un browser non-headless o un headless con rendering GPU abilitato.
Errore 3: Cambiare IP a metà sessione
Se usi un proxy rotante che cambia IP ad ogni richiesta (senza session sticky), Kasada invaliderà il token perché l'IP non combacia con quello usato per generare il KP_UIDz. Usa sempre session sticky con ProxyHat quando lavori con Kasada.
Errore 4: Disabilitare JavaScript
Ovviamente, senza JavaScript ips.js non può eseguire e nessun token viene generato. Kasada serve un challenge page statico che non contiene il contenuto desiderato.
Caso limite: Token scaduto
Il TTL del token KP_UIDz è breve (nell'ordine di minuti). Se mantieni una sessione browser aperta per molto tempo senza fare richieste, il token scade e la prossima richiesta riceve 429. La soluzione è fare una richiesta di "keep-alive" periodica (es. ogni 2-3 minuti) per rinfrescare il token, oppure rigenerare il token navigando alla pagina del challenge.
Considerazioni legali e uso appropriato
Questo articolo è indirizzato a ricerca di sicurezza autorizzata, penetration testing con permesso, e monitoraggio di dati pubblici nel rispetto dei termini di servizio. Le tecniche descritte non devono essere usate per frode, scalping non autorizzato, o violazione di ToS.
Sotto il Computer Fraud and Abuse Act (CFAA) negli Stati Uniti, accedere a un sistema informatico "senza autorizzazione" o "eccedendo l'accesso autorizzato" può costituire un reato federale. La giurisprudenza (in particolare Van Buren v. United States, 2021) ha limitato l'applicabilità del CFAA, ma la situazione legale rimane complessa. In Europa, il GDPR regolamenta il trattamento di dati personali, e la raccolta automatizzata di dati personali (inclusi IP) richiede una base giuridica legittima.
Prima di implementare qualsiasi automazione contro un sito protetto da Kasada:
- Verifica di avere l'autorizzazione del proprietario del sito o che i dati siano pubblicamente accessibili senza restrizioni.
- Rispetta
robots.txte i termini di servizio. - Limita la frequenza delle richieste per non sovraccaricare il server target.
- Non raccogliere dati personali senza una base giuridica legittima sotto GDPR/CCPA.
Per casi d'uso legittimi come SERP tracking, monitoraggio prezzi di e-commerce pubblico, o ricerca accademica, consulta la nostra guida sul web scraping e la guida sul SERP tracking.
Configurazione ProxyHat: setup rapido
Per iniziare con ProxyHat per automazione autorizzata contro Kasada:
- Crea un account su ProxyHat dashboard e seleziona un piano residenziale.
- Configura il proxy SOCKS5 su
gate.proxyhat.com:1080con le credenziali della dashboard. - Usa il geo-targeting (
user-country-XX) per allineare l'IP con la locale del browser. - Usa session sticky (
user-session-XXX) per mantenere lo stesso IP durante il challenge Kasada. - Verifica le locazioni disponibili per il geo-targeting.
- Consulta la documentazione ProxyHat per dettagli avanzati.
Punti chiave
- Kasada è multi-strato: TLS fingerprinting + HTTP/2 fingerprinting + IP reputation + JS challenge. Devi passarli tutti.
- ips.js è un VM bytecode da ~449 KB che non può essere replicato fuori da un browser reale. Il token generato è crittografato e rotante.
- 429 con x-kpsdk-ct significa token invalido, non rate limit. Devi rigenerare il token.
- I proxy datacenter non funzionano con Kasada perché gli ASN datacenter vengono pre-bloccati. I proxy residenziali sono obbligatori.
- Session sticky è critica: l'IP deve rimanere lo stesso tra generazione del token e richieste successive.
- La coerenza del fingerprint (UA, Accept-Language, timezone, viewport, WebGL) è essenziale per passare il challenge JS.
- Usa solo per automazione autorizzata: ricerca di sicurezza, pentesting con permesso, monitoraggio di dati pubblici.
FAQ
Cos'è Kasada Anti-Bot spiegato in modo semplice?
Kasada Anti-Bot è una piattaforma di rilevazione automation che combina fingerprinting TLS (JA3/JA4), fingerprinting HTTP/2, IP reputation scoring e un challenge JavaScript basato su un bytecode VM offuscato (ips.js). A differenza di semplici CAPTCHA, Kasada analizza la richiesta a multipli livelli prima di servire il contenuto, rendendo l'automazione non autorizzata significativamente più difficile.
Perché Kasada Anti-Bot importa per chi usa proxy?
Kasada pre-blocca gli IP provenienti da ASN datacenter (AWS, GCP, Azure, OVH) prima ancora di servire il challenge JavaScript. Questo significa che i proxy datacenter sono inutilizzabili contro siti protetti da Kasada. I proxy residenziali sono essenziali perché forniscono IP da ISP domestici con un trust score alto, permettendo all'automazione autorizzata di ricevere il challenge JS e passarlo pulitamente.
Quale tipo di proxy funziona meglio con Kasada?
I proxy residenziali sono la scelta migliore per Kasada perché forniscono IP da ISP domestici reali che non vengono pre-bloccati. I proxy mobili hanno un trust score ancora più alto ma sono più costosi e limitati. I proxy datacenter non funzionano affatto. Per ProxyHat, usa SOCKS5 su gate.proxyhat.com:1080 con geo-targeting e session sticky per mantenere lo stesso IP durante il challenge.
Come evitare i blocchi quando si implementa automazione contro Kasada?
Per evitare blocchi: usa proxy residenziali con session sticky, esegui ips.js in un browser reale (non in una libreria HTTP), mantieni la coerenza del fingerprint (UA, Accept-Language, timezone e IP devono combaciare), non usare plugin stealth che modificano funzioni native (Kasada rileva le patch), e rigenera il token quando ricevi 429 con x-kpsdk-ct nella risposta.
Cosa significa 429 con x-kpsdk-ct nella risposta?
Una risposta 429 che include l'header x-kpsdk-ct non è un rate limit classico. Significa che il token del challenge Kasada è stato rifiutato perché scaduto, invalido o non coerente con il fingerprint del dispositivo o l'IP attuale. La soluzione è rigenerare il token eseguendo nuovamente ips.js in un browser reale, non aumentare il delay tra le richieste.






