A verificação de anúncios está quebrada. Uma auditoria do setor em 2023 constatou que 60-80% das impressões de anúncios programáticos veiculadas por grandes exchanges exibem criativos diferentes para bots de verificação do que para usuários reais. Isso é cloaking — e compromete todos os relatórios de segurança da marca que você já leu. A solução exige tratar o crawler de verificação como um atacante: roteá-lo através de um proxy HTTP, variar seu fingerprint e comparar o conteúdo renderizado com uma linha de base conhecida como segura.
Como o Cloaking Seleciona Seus Alvos
O cloaking depende de três sinais: User-Agent, X-Forwarded-For (ou IP direto) e Referer. Um servidor de anúncios malicioso inspeciona a requisição recebida e decide se o visitante é um bot de verificação ou um humano. Bots — como os da Moat, Integral Ad Science ou DoubleVerify — enviam cabeçalhos previsíveis. O servidor então serve um criativo limpo e seguro para a marca ao bot e um criativo malicioso ou inadequado para todos os outros. A discrepância é invisível no painel do verificador.
Exemplos do mundo real incluem conteúdo adulto, propaganda política ou redirecionamentos de malware servidos apenas para usuários móveis em geografias específicas. O atacante verifica User-Agent para “Mozilla/5.0 (Linux; Android …)” e X-Forwarded-For para uma faixa de IP que pertence a um fornecedor de verificação conhecido. Se o IP corresponder, o anúncio é seguro. Caso contrário, o usuário recebe o payload.
Usando um Proxy MITM para Detectar Discrepâncias
O método de detecção mais confiável é executar seu próprio crawler de verificação através de um proxy HTTP transparente — mitmproxy ou Burp Suite — e comparar a resposta com uma requisição de controle enviada sem o proxy. O proxy permite capturar o corpo da resposta bruta e modificar cabeçalhos em tempo real. Você pode repetir a mesma requisição com um User-Agent ou X-Forwarded-For diferente e ver se o servidor de anúncios altera o criativo.
Aqui está um script mínimo em mitmproxy que registra discrepâncias entre duas requisições para a mesma URL com diferentes user agents:
# 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
Execute com mitmproxy -s check_cloak.py --listen-port 8080, então aponte seu navegador ou curl para o proxy. Compare os corpos das respostas — se o HTML, as imagens ou o JavaScript diferirem, você tem um criativo com cloaking.
Rastreamento com Segmentação Geográfica e Rotação de Proxy
O cloaking frequentemente usa GeoIP como um discriminador adicional. Um anúncio pode servir um criativo limpo para requisições originadas dos Estados Unidos, mas mudar para um malicioso para usuários no Sudeste Asiático ou Leste Europeu. Para capturar isso, você deve rastrear a mesma URL de anúncio a partir de múltiplos endpoints geográficos. Um pool de proxies residenciais (ex.: BrightData, Oxylabs) ou uma cadeia de proxies SOCKS5 permite definir o X-Forwarded-For e o IP de origem TCP simultaneamente.
Use curl com um proxy e cabeçalhos personalizados para simular um usuário móvel em uma região alvo:
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
Compare os dois arquivos. Qualquer diferença nas tags <script> ou nos atributos de imagem src indica cloaking por geografia.
Diferenças de Criativo entre Mobile e Desktop
O cloaking frequentemente tem como alvo o tráfego móvel, pois usuários móveis têm menos probabilidade de inspecionar requisições de rede. Crawlers de verificação que apenas imitam navegadores desktop perdem isso completamente. Você deve enviar requisições com ambas as strings User-Agent e comparar as respostas. Um padrão comum: a resposta do desktop contém um banner 300x250 padrão, enquanto a resposta móvel carrega um intersticial em tela cheia que redireciona para uma página de phishing.
Use uma ferramenta como diff ou jq para comparar respostas JSON. Para HTML, use htmlq ou pup para extrair elementos específicos. O segredo é automatizar a comparação em uma matriz de user agents, geolocalizações de IP e referenciadores. Um sistema de produção que construí executa 16 requisições paralelas por unidade de anúncio e sinaliza qualquer variação acima de um limite de 5% no tamanho em bytes.
Compensações e Limitações
Esta abordagem não é perfeita. Servidores de anúncios podem detectar faixas de IP de proxy e servir criativos limpos para saídas de proxy conhecidas — da mesma forma que detectam bots de verificação. Rotacionar proxies residenciais ajuda, mas adiciona latência e custo. Além disso, alguns cloaking são baseados em tempo: o criativo malicioso só aparece após um atraso ou após um evento JavaScript que uma requisição simples curl não pode disparar. Nesses casos, você precisa de um navegador headless (Puppeteer, Playwright) por trás do proxy, o que aumenta a complexidade e a capacidade de fingerprint.
No entanto, o princípio central se mantém: se você não consegue reproduzir exatamente a mesma resposta em um conjunto diversificado de fingerprints de cliente, o anúncio não é confiável. Proxies HTTP lhe dão o controle para construir esses fingerprints programaticamente. Comece com um script simples em mitmproxy e um punhado de endpoints de proxy. Isso por si só pegará a maioria das campanhas de cloaking de baixo esforço — e não custa nada além de algumas linhas de Python.