Nenhuma das dez falhas críticas de WordPress de 2026 estava no core — todas em plugin ou tema, e quatro terminam em escrita de arquivo. Por isso a trava de maior retorno não é atualizar: é negar execução de PHP em wp-content/uploads, que barra a classe inteira. Guia em 21 travas, com o custo real das 5 que quebram alguma coisa.
- Zero falhas críticas no core em 2026: o furo veio de plugin e tema.
- Negar PHP em wp-content/uploads teria contido a CVE-2026-32475 do Elementor Pro mesmo sem o patch 4.2.2.
- Priorize atualização por superfície: upload, backup, migração, pagamento e tradução na frente.
- Cinco travas cobram caro: DISALLOW_FILE_MODS, identidade na frente do wp-admin, bloqueio de XML-RPC, disable_functions e a exceção de cache em uploads.
- Esconder versão e trocar prefixo de tabela em site rodando não é hardening, é cortina.
- Plugin de segurança não aplica regra de servidor, constante de wp-config nem permissão de arquivo.
Todo checklist de hardening de WordPress que circula em português começa pelo mesmo lugar: esconda a versão do core, mude o prefixo da tabela, instale um plugin de segurança. Fomos medir o que de fato abriu buraco em site WordPress em 2026 e a lista não bate com o checklist. Nenhuma das falhas críticas do período estava no core. Todas estavam em plugin ou tema — e quase metade delas terminava no mesmo lugar: um arquivo escrito dentro de wp-content/uploads.
Isso muda a ordem de prioridade. Este é um guia de hardening WordPress em 21 travas, agrupadas por camada, na ordem em que elas realmente reduzem risco — e com a parte que os checklists omitem: o que cada trava custa. Cinco delas quebram alguma coisa que provavelmente funciona hoje no seu site. Elas estão marcadas, com o que quebra e o que fazer a respeito.
O que realmente arrombou WordPress em 2026 (e não foi o core)
A tabela abaixo reúne as falhas críticas divulgadas em plugins e temas populares ao longo de 2026, com a versão corrigida de cada uma. Todas são públicas e todas já têm correção disponível. Elas estão aqui por um motivo: o padrão que formam é o argumento deste guia inteiro.
| Plugin / tema | CVE | CVSS | Como entra | Corrigido em |
|---|---|---|---|---|
| GiveWP | CVE-2026-82222 | 10.0 | PHP object injection → execução remota | acima de 4.16.7.1 |
| Forminator Forms | CVE-2026-15748 | 9.8 | Upload de arquivo arbitrário sem login | 1.56.2 (31/07) |
| Avada + Fusion Builder | CVE-2026-18431 | 9.8 | Escrita arbitrária de arquivo → execução remota | acima de 7.16 / 3.16 |
| The Events Calendar | CVE-2026-78006 | 9.8 | Cadeia explorável sem login nem interação | acima de 6.17.4 |
| The Events Calendar | CVE-2026-78159 | 9.8 | Segunda cadeia independente, mesmo perfil | acima de 6.17.3 |
| TranslatePress | CVE-2026-19632 | 9.8 | Exposição de URL de reset de senha → conta de admin | acima de 3.3.1 |
| Pods | CVE-2026-19598 | 9.8 | Escalada de privilégio até administrador | acima de 3.3.9 |
| WPMU DEV Dashboard | CVE-2026-76581 | 9.8 | Bypass de autenticação | acima de 5.0.1 |
| Elementor Pro (Forms) | CVE-2026-32475 | 9.0 | Upload sem login grava .php em uploads | 4.2.2 (19/08) |
| All-in-One WP Migration | CVE-2026-19949 | 8.8 | SQL injection de segunda ordem no restore → execução remota | 7.110 (20/08) |
Fontes primárias das duas mais relevantes para quem usa page builder: o relato da falha do Elementor Pro, o lote de cinco falhas críticas de plugin e tema e a cobertura da falha do Forminator, com cerca de 300 mil sites expostos. No mesmo período, o que o core entregou foi manutenção: a 7.0.3 saiu com correções de rotina — destrinchamos elas em o que mudou na 7.0.3 e qual correção é a sua.
A conta que muda a ordem do checklist
Olhe a coluna “como entra” e conte. Das dez entradas da tabela, quatro terminam em escrita de arquivo: upload sem login no Forminator, upload sem login no Elementor Pro, escrita arbitrária no Avada e restore de arquivo malicioso no All-in-One WP Migration. Duas são escalada de privilégio, duas são bypass ou vazamento de credencial, uma é injeção de objeto, uma é injeção de SQL que vira execução remota.
O grupo de escrita de arquivo é o maior e é o único em que uma única trava de servidor barra todos de uma vez. No caso do Elementor Pro, o arquivo malicioso vai parar em wp-content/uploads/elementor/forms/ com extensão .php. O ataque só vira execução remota porque o servidor concorda em executar PHP naquele diretório. Um servidor configurado para servir uploads como conteúdo estático transformaria uma falha nota 9.0 em um arquivo inerte sentado no disco.
É por isso que a trava número 6 deste guia não é a sexta em importância — ela é a primeira em retorno. Ela não depende de você acompanhar boletim de CVE, não depende de você atualizar no mesmo dia, e continua valendo para a próxima falha de upload, que ainda nem foi descoberta. Atualizar plugin é obrigatório e continua sendo obrigatório; a diferença é que a atualização protege contra a falha que você já conhece, e a trava de servidor protege contra a classe.
O outro recado da tabela é sobre quais plugins merecem atenção desproporcional: formulário, upload, backup, migração, pagamento e tradução. São os que tocam arquivo, banco e credencial. Um plugin de “adicionar ícone social no rodapé” não tem a mesma superfície.
Camada 1 — Superfície: o que você instalou (travas 1 a 5)
1. Faça o inventário e apague o que está desativado. Plugin desativado continua no disco. Se o arquivo for alcançável por URL, parte do código dele pode ser executada sem que o WordPress tenha “ligado” o plugin. Desativar não é remover. Remova.
2. Priorize atualização por superfície, não por ordem da lista. Os plugins que aceitam upload, fazem backup, processam pagamento ou gravam arquivo vão para o topo da fila de atualização. O resto pode esperar a janela semanal. Olhando a tabela de 2026, essa regra sozinha teria colocado Elementor Pro, Forminator e All-in-One WP Migration na frente.
3. Assine um feed de vulnerabilidade do seu stack. O painel do WordPress avisa que existe versão nova, não que existe falha crítica explorada. São coisas diferentes e chegam em tempos diferentes. Uma lista de CVE filtrada pelos plugins que você realmente usa cabe em cinco minutos de leitura por semana.
4. Nada de tema ou plugin pirateado. Isso não é conselho moral, é aritmética de risco: o código já está modificado por alguém que não é o autor, e a modificação é justamente a parte que você não consegue auditar. A falha grave que documentamos no tema XStore estava na versão oficial — imagine a versão adulterada.
5. Liste quem recebe arquivo sem login. Abra cada formulário público do site e responda: ele tem campo de upload? Se tem, esse é o ponto exato da superfície que a tabela acima explorou quatro vezes. Se o campo não é necessário, remova; se é, ele precisa da trava 6 obrigatoriamente. Vale abrir o site como visitante deslogado e percorrer: contato, orçamento, candidatura, suporte.
Camada 2 — A trava que neutraliza a classe inteira (travas 6 a 8)
6. Negue execução de PHP dentro de wp-content/uploads. É a trava de maior retorno do guia. Em Apache ou LiteSpeed, um .htaccess dentro da pasta de uploads:
# wp-content/uploads/.htaccess
<FilesMatch ".(?i:php|phtml|php3|php4|php5|php7|php8|phps|pht|inc)$">
Require all denied
</FilesMatch>Em Nginx, no bloco do site:
location ~* ^/wp-content/uploads/.*.(php|phtml|php[0-9]|phps|pht|inc)$ {
deny all;
return 403;
}Depois de aplicar, teste. Suba um arquivo de texto inofensivo chamado teste-hardening.php pela biblioteca de mídia e chame a URL dele no navegador. Se vier 403, a trava está de pé. Se o conteúdo aparecer interpretado, ela não está. Apague o arquivo depois do teste.
7. Separe o diretório de upload do diretório de execução. Onde a hospedagem permite, uploads ficam fora da raiz web e são servidos por um handler. Onde não permite — e a maioria da hospedagem compartilhada não permite —, a trava 6 é o substituto viável. Vale saber que é um substituto, não um equivalente.
8. Desligue o editor de arquivos do painel. No wp-config.php, antes da linha que manda parar de editar:
define( 'DISALLOW_FILE_EDIT', true ); // some com o editor de tema/plugin
define( 'DISALLOW_FILE_MODS', true ); // some também com instalar/atualizar pelo painelA primeira constante fecha o caminho mais curto entre “roubaram a senha de um administrador” e “executam código no seu servidor”: o editor de temas embutido no painel. A segunda é mais dura e está entre as cinco que quebram alguma coisa — volte nela na seção de custos. A documentação oficial do wp-config.php lista as demais constantes disponíveis.
Camada 3 — Acesso e identidade (travas 9 a 13)
9. Nenhum usuário chamado “admin”, e login diferente do nome público. O WordPress expõe o slug do autor nas URLs de arquivo. Se o login for igual ao slug, você entregou metade da credencial. Crie um usuário administrativo novo com login distinto, migre o conteúdo do antigo e apague o antigo.
10. Segundo fator obrigatório para todo mundo que publica. Não só para administrador: qualquer conta com permissão de editar conteúdo é um caminho para injetar script. Segundo fator resolve, de uma vez, força bruta, credencial vazada em outro serviço e senha reaproveitada.
11. Uma credencial de aplicação por integração, com usuário de serviço dedicado. Esta é prática nossa, não teoria. Publicamos neste site por API, e a conta que publica não é a conta de ninguém: é um usuário de serviço com uma senha de aplicação própria. O ganho não é impedir a invasão — é poder revogar uma integração às três da manhã sem derrubar as outras e sem trocar a senha de uma pessoa. Uma credencial compartilhada entre três automações é uma credencial que ninguém revoga.
12. Ponha o /wp-admin e o /wp-login.php atrás de uma camada de identidade. Um proxy de acesso na borda exige autenticação antes de a requisição chegar ao PHP. É o fim da força bruta em wp-login.php, e é o fim do enumeramento de usuário. Também é a trava que mais quebra coisa — está na lista de custos adiante, com o que ela nos quebrou de verdade.
13. Limite tentativa de login e feche o XML-RPC se você não usa. O xmlrpc.php aceita múltiplas tentativas de autenticação em uma única requisição, o que torna a força bruta barata. Se nada no seu fluxo depende dele, bloqueie no servidor. Se alguma coisa depende — veja a seção de custos antes de bloquear.
Camada 4 — Arquivo, banco e processo (travas 14 a 17)
14. Permissões de arquivo no padrão, sem exceção herdada. Diretórios 755, arquivos 644, wp-config.php em 640 ou 600. O 777 que alguém aplicou em 2019 para “resolver o upload” continua lá até que alguém procure. Procure. O handbook oficial de hardening traz a matriz completa por tipo de hospedagem.
15. Rotacione as chaves de autenticação depois de qualquer suspeita. As oito constantes de salt do wp-config.php assinam os cookies de sessão. Trocar as oito derruba todas as sessões abertas no mundo, inclusive a do invasor que ainda está logado com um cookie válido. É um dos poucos botões que expulsa alguém de dentro.
16. Privilégio mínimo no usuário do banco — sabendo o que isso não resolve. O usuário do banco não precisa de GRANT, FILE nem SUPER. Isso reduz o estrago de um acesso direto ao MySQL. Não reduz quase nada contra SQL injection no próprio WordPress, porque a consulta maliciosa roda com exatamente as permissões que o site já tem. Foi o caso do All-in-One WP Migration. Aplique, e não conte com isso como defesa principal.
17. Mantenha o PHP em versão com suporte e restrinja função perigosa quando puder. PHP fora de suporte não recebe correção de segurança, e o WordPress não consegue compensar isso. Onde a hospedagem deixa configurar disable_functions, desligar exec, shell_exec, passthru e system encurta bastante o que um webshell consegue fazer depois de entrar. Também está na lista de custos.
Camada 5 — Borda e detecção (travas 18 a 21)
18. Firewall de aplicação na borda, com correção virtual. O valor real de um WAF não é bloquear o ataque genérico — é te dar dias de folga entre a divulgação de uma CVE e a sua janela de atualização. Regras de correção virtual costumam chegar no mesmo dia do anúncio.
19. Monitore integridade de arquivo. A pergunta que você quer conseguir responder em trinta segundos é: o que mudou dentro de wp-content nas últimas 24 horas? Sem uma linha de base, essa pergunta leva um dia. Com ela, leva um comando. É assim que se descobre um webshell antes do cliente descobrir.
20. Backup fora do servidor, com restauração testada. Backup que mora no mesmo disco do site é backup que o invasor também criptografa. E há a ironia de 2026: o plugin de backup mais instalado do ecossistema foi o próprio vetor de uma falha nota 8.8. A lição não é abandonar backup, é parar de tratar a ferramenta de backup como infraestrutura confiável só porque o nome dela diz “backup”. Teste a restauração pelo menos uma vez por trimestre, em ambiente separado.
21. Escreva o plano dos primeiros trinta minutos. Quem tira o site do ar, para onde aponta o DNS, quem avisa o cliente, onde está o backup mais recente sabidamente limpo, quem tem acesso ao painel da hospedagem. Um documento de uma página, escrito com o site funcionando, vale mais que qualquer plugin. Se precisar de um ponto de partida para redigir política de dados e avaliação de risco, temos prompts prontos para escrever uma política de proteção de dados para site e para montar a avaliação de risco do projeto.
As 5 travas que quebram alguma coisa
Nenhum checklist conta esta parte, e é ela que faz o hardening voltar atrás na semana seguinte. As cinco abaixo funcionam — e cobram.
Trava 6 (negar PHP em uploads) — quebra: raro, mas existe. Alguns plugins de cache e de otimização geram arquivos PHP dentro de wp-content. Se eles gerarem dentro de uploads, param. O sintoma é imediato e o diagnóstico é fácil: 403 em um caminho de uploads no log. A saída é uma exceção nominal para aquele caminho específico, nunca desligar a regra inteira.
Trava 8b (DISALLOW_FILE_MODS) — quebra: atualização pelo painel. Com ela ligada, some o botão de atualizar plugin. Você passa a depender de linha de comando ou do painel da hospedagem para qualquer atualização. Em site que você opera com disciplina, é excelente. Em site de cliente que se atualiza sozinho, é a receita para ficar seis meses desatualizado — que é pior do que o risco que a constante evita. Decida pelo perfil de operação, não pelo checklist.
Trava 12 (identidade na frente do /wp-admin) — quebra: toda automação externa. Esta é a nossa cicatriz. O painel deste site fica atrás de uma camada de identidade e isso funciona: força bruta em wp-login.php simplesmente não chega ao PHP. O custo apareceu do outro lado: qualquer ferramenta que precise abrir o painel passa a esbarrar na mesma parede — inclusive a nossa. Já tivemos que resolver por arquivo, via painel da hospedagem, tarefa que em um site comum seriam dois cliques no wp-admin. Foi assim, por exemplo, que corrigimos o cache do sitemap que servia cópia velha: sem painel, por arquivo. Se você depende de automação, planeje a rota de serviço antes de ligar a camada de identidade — seja um token de contorno para a API, seja um caminho de exceção. Descobrir isso depois custa uma tarde.
Trava 13 (bloquear XML-RPC) — quebra: aplicativo móvel, Jetpack e pingback. O aplicativo oficial do WordPress, parte das integrações do Jetpack e o sistema de pingback usam o xmlrpc.php. Se alguém da equipe publica pelo celular, você vai descobrir do jeito ruim. Confira quem usa antes de bloquear.
Trava 17 (disable_functions) — quebra: backup, imagem e deploy. Vários plugins de backup chamam exec para compactar. Bibliotecas de imagem chamam binário externo. Desligar as quatro funções de execução é ótimo e vai quebrar algo — descubra o quê em ambiente de teste, não em produção numa sexta-feira.
O que não adianta (e continua em todo checklist)
Esconder a versão do WordPress. O número da versão sai no CSS, no JS, no feed e no comportamento do próprio core. Um scanner leva menos de um segundo para inferir. Isso não é uma trava, é uma cortina.
Trocar o prefixo da tabela num site que já existe. Em instalação nova, é grátis e não custa nada fazer. Em site rodando, a migração mexe em valores serializados espalhados por wp_options e usermeta, e o ganho contra SQL injection moderna é próximo de zero — a consulta maliciosa lê o prefixo real do próprio banco.
Renomear o wp-login.php sem nada atrás. Muda o endereço, não o mecanismo. Um scanner acha o novo endereço pelo redirecionamento. Vale como redução de ruído no log, não como controle de acesso.
Achar que um plugin de segurança é o hardening. Ele cobre parte das travas 18 e 19 e ajuda na 13. Não cobre a 6, a 8, a 14, a 16 nem a 17 — porque essas são de servidor e de configuração, e nenhum plugin as aplica por você. Um plugin de segurança sozinho é a parte mais fácil do trabalho.
Como saber se já entraram
Antes de aplicar qualquer trava, vale gastar quinze minutos checando se o site já está comprometido — porque aplicar hardening sobre um site invadido só dificulta a limpeza.
Os sinais mais confiáveis: usuário administrador que ninguém criou; arquivo PHP com data recente dentro de wp-content/uploads; tarefa agendada desconhecida no cron do WordPress; index.php ou wp-config.php com data de modificação que não bate com nenhuma atualização; e o clássico — o site aparecendo na busca com títulos em outro idioma que você nunca escreveu.
Um comando resolve o mais urgente, se você tem acesso a terminal:
find wp-content/uploads -name "*.php" -mtime -30 -lsEm uma instalação saudável, a saída é vazia. Qualquer linha aí merece investigação imediata. Se encontrar algo, não comece pelo hardening: comece pela limpeza. Escrevemos o roteiro completo em como limpar um site WordPress invadido.
Hardening WordPress em uma tarde: a ordem de aplicação
Se você tem quatro horas e um site em produção, esta é a sequência que entrega mais risco eliminado por minuto gasto. Ela deliberadamente deixa as travas caras para o fim.
- Backup completo e testado, fora do servidor. Nada começa antes disso.
- Varredura de comprometimento (a seção anterior). Se achou algo, pare e limpe.
- Inventário: remova plugin desativado, atualize quem toca arquivo e credencial.
- Trava 6: negar PHP em uploads, e testar com um arquivo de prova.
- Travas 9 e 10: usuário administrativo novo e segundo fator em todo mundo que publica.
- Travas 8 e 14:
DISALLOW_FILE_EDITe revisão de permissões. - Travas 18 a 21: firewall de borda, integridade de arquivo, backup externo, plano escrito.
- Só então avalie as caras: 8b, 12, 13 e 17 — cada uma com teste em ambiente separado.
Repare que a ordem não é a ordem da numeração. Numeração é organização por camada; esta lista é organização por retorno. Se a tarde acabar no passo 5, o site já está em outro patamar.
O próximo passo
Hardening é configuração, e configuração envelhece. O que mantém o ganho é a rotina: uma janela semanal de atualização priorizada por superfície, uma revisão trimestral das travas e um teste de restauração de backup por trimestre. Três compromissos de calendário valem mais que qualquer plugin pago.
Se você quer a versão curta e introdutória deste assunto, temos sete dicas fundamentais de segurança no WordPress — é o ponto de partida, e este guia é a camada de cima. Se o seu problema é o oposto e o site está lento em vez de exposto, medimos as causas em Elementor lento: 18 causas e o fix que medimos.
E se você prefere aprender isso construindo em vez de lendo, é exatamente o que fazemos no curso de WordPress de verdade e na mentoria: configuração de servidor, operação e as decisões que não cabem em checklist. Para aprofundar do lado do código, a documentação oficial de segurança para desenvolvedores cobre sanitização, escape e nonces — a metade do problema que mora no tema e no plugin que você mesmo escreve.
Perguntas frequentes
Qual é a trava de hardening de WordPress com maior retorno?
Negar a execução de PHP dentro de wp-content/uploads. Das dez falhas críticas de plugin e tema de 2026, quatro terminam em escrita de arquivo — inclusive a CVE-2026-32475 do Elementor Pro, que grava um .php em wp-content/uploads/elementor/forms/. Se o servidor não executa PHP naquele diretório, o arquivo fica inerte.
Preciso de um plugin de segurança se já fiz o hardening?
Ele ajuda, mas cobre pouco do checklist. Um plugin de segurança atua sobre firewall, monitoramento e limite de login. Não aplica regra de servidor em uploads, não define constantes no wp-config.php, não corrige permissão de arquivo e não reduz privilégio do usuário do banco. Essas são as travas que dependem de configuração, não de plugin.
Esconder a versão do WordPress e mudar o prefixo da tabela adianta?
Quase nada. A versão vaza pelo CSS, pelo JS e pelo feed, e um scanner infere em menos de um segundo. Trocar o prefixo da tabela é grátis em instalação nova, mas em site rodando mexe em valores serializados e não protege contra SQL injection, porque a consulta maliciosa lê o prefixo real do próprio banco.
O que quebra ao colocar o wp-admin atrás de uma camada de identidade?
Toda automação externa que precisa abrir o painel. A força bruta em wp-login.php para de chegar ao PHP, o que é excelente, mas qualquer ferramenta sua que dependa do wp-admin esbarra na mesma parede. Planeje a rota de serviço — token de contorno para a API ou caminho de exceção — antes de ligar a camada.
Devo bloquear o xmlrpc.php?
Só depois de confirmar quem usa. O xmlrpc.php aceita várias tentativas de autenticação por requisição, o que barateia a força bruta, e por isso vale bloquear. Mas ele sustenta o aplicativo móvel oficial, parte do Jetpack e o pingback. Se alguém da equipe publica pelo celular, o bloqueio aparece como falha de login sem explicação.
Como saber se o site já foi invadido antes de aplicar as travas?
Procure arquivo PHP com data recente em wp-content/uploads, usuário administrador que ninguém criou, tarefa agendada desconhecida e data de modificação estranha em index.php ou wp-config.php. Em terminal, find wp-content/uploads -name "*.php" -mtime -30 -ls deve devolver saída vazia em instalação saudável.






