Você abre o banco de um site e encontra, no meio da tabela wp_options, um bloco de código que ninguém colocou ali. Ou pior: o site começa a redirecionar para domínios estranhos, e você desconfia que o problema não está nos arquivos, mas nas consultas que o WordPress faz ao banco. SQL injection WordPress é exatamente isso: alguém conseguiu inserir comandos SQL através de um campo de formulário, parâmetro de URL ou plugin vulnerável, e agora o banco carrega instruções que não deveriam existir.
O sintoma nem sempre é óbvio. Às vezes o site funciona normalmente, mas há registros novos em wp_users, links estranhos em wp_posts ou opções com nomes aleatórios em wp_options. Em outros casos, a página inicial é substituída por um redirecionamento ou o painel administrativo fica lento. A diferença entre um site com SQL injection e um site apenas invadido por outro vetor está no rastro: a injeção deixa marcas no banco, não só nos arquivos.
Por que SQL injection WordPress é tão comum em plugins e temas
O WordPress em si, quando mantido atualizado, tem boa proteção contra injeção SQL. O problema está no código de terceiros. Plugins e temas que montam consultas concatenando strings em vez de usar prepared statements abrem a porta. Um exemplo clássico é uma função que recebe um parâmetro de URL e o insere direto na cláusula WHERE, sem sanitização.
Além disso, plugins abandonados ou sem atualização recente são alvos fáceis. Se você administra vários sites, a chance de um deles ter um plugin vulnerável é alta. Por isso, a triagem de vulnerabilidades em plugin WordPress é uma etapa que não pode ser pulada.
Outro ponto: temas antigos, principalmente os que usam campos personalizados sem validação, também podem ser vetores. O atacante não precisa de acesso ao painel; basta encontrar um parâmetro que chegue ao banco sem tratamento.
Como diagnosticar SQL injection WordPress em vários sites
Antes de sair limpando, é preciso confirmar. A ordem de verificação abaixo funciona tanto para um site quanto para dezenas, e pode ser feita via WP-CLI ou phpMyAdmin.
- Verifique a tabela wp_options. Procure por opções com nomes aleatórios, valores contendo
<script>,base64_decodeoueval. Um comando útil éSELECT option_name, option_value FROM wp_options WHERE option_value LIKE '%<script%' OR option_value LIKE '%base64%';. Em vários sites, rode isso em cada banco. - Inspecione wp_postmeta e wp_usermeta. Injeções persistentes costumam se esconder em metadados. Procure por meta_values com tags script ou redirecionamentos. Exemplo:
SELECT * FROM wp_postmeta WHERE meta_value LIKE '%<script%';. - Cheque wp_posts e wp_users. Posts com conteúdo estranho, usuários novos com nomes aleatórios ou e-mails suspeitos. A auditoria de logins WordPress: auditar admins em vários sites ajuda a identificar contas criadas pelo atacante.
- Analise os logs de acesso. Procure por requisições com parâmetros que contenham
UNION SELECT,OR 1=1ou--. Se o servidor tiver logs, essa é a prova mais direta.
Em um parque de sites, automatize essa varredura. Um script simples que percorre os bancos e aplica as consultas acima economiza horas. Ferramentas de gerenciamento em massa, como o 100% WP, ajudam a rodar comandos WP-CLI em todos os sites de uma vez, mas o diagnóstico manual ainda é necessário para interpretar os resultados.
Portas de entrada mais comuns
Nem toda injeção vem de um plugin famoso. Muitas vezes é um plugin pequeno, sem atualização há meses, que faz consultas diretas. Outras vezes, é um tema comprado em marketplaces duvidosos. A tabela abaixo resume os vetores mais frequentes.
| Vetor | Como identificar | Prioridade |
|---|---|---|
| Plugin desatualizado | Versão antiga, sem atualizações recentes | Alta |
| Tema com consultas customizadas | Funções que usam $wpdb->query sem prepare |
Alta |
| Formulários de contato | Campos que vão direto para o banco | Média |
| Parâmetros de URL | Requisições com ?id= ou ?cat= sem validação |
Média |
Se você tem vários sites, comece pelos que usam plugins em comum. Um plugin vulnerável pode estar em todos eles, e a injeção pode ter atingido cada banco de forma independente.
Como prevenir SQL injection WordPress na prática
Prevenir é mais barato que limpar. As medidas abaixo valem para qualquer site, mas em escala exigem padronização.
- Atualize tudo. Plugins, temas e o core. Uma atualização de segurança WordPress em vários sites pode ser agendada e executada em lote. Não deixe para depois.
- Use prepared statements. Se você desenvolve, nunca concatene variáveis em consultas. Use
$wpdb->prepare(). A documentação oficial do WordPress explica o método em detalhes: developer.wordpress.org/reference/classes/wpdb/prepare/. - Sanitize entradas. Todo dado que vem do usuário deve ser validado. Funções como
sanitize_text_field()eesc_sql()ajudam, mas não substituem o prepare. - Restrinja permissões de banco. O usuário do banco não precisa de permissões de DROP ou ALTER. No mínimo, apenas SELECT, INSERT, UPDATE e DELETE.
- Monitore alterações. Ferramentas que comparam o banco antes e depois de atualizações ajudam a detectar injeções persistentes.
Além disso, um hardening de segurança WordPress instalação: hardening em vários sites inclui remover plugins inativos, desabilitar edição de arquivos e limitar tentativas de login.
Limpar o banco ou restaurar backup?
Essa é a decisão mais difícil. Se a injeção já está persistida, limpar manualmente pode deixar rastros. O critério é simples: se você tem um backup íntegro e recente, anterior à injeção, restaurar é mais seguro. Se não tem, ou se o backup é antigo demais, a limpeza é o caminho.
Para limpar, remova os registros maliciosos das tabelas afetadas. Mas atenção: remover apenas a linha visível pode não ser suficiente. O atacante pode ter criado um cron job ou uma opção que recria a injeção. Verifique também wp_options por chaves como cron e siteurl.
Se a limpeza for necessária, faça em um ambiente de teste primeiro. Depois de limpar, monitore o site por alguns dias para garantir que a injeção não voltou. Em vários sites, esse monitoramento precisa ser simultâneo.
Quando NÃO usar essa abordagem
Se o site faz parte de um ambiente com compliance rígido, como PCI DSS, a limpeza manual pode não ser aceita. Nesses casos, a restauração de um backup verificado é obrigatória. Além disso, se você não tem acesso ao banco via SSH ou phpMyAdmin, e o painel da hospedagem não oferece ferramentas de consulta, talvez seja melhor contratar um serviço especializado antes de tentar qualquer coisa.
Outro cenário: se a injeção atingiu o core do WordPress, não apenas plugins, a limpeza pode ser inútil. O melhor é reinstalar o core e restaurar o banco.
Erros comuns ao lidar com SQL injection WordPress
- Apagar apenas o que é visível. A injeção pode estar em metadados ou opções ocultas.
- Não trocar as senhas. Depois de uma injeção, todas as senhas de administrador devem ser trocadas, incluindo a do banco.
- Ignorar outros sites. Se um site foi atingido, os outros que compartilham o mesmo plugin ou tema também podem estar vulneráveis.
- Confiar apenas em plugins de segurança. Eles ajudam, mas não substituem a correção do código vulnerável.
Para uma visão mais ampla, vale conferir o guia sobre site WordPress hackeado: diagnosticar e limpar em vários sites, que cobre outros vetores.
Prevenção contínua em vários sites
Depois de resolver a injeção, o trabalho não acaba. É preciso manter a vigilância. Uma rotina de atualizações semanais, varreduras mensais no banco e revisão de plugins instalados reduz muito o risco. Se você administra dezenas de sites, automatizar essas tarefas é essencial. O 100% WP permite gerenciar atualizações, backups e monitoramento de segurança em todos os sites de um único painel, o que ajuda a fechar a porta antes que o próximo ataque aconteça.
Por fim, se a injeção já causou danos graves ou você não se sente seguro para limpar o banco, considere contratar um serviço especializado em remoção de malware e segurança. Em muitos casos, o custo de uma limpeza malfeita é maior que o de um serviço profissional.


