← Voltar ao blog

Checklist de limpeza de malware no Magento 2 para lojistas

Rodrigo Biazzi

Uma loja Magento comprometida geralmente não parece quebrada. O malware mais comum em sites de ecommerce é o skimmer de pagamento: algumas linhas de JavaScript que copiam os dados do cartão do formulário de checkout e os enviam para outro lugar. A loja continua vendendo, e o dono descobre semanas depois pelo provedor de pagamento, por um banco ou por um cliente.

Este checklist é para lojistas e desenvolvedores que suspeitam de um comprometimento. Cobre como confirmar, como limpar sem deixar uma porta dos fundos, e como fazer o hardening da loja depois. Não substitui uma resposta a incidentes profissional quando há dados de cartão envolvidos, mas descreve o trabalho que precisa ser feito de qualquer forma.

Sinais de que algo está errado

  • O provedor de pagamento ou o banco adquirente reporta fraude ligada à sua loja
  • Um scanner de segurança, como o Security Scan Tool gratuito da Adobe, reporta malware ou um skimmer conhecido
  • Usuários admin que você não reconhece, ou integrações que ninguém criou
  • JavaScript inesperado carregado no checkout de um domínio que você não conhece, visível na aba network das ferramentas de desenvolvedor do navegador
  • Arquivos PHP novos em pastas que só deveriam ter imagens ou arquivos estáticos
  • Carga do servidor ou tráfego de saída que não combina com a atividade normal da loja

Qualquer um desses basta para iniciar o processo abaixo. Não espere um segundo sinal.

1. Contenha antes de investigar

Se o skimmer está ativo, cada pedido expõe mais um cliente. Decida rápido se vai colocar a loja em modo de manutenção ou desativar os pagamentos com cartão até a limpeza terminar. É uma decisão de negócio, mas deve ser tomada em horas, não em dias.

Depois, preserve as evidências antes de mudar qualquer coisa:

  • Uma cópia completa da pasta de código, incluindo vendor, generated e pub
  • Um dump do banco
  • Logs de acesso do servidor web e logs do PHP, pelo maior período que existirem

Guarde essas cópias fora do servidor. Você vai precisar delas para achar o ponto de entrada, e pode precisar delas para o provedor de pagamento ou para um investigador forense. Se houve dados de cartão envolvidos, procure seu provedor de pagamento cedo. O PCI DSS e leis de privacidade como a GDPR podem exigir notificação formal em prazos curtos.

2. Descubra o que mudou nos arquivos

Se o projeto está no Git, a checagem mais rápida é comparar o servidor com o repositório:

cd /var/www/shop
git status --porcelain
git diff --stat

Para o vendor, compare com uma instalação nova. Rode composer install numa pasta limpa separada a partir do mesmo composer.lock e compare:

diff -rq /tmp/clean-build/vendor /var/www/shop/vendor

Sem Git, procure arquivos que não deveriam existir e arquivos PHP modificados recentemente:

find pub/media pub/static var -type f -name "*.php"
find app pub vendor -type f -name "*.php" -mtime -30 -printf "%TY-%Tm-%Td %p\n" | sort
grep -rlE "eval\(|base64_decode\(|gzinflate\(|str_rot13\(" app/code pub --include=*.php

O grep vai pegar algum código legítimo, então leia cada resultado antes de decidir. Atacantes também alteram os timestamps dos arquivos, então um arquivo que parece antigo não é prova de que está limpo. Por isso reconstruir a partir de uma fonte conhecida no passo 4 importa mais do que achar todos os arquivos.

Verifique também lugares fora do web root: o crontab do usuário web, arquivos no diretório home e quaisquer scripts de inicialização. Reinfecção por um job agendado é um motivo comum para uma loja limpa ser infectada de novo.

3. Descubra o que mudou no banco

Muitos skimmers vivem só no banco, porque nenhum scan de arquivos os encontra ali. Os lugares usuais são campos de configuração que renderizam HTML e o conteúdo CMS.

SELECT config_id, scope, scope_id, path
FROM core_config_data
WHERE value LIKE '%<script%' OR value LIKE '%eval(%' OR value LIKE '%atob(%';

SELECT block_id, identifier, update_time
FROM cms_block
WHERE content LIKE '%<script%';

SELECT page_id, identifier, update_time
FROM cms_page
WHERE content LIKE '%<script%';

Preste atenção especial às configurações de design para o head e o footer do HTML, que ficam em core_config_data em caminhos começando com design/. Algumas lojas adicionam scripts de tracking ali de forma legítima, então compare cada resultado com o que o time de marketing sabe que adicionou.

