Fingerprinting TLS (JA3/JA4): Perché gli IP puliti vengono ancora bloccati
Il tuo IP residenziale è pulito, i tuoi header sono perfetti, e ottieni comunque un 403 alla prima richiesta. Il problema è la tua stretta di mano TLS — l'impronta digitale che i sistemi anti-bot leggono prima che venga scambiato qualsiasi HTTP.
Ecco un enigma che ogni scraper affronta prima o poi: l'IP residenziale è pulito, il User-Agent è una stringa Chrome aggiornata, gli header sono in perfetto ordine — e la primissima richiesta restituisce 403. Nulla che ruoti lo risolve. La ragione è che il blocco è avvenuto prima che i tuoi header fossero mai letti. I moderni sistemi anti-bot fingerprintano la tua stretta di mano TLS, e un client Python, Go o curl di default si annuncia come un bot nel ClientHello, uno strato sotto l'HTTP. Questo è ciò che fanno il fingerprinting JA3 e JA4, e perché curl ottiene un 403 dove il browser ottiene un 200 sullo stesso URL.
Cosa legge il fingerprinting TLS
Ogni connessione HTTPS si apre con una stretta di mano TLS. Il client invia un ClientHello che pubblicizza, in un ordine specifico, quale versione TLS desidera, quali suite di cifratura supporta, quali estensioni offre (SNI, ALPN e altro), quali curve ellittiche e quali formati di punto. Nessuno di questi nomina direttamente il tuo browser — ma la combinazione e l'ordine esatti sono una firma quasi unica dello stack software. La lista di Chrome differisce da quella di Firefox, e entrambe differiscono notevolmente da requests di Python o net/http di Go. Leggi la stretta di mano, e puoi indovinare il client prima che un byte di HTTP venga scambiato.
JA3: cinque campi in un hash MD5
JA3, pubblicato nel 2017 dagli ingegneri di Salesforce, è il metodo classico. Prende cinque campi dal ClientHello — versione TLS, cifrature, estensioni, curve ellittiche e formati di punto — li concatena, e passa la stringa attraverso MD5. Un esempio concreto: i campi
771,4865-4866-4867,0-11-10-35-16-5-13,29-23-24,0
si trasformano in e7d705a3286e19ea42f587b344ee6865 — un'impronta digitale che appartiene a una build standard di curl. I fornitori anti-bot mantengono database di questi hash. Una richiesta il cui JA3 corrisponde a una libreria di scraping nota riceve un limite di velocità più severo, una sfida o un blocco totale. Il controllo più potente è la correlazione: se il tuo User-Agent dichiara Chrome 120 ma il tuo JA3 dice python-requests, quella contraddizione da sola è sufficiente per farti fallire.
Perché JA3 ha lasciato il posto a JA4
JA3 ha una debolezza che lo ha reso un segnale instabile. Da Chrome 110 e Firefox 114, i browser randomizzano l'ordine delle estensioni TLS su ogni connessione per resistere al fingerprinting. Ciò significa che un vero browser ora produce un hash JA3 diverso ad ogni sessione — quindi il JA3 grezzo genera falsi positivi su utenti genuini. La risposta dell'industria è JA3N (una variante normalizzata che ordina le estensioni prima di fare l'hash, annullando la randomizzazione) e JA4, uno schema più recente di FoxIO costruito dallo stesso creatore di JA3.
JA4 è più leggibile e più difficile da falsificare. Utilizza un layout a tre parti a_b_c, per esempio t13d1516h2_8daaf6152771_e5627efa2ab1. Il prefisso da solo dice molto: t per TCP, 13 per TLS 1.3, d per un SNI basato su dominio, 15 suite di cifratura, 16 estensioni, e h2 per HTTP/2 come primo ALPN — seguito da due hash troncati delle cifrature ordinate e delle estensioni più algoritmi di firma. JA4 è uno di una famiglia: JA4S fingerprinta il server, JA4H gli header HTTP, JA4X il certificato, e JA4T lo strato TCP grezzo.

Perché un IP pulito non ti salva
Questa è la parte che fa inciampare le persone che investono solo in proxy. Un IP residenziale immacolato dice al sito che il traffico proviene da una rete reale. Una stretta di mano TLS non corrispondente al browser dice che il traffico proviene da uno script. Quando questi due segnali non concordano, la stretta di mano vince, perché è molto più difficile da falsificare per caso. Puoi ruotare attraverso mille uscite pulite e fallire comunque ogni richiesta se tutte e mille portano lo stesso JA3 python-requests. L'IP e l'impronta digitale sono assi separati — devi ottenere entrambi corretti.
Concretamente, ciò si manifesta nei tassi di passaggio contro un obiettivo protetto da Cloudflare: un client requests di default supera circa il due percento delle richieste, httpx con HTTP/2 fa un po' meglio, e un client abbinato al browser supera l'ottanta percento. Stesso pool di IP in ogni caso. La variabile è lo stack TLS. Akamai alza ulteriormente l'asticella combinando l'impronta digitale TLS con un'impronta digitale HTTP/2 — i valori del frame SETTINGS, le dimensioni delle finestre e le priorità dei flussi — quindi anche un JA3 corretto può essere catturato se lo strato HTTP/2 sembra scriptato. La nostra analisi di perché Akamai blocca la maggior parte del traffico proxy approfondisce ulteriormente quello stack.

Le opzioni di impersonificazione che effettivamente passano
Non puoi collegare una stretta di mano del browser a un client standard modificando le stringhe di cifratura — le manopole OpenSSL e urllib3 semplicemente non espongono ogni parametro che JA3 legge. Ciò che funziona è un client che parla l'esatto dialetto TLS del browser:
- curl_cffi (Python) — binding su curl-impersonate. Un argomento,
impersonate="chrome120", e il tuo JA3 corrisponde al vero Chrome. - curl-impersonate — un binario curl patchato che riproduce gli stack TLS e HTTP di Chrome e Firefox dalla riga di comando.
- tls-client (Go) — un client HTTP con profili di browser selezionabili (Chrome, Firefox, Safari) a livello di stretta di mano.
- Automazione reale del browser — Playwright, Puppeteer o Selenium utilizzano un vero motore del browser, quindi il JA3 è genuino. Il problema sono altri segnali (il flag
navigator.webdriver, canvas e WebGL) che ancora trapelano, quindi i tassi di passaggio si aggirano intorno al sessanta percento senza un ulteriore indurimento.
# curl_cffi: a browser-shaped handshake in two lines
from curl_cffi import requests
session = requests.Session(impersonate="chrome120")
r = session.get(
"https://example.com",
proxies={"https": "http://USER:PASS@gate.quantumproxies.io:8000"},
timeout=20,
)
print(r.status_code) # matched JA3 + a clean residential exit
Nota il proxy in quel frammento. L'impersonificazione e un'uscita pulita sono complementari, non alternative: la stretta di mano a forma di browser ti fa superare il controllo TLS, e un IP residenziale pulito mantiene la richiesta fuori dalle liste di blocco di reputazione. Abbinali e risolvi entrambi gli assi contemporaneamente.
Salta la corsa agli armamenti TLS con l'API Scraper
Quando delegare l'intero problema
L'impersonificazione fai-da-te funziona finché il target ruota il suo rilevamento, aggiunge un'impronta digitale HTTP/2 o richiede l'esecuzione di JavaScript — allora stai mantenendo una libreria di emulazione del browser come secondo lavoro. Un Scraper API porta un'impronta digitale del browser reale e rotante, corrisponde allo strato HTTP/2, esegue JS su richiesta e restituisce HTML pulito, markdown o JSON da una singola chiamata. Trasforma la corsa agli armamenti TLS in un problema di qualcun altro mentre tu ti occupi dei dati. Per una visione più ampia di come i siti segnalano l'automazione, consulta la nostra guida su ogni segnale di rilevamento dei proxy.
Domande frequenti
Cos'è un'impronta digitale JA3?
Un'impronta digitale JA3 è un hash MD5 di cinque campi presi dal TLS ClientHello — versione TLS, suite di cifratura, estensioni, curve ellittiche e formati di punto. Poiché ogni stack software ordina questi campi in modo diverso, l'hash identifica il client (Chrome, Firefox, curl, Python) prima che venga scambiato qualsiasi dato HTTP.
Qual è la differenza tra JA3 e JA4?
JA3 fa l'hash di cinque campi ClientHello con MD5 e si rompe quando i browser randomizzano l'ordine delle estensioni. JA4, da FoxIO, ordina i campi prima di fare l'hash in modo che sopravviva a quella randomizzazione, aggiunge un prefisso di metadati leggibile dall'uomo, e copre QUIC/HTTP/3, ALPN e algoritmi di firma. JA4 è il segnale moderno più affidabile; JA3N è un ripiego normalizzato per JA3.
Posso bypassare il fingerprinting TLS solo con i proxy?
No. I proxy cambiano l'IP, non la stretta di mano. Se la tua impronta digitale TLS corrisponde a una libreria di scraping nota, ruotare le uscite non aiuterà — ogni richiesta porta ancora la firma del bot. Hai bisogno di un client che riproduca lo stack TLS di un browser, poi un proxy pulito sopra per la reputazione IP.
Python requests ha un'impronta digitale TLS rilevabile?
Sì. requests utilizza urllib3 con un ordine distintivo di cifratura ed estensioni che i fornitori anti-bot hanno catalogato, quindi il suo JA3 è una firma nota del bot. Passa a curl_cffi con un profilo impersonate per inviare una stretta di mano abbinata al browser.
Il fingerprinting TLS ha spostato la lotta sotto l'HTTP, ed è per questo che i trucchi sugli header e la rotazione degli IP non sono più sufficienti da soli. Abbina la stretta di mano, mantieni l'uscita pulita, e il problema del 403-alla-prima-richiesta scompare. Questa è una guida tecnica, non una licenza per ignorare i termini di un sito — raschia sempre nel rispetto della legge e delle regole del target.