Ir para o conteúdo

Análise de Card Testing — VTEX

Ferramentas que leem a API da VTEX para investigar o ataque de card testing na loja useveggi.com.br: descobrir domínios de ataque novos, medir a taxa de recusa mês a mês e detalhar a infraestrutura por trás dos pedidos negados.

Onde fica: C:\Projetos\vtex-analise

Credenciais

Todos os scripts leem as credenciais do arquivo .env dessa pasta — VTEX_ACCOUNT, VTEX_APP_KEY e VTEX_APP_TOKEN. Não coloque credencial em outro lugar. O .gitignore já bloqueia o .env e os CSVs; não copie essa pasta para lugar público nem anexe o .env em e-mail.


O jeito fácil: os executáveis

Procurando a receita passo a passo?

Esta página explica o que cada executável faz. Para o roteiro na ordem, com o que fechar antes de cada um e o que fazer com o resultado, veja Passo a Passo da Rotina.

Não precisa abrir o PowerShell nem decorar comando nenhum. Na pasta C:\Projetos\vtex-analise há arquivos numerados. Dê dois cliques no que a situação pedir.

A rotina, do começo ao fim

TODA SEGUNDA          2 - dominio de ataque novo
                         │
                         ├── "Nenhuma infraestrutura nova"  ──►  acabou
                         └── listou dominio  ──►  5 - BLOQUEAR dominio novo

DIA 1 DO MES          3 - taxa de recusa
                         │
                         ├── nenhum mes marcado  ──►  acabou
                         └── mes com <<<  ──►  7 - INVESTIGAR mes suspeito
                                                  │
                                                  ├── ja deu pra entender
                                                  │   ──►  5 ou 6 pra bloquear
                                                  │
                                                  └── preciso do motivo da
                                                      recusa e do CPF
                                                      ──►  8 - ANALISE PROFUNDA

A CADA 3 MESES        9 - ATUALIZAR planilha do panorama

Qual executável usar

Situação Executável
Rotina de segunda-feira 2 - SEMANAL - dominio de ataque novo.bat
Rotina do dia 1 do mês 3 - MENSAL - taxa de recusa.bat
O 3 marcou um mês com <<< 7 - INVESTIGAR mes suspeito.bat
O 7 não bastou — preciso do motivo da recusa, CPF, correlação 8 - ANALISE PROFUNDA do periodo.bat
Descobri um domínio de ataque 5 - BLOQUEAR dominio novo.bat
Descobri um e-mail ou CPF específico 6 - BLOQUEAR ou LIBERAR email e CPF.bat
Vou mostrar o panorama para a VTEX 9 - ATUALIZAR planilha do panorama.bat
Quero abrir a pasta de resultados 4 - ABRIR a pasta de resultados.bat

Todos param e mostram o erro

Nenhum executável fecha a janela na sua cara quando dá errado. Copie a mensagem e mande para o Claude — é o suficiente para descobrir o que houve.


Onde cada arquivo cai

Tudo que os programas geram vai para saida/, uma pasta por script, com o nome do script. A pergunta que se faz na frente da pasta — de onde veio este arquivo? — se responde sozinha pelo nome. Há um LEIA-ME.txt dentro de saida/ explicando pasta por pasta.

Pasta Vem de O que tem
clientes-travados/ executável 1 As mensagens prontas, a lista de clientes e os descartados como bot
vigia-dominios/ executável 2 vigia-<data>.csv de cada rodada
extrai-infra/ executável 7 infra-*.csv, um por período investigado
vtex-export-oms/ executável 8, etapa 1 A coleta crua: 33 campos por pedido
gerar-xlsx/ executável 8, etapa 2 Card_Testing_VTEX.xlsx
indice-pedidos/ executável 9, etapa 1 Índice de todos os pedidos
monta-planilha/ executável 9, etapa 3 card-testing-2024-2026.xlsx, a planilha do panorama
extrai-negados/, marca-cancelamento/, cruza-quarentena/, parcelas/, listas-de-pedidos/ scripts sem executável Material das análises pontuais
_arquivo-morto/ — Sobras de agosto/2026. Nenhum script gera nem lê. Pode apagar

Nunca apague a pasta extrai-infra

A planilha do panorama é montada juntando todos os infra-*.csv de lá. Apagar um arquivo faz aquele mês sumir do relatório.

Para quem for escrever script novo aqui

