La verifica degli annunci è compromessa. Un audit del settore del 2023 ha rilevato che il 60-80% delle impressioni pubblicitarie programmatiche servite tramite i principali exchange mostra creatività diverse ai bot di verifica rispetto agli utenti reali. Questo è cloaking — e mina ogni report di brand safety che abbiate mai letto. La soluzione richiede di trattare il crawler di verifica come un attaccante: instradarlo attraverso un proxy HTTP, variare la sua impronta digitale e confrontare il contenuto renderizzato con una baseline nota come sicura.
Come il cloaking seleziona i suoi bersagli
Il cloaking si basa su tre segnali: User-Agent, X-Forwarded-For (o IP diretto) e Referer. Un server pubblicitario malevolo ispeziona la richiesta in arrivo e decide se il visitatore è un bot di verifica o un umano. I bot — come quelli di Moat, Integral Ad Science o DoubleVerify — inviano header prevedibili. Il server serve quindi una creatività pulita e brand-safe al bot e una creatività malevola o inappropriata a tutti gli altri. La discrepanza è invisibile al dashboard del verificatore.
Esempi reali includono contenuti per adulti, propaganda politica o reindirizzamenti malware serviti solo a utenti mobile in aree geografiche specifiche. L'attaccante controlla User-Agent per "Mozilla/5.0 (Linux; Android …)" e X-Forwarded-For per un intervallo IP che appartiene a un noto vendor di verifica. Se l'IP corrisponde, l'annuncio è sicuro. In caso contrario, l'utente riceve il payload.
Utilizzo di un proxy MITM per rilevare discrepanze
Il metodo di rilevamento più affidabile è eseguire il proprio crawler di verifica attraverso un proxy HTTP trasparente — mitmproxy o Burp Suite — e confrontare la risposta con una richiesta di controllo inviata senza proxy. Il proxy permette di catturare il corpo della risposta grezza e modificare gli header in tempo reale. Puoi riprodurre la stessa richiesta con un User-Agent o X-Forwarded-For diverso e vedere se il server pubblicitario cambia la creatività.
Ecco uno script mitmproxy minimale che registra le discrepanze tra due richieste alla stessa URL con user agent diversi:
# save as check_cloak.py
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
if "adserver.example.com" in flow.request.pretty_host:
ua = flow.request.headers.get("User-Agent", "")
if "Android" in ua:
flow.request.headers["X-Forwarded-For"] = "1.2.3.4" # bot IP
else:
flow.request.headers["X-Forwarded-For"] = "5.6.7.8" # user IP
Eseguilo con mitmproxy -s check_cloak.py --listen-port 8080, poi punta il tuo browser o curl al proxy. Confronta i corpi delle risposte — se HTML, immagini o JavaScript differiscono, hai una creatività cloaked.
Crawling geolocalizzato con rotazione dei proxy
Il cloaking usa spesso GeoIP come discriminante aggiuntivo. Un annuncio può servire una creatività pulita a richieste provenienti dagli Stati Uniti ma passare a una malevola per utenti nel Sud-est asiatico o nell'Europa orientale. Per individuarlo, devi eseguire il crawl dello stesso URL pubblicitario da più endpoint geografici. Un pool di proxy residenziali (es. BrightData, Oxylabs) o una catena di proxy SOCKS5 ti permette di impostare contemporaneamente X-Forwarded-For e l'IP sorgente TCP.
Usa curl con un proxy e header personalizzati per simulare un utente mobile in una regione target:
curl -x socks5://user:pass@proxy-us-east:1080 \
-H "User-Agent: Mozilla/5.0 (Linux; Android 13; Pixel 7)" \
-H "X-Forwarded-For: 203.0.113.50" \
-H "Referer: https://example.com/article" \
-o response_us.html \
https://adserver.example.com/ad
curl -x socks5://user:pass@proxy-vietnam:1080 \
-H "User-Agent: Mozilla/5.0 (Linux; Android 13; Pixel 7)" \
-H "X-Forwarded-For: 42.112.0.1" \
-H "Referer: https://example.com/article" \
-o response_vn.html \
https://adserver.example.com/ad
Confronta i due file. Qualsiasi differenza nei tag <script> o negli attributi src delle immagini indica cloaking basato sulla geografia.
Differenze creative tra mobile e desktop
Il cloaking prende spesso di mira il traffico mobile perché gli utenti mobile hanno meno probabilità di ispezionare le richieste di rete. I crawler di verifica che imitano solo browser desktop lo perdono completamente. Devi inviare richieste con entrambe le stringhe User-Agent e confrontare le risposte. Un pattern comune: la risposta desktop contiene un banner 300x250 standard, mentre quella mobile carica un interstiziale a schermo intero che reindirizza a una pagina di phishing.
Usa uno strumento come diff o jq per confrontare risposte JSON. Per HTML, usa htmlq o pup per estrarre elementi specifici. La chiave è automatizzare il confronto su una matrice di user agent, geolocalizzazioni IP e referrer. Un sistema di produzione che ho costruito esegue 16 richieste parallele per unità pubblicitaria e segnala qualsiasi variazione oltre una soglia del 5% nella dimensione in byte.
Compromessi e limitazioni
Questo approccio non è perfetto. I server pubblicitari possono rilevare gli intervalli IP dei proxy e servire creatività pulite alle uscite proxy note — allo stesso modo in cui rilevano i bot di verifica. Ruotare proxy residenziali aiuta ma aggiunge latenza e costi. Inoltre, alcuni cloaking sono basati sul tempo: la creatività malevola appare solo dopo un ritardo o dopo un evento JavaScript che una semplice richiesta curl non può attivare. In questi casi serve un browser headless (Puppeteer, Playwright) dietro il proxy, il che aumenta complessità e fingerprintabilità.
Tuttavia il principio di base rimane: se non riesci a riprodurre esattamente la stessa risposta attraverso un insieme diversificato di impronte client, l'annuncio non è affidabile. I proxy HTTP ti danno il controllo per costruire quelle impronte in modo programmatico. Inizia con un semplice script mitmproxy e una manciata di endpoint proxy. Da solo catturerà la maggior parte delle campagne di cloaking a basso sforzo — e non costa nulla se non poche righe di Python.