Depois verifique os acessos:

SELECT user_id, username, email, created, logdate, is_active FROM admin_user;
SELECT integration_id, name, email, status, created_at FROM integration;

Apague usuários admin e integrações que ninguém consiga explicar. Verifique também as widget instances e os email templates se a sua loja os customiza, já que os dois podem guardar markup.

4. Reconstrua a partir de uma fonte limpa conhecida

Limpar arquivos infectados um a um deixa uma chance real de perder algum. A abordagem confiável é reconstruir o código:

  1. Comece pelo seu repositório Git num commit anterior ao comprometimento, ou de uma instalação limpa do Composer das mesmas versões.
  2. Revise o código customizado em app/code e o tema contra o repositório. Tudo que não está no controle de versão precisa ser lido linha por linha ou substituído.
  3. Rode composer install para recriar o vendor a partir do lock file.
  4. Regenere o código gerado e o static content com setup:di:compile e setup:static-content:deploy. Não copie generated, pub/static ou var do servidor antigo.
  5. Copie o pub/media só depois de checar se há scripts nele, e confirme que o servidor web não executa PHP a partir da media.
  6. Faça o deploy num servidor novo, ou recém-instalado, se não der para descartar que o próprio sistema operacional foi comprometido.

5. Troque todas as credenciais

Assuma que o atacante leu o app/etc/env.php. Troque:

  • A senha do usuário do banco
  • Todas as senhas de admin, e resete o 2FA de todo usuário admin
  • Chaves de API do gateway de pagamento, credenciais de frete e ERP, e qualquer outro segredo guardado na configuração
  • Chaves SSH, painel de hospedagem e senhas de SFTP
  • Tokens de integração e de API
  • A encryption key do Magento, seguindo a orientação da Adobe para a sua versão, porque valores criptografados com a chave antiga eram legíveis para quem a tivesse

6. Feche o ponto de entrada

Uma loja limpa mas não atualizada será comprometida de novo, muitas vezes em dias. Use os logs que você preservou para descobrir como o atacante entrou. As causas usuais:

  • Security patches do Magento faltando. Faça o upgrade para a última patch release da sua versão. Veja o guia de security patches.
  • Uma extensão de terceiros vulnerável. Atualize ou remova, e revise as demais. O checklist de auditoria de extensões mostra como.
  • Credenciais de admin roubadas sem 2FA.
  • Acesso fraco ao servidor: senhas SSH compartilhadas, portas de banco expostas, painéis de controle antigos.

7. Faça o hardening e monitore

  • Negue a execução de PHP em pub/media e pub/static no servidor web. A config de exemplo do Nginx do Magento já faz isso, então confira se a sua config ainda tem.
  • Restrinja o admin por IP ou VPN e mantenha a autenticação de dois fatores ativa. Veja o checklist de hardening do admin.
  • Deixe o código somente leitura para o usuário do servidor web em produção, com acesso de escrita só para var, generated, pub/static e pub/media.
  • Adicione uma Content Security Policy que restrinja de onde o checkout pode carregar scripts e para onde pode enviar dados. O Magento 2.4.7 e posteriores aplicam CSP nas páginas de pagamento.
  • Monitore mudanças de arquivos e os campos de configuração listados no passo 3, e agende scans externos regulares.

Depois da limpeza, continue observando por algumas semanas. Se a mesma injeção voltar, o ponto de entrada ainda está aberto.

FAQ

Como sei se minha loja Magento tem um skimmer de cartão?

Abra o checkout com as ferramentas de desenvolvedor do navegador e procure scripts ou requisições para domínios desconhecidos. Procure também tags script em core_config_data e no conteúdo CMS, e rode um scan externo de malware.

Basta apagar os arquivos infectados?

Em geral não. Atacantes deixam portas dos fundos em vários lugares, incluindo o banco e o cron. Reconstrua o código a partir de uma fonte limpa, limpe o banco e troque todas as credenciais.

Preciso notificar alguém depois de uma invasão no Magento?

Se dados de pagamento ou pessoais foram expostos, o PCI DSS e leis de privacidade como a GDPR podem exigir notificar o provedor de pagamento, as autoridades e os clientes. Busque orientação cedo, porque os prazos podem ser curtos.

Como o atacante entrou?

As causas mais comuns são security patches faltando, extensões vulneráveis e senhas de admin roubadas. Confira seus logs de acesso de antes da data da infecção para achar o ponto de entrada exato.

Atendo como freelancer em Magento e Adobe Commerce, incluindo limpeza e hardening depois de um comprometimento. Se você precisa de ajuda com isso, fale comigo.

Artigos relacionados