Grave com pp.pasta_de("seu-script", "x.csv") no Python ou pastaDe("seu-script", "x.csv") no Node. Script que lê a saída de outro passa a pasta do outro — assim a dependência entre eles fica escrita na própria chamada, como no monta-planilha.py, que lê de extrai-infra, indice-pedidos e marca-cancelamento.


7 — Investigar mês suspeito

Quando: o executável 3 marcou um mês com <<<.

Ele pergunta duas datas e mostra quem está por trás dos pedidos negados daquele período.

Data inicial (ex: 2026-09-01):
Data final   (ex: 2026-09-30):

Formato ano-mês-dia. Para o mês de setembro inteiro: 2026-09-01 até 2026-09-30.

Mês inteiro leva alguns minutos — são duas consultas à VTEX por pedido.

O que sai e como ler

Sai um arquivo em saida\extrai-infra\infra-<data>-a-<data>.csv. Abra no Excel e olhe três colunas:

Coluna O que denuncia
ip Muitos pedidos do mesmo IP = bot
device Mesmo aparelho repetido = bot
bin Vários cartões diferentes = teste de cartão

A régua

Cliente de verdade tem 1 ou 2 tentativas recusadas. Bot tem dezenas.

Achou domínio suspeito → executável 5. Achou e-mail ou CPF específico → executável 6.


8 — Análise profunda

Quando: o 7 mostrou que há ataque, mas você precisa de mais para agir ou para levar à VTEX.

Traz 33 informações por pedido, contra 11 do executável 7. Só aqui aparecem:

  • o motivo real da recusa, escrito pelo banco
  • CPF, nome, telefone e cidade do titular
  • o e-mail sem a máscara da VTEX (-123b.ct.vtex.com.br)
  • quantos cartões diferentes cada CPF queimou — a prova do card testing

Pergunta as mesmas duas datas, roda em duas etapas e monta a planilha saida\gerar-xlsx\Card_Testing_VTEX.xlsx.

É lento — use em período curto

São três consultas por pedido, mais uma pausa entre elas. Rode no período que o 7 já apontou, nunca no ano inteiro. Para varrer meses, o caminho é o 7.

Feche a planilha no Excel antes de rodar

Se o Card_Testing_VTEX.xlsx estiver aberto, a coleta funciona mas a planilha não é gravada — e aí a coleta inteira precisa ser refeita.


9 — Atualizar a planilha do panorama

Quando: a cada 3 ou 4 meses, ou quando for mostrar o panorama do ataque para a VTEX.

A planilha saida\monta-planilha\card-testing-2024-2026.xlsx guarda a história toda do ataque. O executável pergunta a partir de qual mês faltam dados e roda as três etapas na ordem certa.

Nunca apague os arquivos infra-*.csv

A planilha é montada juntando todos eles. Apagar um arquivo faz aquele mês sumir do panorama, e a única forma de recuperar é rodar o 7 de novo naquele período.

Feche a planilha no Excel antes de rodar.


Por dentro — os comandos

Esta parte é a referência técnica, para manutenção ou quando algo sair do esperado. A rotina do dia a dia não precisa dela.

Como abrir o PowerShell

Tecla Windows, digite powershell, Enter. Para colar: botão direito do mouse (não é Ctrl+V).

1. Vigia de domínios — rode toda semana

É o único item que vale colocar na rotina. Descobre domínio de ataque novo antes que ele seja usado em volume.

Executável equivalente: 2 - SEMANAL - dominio de ataque novo.bat

cd "C:\Projetos\vtex-analise"
python vigia-dominios.py          # últimos 7 dias
python vigia-dominios.py 30       # últimos 30 dias

Classifica cada domínio em três situações:

Situação Significado Ação
JÁ COBERTO O validador já bloqueia Nada a fazer
PROVÁVEL REAL MX em Google Workspace, Microsoft 365 ou Cloudflare Não bloqueie — é cliente de verdade cujo cartão foi recusado
INFRA NOVA Servidor desconhecido Único que exige ação. O script já imprime o comando de bloqueio pronto para copiar

Success

Se der "Nenhuma infraestrutura nova", está tudo em dia.

O comando impresso é o wrangler kv key put ... blocklist do Validador de e-mail — lembre que ele substitui a lista inteira.


2. Mapa mensal — taxa de recusa

Executável equivalente: 3 - MENSAL - taxa de recusa.bat

python mapa-mensal.py 2026           # um ano
python mapa-mensal.py 2024 2026      # intervalo

Mostra, mês a mês, quantos pedidos houve e quantos foram negados. Marca com <<< os meses acima de 60%.

Referência

Taxa normal de e-commerce: 10% a 15%. Acima de 50% é ataque.


3. Investigar um período específico

Quando o mapa mensal acusar um mês ruim e você quiser saber quem foi:

Executável equivalente: 7 - INVESTIGAR mes suspeito.bat

python extrai-infra.py 2026-09-01 2026-09-30

Gera saida/extrai-infra/infra-<data>-a-<data>.csv com IP, device, sessão, user-agent, bandeira, BIN e finais do cartão de cada pedido negado.

Warning

Para janela grande demora — são duas chamadas de API por pedido.

Se quiser só os e-mails, sem IP e cartão, é mais rápido:

python extrai-negados.py 2026-09-01 2026-09-30

Por que duas APIs

O OMS da VTEX esconde as recusas dentro do status "Cancelado". Só a API de Pagamentos tem o motivo real da negativa, o IP e o device — por isso o script cruza as duas.

O extrai-infra.py não traz o motivo da recusa

Ele chama a API de Pagamentos, mas extrai dali apenas IP, device, sessão e user-agent — o returnMessage e o returnCode são descartados. Para ter o motivo da recusa, use a ferramenta em Node da seção 4.


4. Análise profunda — a caixa de ferramentas em Node

A pasta tem uma segunda implementação desta mesma investigação, em Node. Foi a primeira versão (19 a 24/08/2026), anterior à reescrita em Python, e não foi aposentada: ela coleta 33 campos por pedido contra os 11 do extrai-infra.py.

Executável equivalente: 8 - ANALISE PROFUNDA do periodo.bat

O que só o Node traz

Campo Por que importa
motivo_pagamento (returnMessage) e codigo_retorno O motivo real da recusa. O extrai-infra.py chama a API de Pagamentos mas não extrai esses campos
adquirente, status_adquirente Qual conector recusou e o que ele respondeu
cpf, nome, telefone, cidade, uf Identificação do titular
email desmascarado O Python devolve o e-mail com a máscara da VTEX (-123b.ct.vtex.com.br); o Node aplica emailReal() e limpa
utm_source, utm_campaign De onde veio o pedido
correlação Mesmo CPF / IP / device em outros pedidos, e quantos cartões distintos por CPF
cd "C:\Projetos\vtex-analise"
node vtex_export_oms.mjs 2026-09-01 2026-09-30   # periodo escolhido
node vtex_export_oms.mjs                          # periodo padrao do topo do arquivo
node gerar_xlsx.mjs                               # monta Card_Testing_VTEX.xlsx

As datas são parâmetro desde 28/08/2026

Antes disso era preciso editar as constantes DE e ATE no topo do arquivo a cada investigação. Hoje elas continuam lá como padrão, usadas quando nenhuma data é passada — rodar sem argumento funciona igual a antes. As datas vão no formato AAAA-MM-DD; qualquer outro formato o script recusa antes de gastar chamada de API.

Qual usar: decida pelo custo de API

Esta é a razão de as duas existirem. O Node é mais completo, mas mais caro:

Ferramenta Chamadas por pedido Campos Quando usar
vigia-dominios.py nenhuma (só lista) — Rotina semanal
extrai-negados.py nenhuma (só lista) e-mail Janela grande
extrai-infra.py 2 11 Janela média — IP, device e cartão
vtex_export_oms.mjs 3 + 240 ms de espera 33 Janela curta — investigação a fundo

Não rode o Node em janela grande

Três chamadas por pedido mais a espera entre elas tornam a varredura de meses inteiros inviável. Para varrer, use o Python; para dissecar um período suspeito já identificado, use o Node.

Credenciais

Python e Node leem o mesmo .env da pasta — o env.mjs é quem faz a ponte para os scripts em Node. O .gitignore bloqueia .env, CSVs e planilhas.


5. Perfil de parcelamento (não é antifraude)

parcelas.mjs responde a uma pergunta comercial, não de segurança: em quantas vezes o cliente real costuma dividir a compra, e em qual bandeira.

Olha só os meses limpos, sem ataque — incluir mês sujo contamina a média, porque pedido de bot é sempre à vista e de valor baixo.

cd "C:\Projetos\vtex-analise"
node parcelas.mjs                      # usa _2025.json desta pasta
node parcelas.mjs caminho\lista.json   # usa outra exportação

Gera parcelas-2025.json com {mes, valor, parcelas, bandeira, valorParcela}. O resultado da rodada de 21/08/2026 já está na pasta: 254 pedidos, nenhuma falha.

Info

A entrada é a lista de pedidos gerada pelo _mensal2025.mjs, na mesma pasta. Sem argumento, o script usa o _2025.json que já está lá.


6. Atualizar a planilha do panorama

A planilha card-testing-2024-2026.xlsx foi gerada com dados até 25/08/2026. Para atualizar com meses novos, rodar os três na ordem:

Executável equivalente: 9 - ATUALIZAR planilha do panorama.bat

python indice-pedidos.py 2024-01 2026-12     # índice de todos os pedidos
python extrai-infra.py 2026-09-01 2026-12-31 # detalhe dos negados novos
python monta-planilha.py                     # consolida

Feche a planilha no Excel antes do terceiro comando

Senão dá erro de permissão.

Warning

O monta-planilha.py lê todos os infra-*.csv da pasta e junta. Não apague os antigos.


Scripts da pasta

Script O que faz Executável
vigia-dominios.py Classifica domínios dos pedidos negados em JÁ COBERTO / PROVÁVEL REAL / INFRA NOVA 2
mapa-mensal.py Taxa de recusa mês a mês 3
extrai-infra.py Detalhe completo dos negados (IP, device, cartão) → infra-*.csv 7
extrai-negados.py Só os e-mails dos negados — versão rápida —
indice-pedidos.py Índice de todos os pedidos do período → indice-pedidos.csv 9
monta-planilha.py Consolida os infra-*.csv em card-testing-2024-2026.xlsx 9
marca-cancelamento.py Marca cancelamentos → cancelamentos.csv —
puxa-pedidos.py Coleta bruta de pedidos da API —
parcelas.mjs Perfil de parcelamento dos meses limpos → parcelas-2025.json —
env.mjs Lê as credenciais do .env. Importado pelos scripts em Node —

Scripts em Node (mesma pasta)

Script O que faz Executável
vtex_export_oms.mjs Coleta os 33 campos por pedido cruzando OMS + Payments + Transaction 8
gerar_xlsx.mjs Monta Card_Testing_VTEX.xlsx a partir do vtex_dados.json 8
_mensal2025.mjs Lista os pedidos de 2025 → _2025.json (entrada do parcelas.mjs) —
_2026.mjs Mesma coisa para 2026 → _2026.json —

Histórico

Data Evento
Julho/2026 Início do ataque de card testing identificado na loja
19/08/2026 Chamado escalado na VTEX
25/08/2026 Validador de e-mail no ar; planilha de panorama 2024–2026 gerada
28/08/2026 Executáveis 7, 8 e 9 criados; vtex_export_oms.mjs passou a aceitar as datas por parâmetro
28/08/2026 saida/ reorganizada: uma pasta por script (antes eram 29 arquivos em saida/investigacao)

Diagnóstico

Sintoma Causa provável e ação
Script retorna 401 / 403 VTEX_APP_KEY ou VTEX_APP_TOKEN inválidos no .env. Regerar em VTEX Admin → Configurações da conta → Chaves de aplicação
Script retorna 429 A VTEX pediu calma. Espere alguns minutos e rode de novo
monta-planilha.py dá erro de permissão Planilha aberta no Excel. Fechar e rodar de novo
Planilha saiu com meses faltando Algum infra-*.csv foi apagado da pasta. Rodar extrai-infra.py (ou o executável 7) para o período faltante
extrai-infra.py demora demais Normal em janela grande — duas chamadas de API por pedido. Quebrar em períodos menores
Preciso do motivo da recusa e o CSV não tem O extrai-infra.py não extrai esse campo. Use o executável 8 (vtex_export_oms.mjs) na janela específica
E-mail no CSV vem com -123b.ct.vtex.com.br Máscara da VTEX. O Python não remove; o vtex_export_oms.mjs remove
Node muito lento ou estourando limite de API Esperado: 3 chamadas por pedido, contra 2 do Python. Use o Python para janela grande
.env nao encontrado ao rodar script Node O env.mjs procura o .env na pasta dele. Confirme que está rodando de dentro do vtex-analise
Data inicial invalida no executável 8 A data precisa ser AAAA-MM-DD — 2026-09-01, não 01/09/2026
Vigia não acha nada há semanas Bom sinal: a blocklist está cobrindo. Confirmar com mapa-mensal.py que a taxa de recusa caiu
Taxa de recusa alta mas domínios são "PROVÁVEL REAL" Não é card testing por e-mail descartável — investigar com o executável 7 (IP e device repetidos indicam bot; BINs variados indicam teste de cartão)