WordPress Hackeado Novamente? Migração para Next.js + Supabase Resolve
Seu cliente liga: a loja WooCommerce dele foi hackeada novamente. Você limpou mês passado — removeu o backdoor, corrigiu vinte e três plugins, rotacionou credenciais. Mas esta manhã o processador de pagamento dele sinalizou atividade suspeita de cartão. Você SSH entra e encontra: um skimmer de cartão de crédito escondido dentro de um plugin de análise legítimo que auto-atualizou na terça à noite. Mesma história, plugin diferente. A superfície de ataque não é um bug no WordPress core — são os trinta e sete plugins de terceiros dos quais o site depende para funcionar. Cada um é uma porta. A maioria é corrigida lentamente. Alguns nunca são. A migração para Next.js + Supabase não apenas limpa a infecção — remove toda a camada de plugins onde 90% das violações de WordPress se originam.
Este artigo não é sobre criticar WordPress. Ele alimentou uma grande fatia da web por boas razões. Mas a arquitetura que o tornou acessível em 2005 é a mesma que o torna um ímã para ataques automatizados em 2026. Se você foi hackeado — ou está cansado de gastar dinheiro com plugins de segurança que são eles próprios vetores de ataque — este é seu guia de jogo para migrar para algo fundamentalmente mais seguro.
Índice
- O Problema de Segurança do WordPress é Arquitetural
- Vetores de Ataque Comuns do WordPress em 2026
- Por Que Arquitetura Headless Elimina Categorias Inteiras de Ataque
- Next.js + Supabase: Stack Focado em Segurança
- Comparação de Superfície de Ataque: WordPress vs Headless
- O Guia de Migração: WordPress para Next.js + Supabase
- Endurecimento de Segurança Pós-Migração
- Custo Real da Segurança do WordPress vs Migração
- FAQ

O Problema de Segurança do WordPress é Arquitetural
Permita-me ser claro sobre algo: o time do WordPress core faz um trabalho sólido de segurança. WordPress core, mantido atualizado, é razoavelmente seguro. Mas ninguém executa apenas WordPress core. O site WordPress médio tem 20-30 plugins instalados. Cada um é uma dependência que você não escreveu, mantida por alguém que você não conhece, com acesso ao seu banco de dados, seu sistema de arquivos e os dados dos seus usuários.
Aqui está a coisa que continua sendo ignorada em artigos de "melhores práticas de segurança do WordPress": o problema não é que proprietários de sites WordPress são negligentes. O problema é que a arquitetura do WordPress exige que você instale código PHP executável de terceiros diretamente no seu servidor para obter funcionalidade básica. É equivalente a dar a todo contratante que trabalha na sua casa uma cópia da chave da sua casa — permanentemente.
O banco de dados de vulnerabilidades WPScan rastreou mais de 7.900 novas vulnerabilidades de WordPress em 2024, com plugins responsáveis por aproximadamente 96% delas. O relatório de ameaças de 2024 do Sucuri descobriu que WordPress respondeu por aproximadamente 95% de todas as infecções de CMS que limparam. E o Patchstack reportou que 33% das vulnerabilidades críticas de WordPress em 2024 não tinham patch disponível no momento da divulgação.
Estas não são falhas que podem ser corrigidas com melhores práticas de codificação. São propriedades emergentes da própria arquitetura.
Vetores de Ataque Comuns do WordPress em 2026
Antes de falarmos sobre a solução, vamos catalogar contra o que você está realmente se defendendo. Eu pessoalmente triagi dezenas de sites WordPress comprometidos, e os ataques seguem padrões previsíveis.
Injeção SQL Através de Plugins
WordPress usa um banco de dados MySQL com um esquema bem documentado. Todo plugin que aceita entrada de usuário e toca o banco de dados é um possível ponto de injeção SQL. A função $wpdb->prepare() existe, mas é opcional. Desenvolvedores de plugins a esquecem, usam mal ou pulam inteiramente para queries "simples".
Uma vez rastreei uma injeção de volta para um plugin de formulário de contato que havia sido abandonado por 18 meses, mas ainda estava instalado em 200.000+ sites. O invasor estava usando uma injeção baseada em UNION para despejar a tabela wp_users, pegar hashes de senha do admin e cracking dos fracos offline.
-- Como uma injeção SQL típica de WordPress se parece em logs
GET /wp-content/plugins/vulnerable-plugin/ajax.php?id=1%20UNION%20SELECT%201,user_login,user_pass,4,5%20FROM%20wp_users--
Injeção de Objeto PHP e Execução Remota de Código
O uso intenso de serialize() e unserialize() do WordPress cria oportunidades para injeção de objeto PHP. Quando um plugin desserializa dados controlados pelo usuário (e muitos fazem), um invasor pode elaborar payloads que executam código arbitrário durante o processo de desserialização.
Em 2024, uma vulnerabilidade crítica de RCE em um plugin de backup popular (instalado em 5 milhões+ de sites) permitiu que atacantes não autenticados executassem código PHP arbitrário. A correção levou 11 dias para ser lançada. Onze dias onde cada site com esse plugin era um alvo fácil.
Ataques da Cadeia de Fornecimento de Plugins
Este é o que me assusta mais. Invasores compram plugins abandonados com grandes bases de instalação, empurram uma "atualização de segurança" contendo um backdoor, e os mecanismos de auto-update do WordPress distribuem o malware para cada site executando esse plugin. Aconteceu com Display Widgets (300.000 instalações) e Social Warfare (70.000 instalações), e esses são apenas os que foram pegos.
Ataques de Força Bruta em wp-login.php
Todo site WordPress expõe /wp-login.php e /xmlrpc.php por padrão. Botnets automatizados atingem esses endpoints constantemente. Wordfence reportou bloquear uma média de 3 bilhões de requisições maliciosas por mês em toda sua rede em 2024. Mesmo com limitação de taxa e autenticação de dois fatores, você está gastando recursos de servidor processando esses ataques.
Cross-Site Scripting (XSS) via Temas e Plugins
XSS armazenado em WordPress é particularmente perigoso porque o painel de administração e o site de face pública compartilham o mesmo contexto de sessão. Um payload XSS injetado através de um comentário, envio de formulário ou configuração de plugin vulnerável pode escalar para acesso de admin completo.
Por Que Arquitetura Headless Elimina Categorias Inteiras de Ataque
Aqui é onde as coisas ficam interessantes. Uma arquitetura headless não apenas reduz sua superfície de ataque — elimina categorias inteiras de ataques removendo as condições que as tornam possíveis.
Em uma configuração tradicional do WordPress, o mesmo servidor que renderiza seu HTML também:
- Executa código PHP de 20+ plugins de terceiros
- Gerencia autenticação de usuários
- Conecta ao banco de dados
- Serve a interface de administração
- Manipula uploads de arquivos
- Processa envios de formulários
São muitas responsabilidades para uma única aplicação. Em uma configuração headless com Next.js e Supabase, essas responsabilidades são separadas em serviços isolados:
- Frontend (Next.js em Vercel/Netlify): HTML/JS estático servido de um CDN. Sem runtime do lado do servidor exposto à internet pública na maioria dos casos.
- Banco de Dados + Auth (Supabase): Postgres gerenciado com Row Level Security, nunca diretamente exposto aos usuários finais.
- Camada de API: Funções serverless com endpoints explícitos e mínimos.
- CMS (se necessário): CMS headless executando em sua própria infraestrutura isolada.
Não há PHP para injetar. Não há diretório de plugin com acesso de escrita. Não há sessão compartilhada entre admin e o site público. Não há wp-login.php para os bots martelarem.
Você não precisa de um WAF para proteger uma superfície de ataque que não existe.

Next.js + Supabase: Stack Focado em Segurança
Vamos ser específicos sobre por que essa combinação particular funciona tão bem de um ponto de vista de segurança.
Next.js: O Frontend que Não Executa Código
Quando você constrói um site Next.js com geração estática (SSG) ou regeneração estática incremental (ISR), o que é deployado são arquivos HTML, CSS e JavaScript em um CDN. Não há servidor de aplicação processando requisições em tempo real. Você não pode SQL-injetar um CDN.
Para funcionalidade dinâmica, Next.js Server Actions e Route Handlers executam como funções serverless. Cada função é:
- Isolada em seu próprio contexto de execução
- Sem estado (sem memória compartilhada entre requisições)
- De curta duração (cold start, executar, encerrar)
- Explicitamente definida (sem auto-discovery de endpoints)
// Next.js Route Handler -- explícito, tipado, mínimo
import { createClient } from '@/lib/supabase/server'
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
const ContactSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
message: z.string().min(10).max(5000),
})
export async function POST(request: NextRequest) {
const body = await request.json()
const parsed = ContactSchema.safeParse(body)
if (!parsed.success) {
return NextResponse.json({ error: 'Invalid input' }, { status: 400 })
}
const supabase = await createClient()
const { error } = await supabase
.from('contact_submissions')
.insert(parsed.data)
if (error) {
return NextResponse.json({ error: 'Submission failed' }, { status: 500 })
}
return NextResponse.json({ success: true })
}
Compare isso com um plugin de formulário de contato do WordPress que tem que ligar no sistema de ação do WordPress, incluir seu próprio handler AJAX, gerenciar sua própria verificação de nonce e construir suas próprias queries SQL. A versão Next.js tem menos peças móveis, entrada validada via Zod e queries parametrizadas através do cliente Supabase.
Supabase: Postgres com Row Level Security
Supabase oferece um banco de dados PostgreSQL gerenciado com um recurso assassino: Row Level Security (RLS). Em vez de confiar no código da sua aplicação para fazer cumprir o controle de acesso (o modelo WordPress), você define políticas de segurança no nível do banco de dados.
-- Apenas usuários autenticados podem ler seus próprios dados
CREATE POLICY "Users can view own profile"
ON profiles
FOR SELECT
USING (auth.uid() = user_id);
-- Público pode inserir em contact_submissions mas não ler
CREATE POLICY "Anyone can submit contact form"
ON contact_submissions
FOR INSERT
WITH CHECK (true);
CREATE POLICY "Only admins can read submissions"
ON contact_submissions
FOR SELECT
USING (auth.jwt() ->> 'role' = 'admin');
Mesmo se um invasor encontrar uma maneira de fazer queries Supabase arbitrárias (que já é muito mais difícil sem um contexto de execução PHP), as políticas RLS impedem que acessem dados que não deveriam ver. Isto é defesa em profundidade que WordPress fundamentalmente não pode oferecer porque seu sistema de permissões é implementado em código PHP, não no nível do banco de dados.
Supabase também manipula autenticação com suporte integrado para email/senha, magic links, provedores OAuth e autenticação multifator. Sem plugin necessário. Sem código de terceiros executando no seu servidor.
Comparação de Superfície de Ataque: WordPress vs Headless
Vamos colocar lado a lado.
| Vetor de Ataque | WordPress | Next.js + Supabase |
|---|---|---|
| Injeção SQL | Alto risco -- plugins constroem queries brutas | Próximo de zero -- queries parametrizadas via cliente Supabase, RLS como backup |
| PHP/Execução Remota de Código | Alto risco -- plugins executam PHP do lado do servidor | Não aplicável -- sem runtime PHP |
| Cadeia de Fornecimento de Plugin | Risco crítico -- auto-updates distribuem malware | Não aplicável -- sem ecossistema de plugin |
| Força Bruta (login) | Sempre exposto (wp-login.php, xmlrpc.php) |
Acesso admin através Supabase Auth ou dashboard separado, sem endpoint de login público necessário |
| XSS (Armazenado) | Alto risco -- contexto admin/público compartilhado | Baixo risco -- React escapa saída por padrão, admin e público são apps separados |
| Exploração de Upload de Arquivo | Alto risco -- arquivos PHP carregados podem executar | Baixo risco -- uploads vão para armazenamento de objeto (Supabase Storage/S3), nunca executados como código |
| Exposição de Banco de Dados | Acesso MySQL direto se servidor for comprometido | Banco de dados atrás da infraestrutura Supabase, políticas RLS como guarda final |
| DDoS em Origin | Servidor deve processar cada requisição | Assets estáticos em CDN, origin raramente atingido |
| Enumeração de Caminho Conhecido | wp-admin, wp-content, wp-includes tudo escaneável |
Sem caminhos previsíveis, sem rotas admin expostas |
O Guia de Migração: WordPress para Next.js + Supabase
Certo, você está convencido (ou seu site hackeado o convenceu). Aqui está como realmente fazer isso. Executamos essa migração em Social Animal o suficiente para ter um processo repetível.
Fase 1: Triagem e Auditoria de Conteúdo (Semana 1)
Antes de tocar em qualquer código, você precisa entender o que realmente tem.
- Exporte todo o conteúdo do WordPress usando WP-CLI ou a REST API. Não confie em exportações XML — elas perdem campos meta e tipos de post customizados.
- Catalogue toda a funcionalidade fornecida por plugins. Faça uma planilha: nome do plugin, o que faz, se você realmente precisa, e o que o substitui.
- Mapeie estruturas de URL para preservação SEO. Cada URL existente precisa um redirecionamento ou uma rota correspondente em Next.js.
- Identifique recursos dinâmicos — formulários, busca, contas de usuário, ecommerce — que precisam de endpoints de API.
# Exporte conteúdo WordPress via REST API
curl -s "https://yoursite.com/wp-json/wp/v2/posts?per_page=100&page=1" | jq '.' > posts_page1.json
curl -s "https://yoursite.com/wp-json/wp/v2/pages?per_page=100" | jq '.' > pages.json
curl -s "https://yoursite.com/wp-json/wp/v2/media?per_page=100" | jq '.' > media.json
Fase 2: Migração de Schema e Dados do Supabase (Semana 2)
Projecte seu schema de banco de dados Supabase com base na auditoria de conteúdo. Não apenas replique o schema do WordPress — ele é inchado com tabelas de metadados e blobs de dados serializados.
-- Schema limpo e com propósito
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
content TEXT,
excerpt TEXT,
featured_image TEXT,
status TEXT DEFAULT 'draft' CHECK (status IN ('draft', 'published', 'archived')),
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
author_id UUID REFERENCES auth.users(id)
);
-- Abilitar RLS imediatamente
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Published posts are public"
ON posts FOR SELECT
USING (status = 'published');
CREATE POLICY "Authors can manage own posts"
ON posts FOR ALL
USING (auth.uid() = author_id);
Escreva um script de migração (Node.js ou Python) que transforma exportações JSON do WordPress em seu novo schema e as insere no Supabase.
Fase 3: Construção de Next.js (Semanas 3-5)
Constuia seu frontend Next.js. Se você está trabalhando com um time que conhece o stack, isso é rápido. Se você precisa de ajuda, nosso time de desenvolvimento Next.js executou essa migração o suficiente para ter opiniões fortes sobre os padrões corretos.
Decisões arquitetônicas chave:
- Geração estática para páginas de conteúdo — posts de blog, landing pages, sobre. Estes se tornam arquivos HTML em um CDN.
- Server components para dados dinâmicos — buscar do Supabase em tempo de requisição com cache.
- Route handlers para envios de formulário — formulários de contato, signups de newsletter, etc.
- Middleware para redirecionamentos — manipule todas as suas URLs antigas do WordPress.
// next.config.ts -- manipule redirecionamentos de URL do WordPress
const nextConfig = {
async redirects() {
return [
{
source: '/category/:slug',
destination: '/blog/category/:slug',
permanent: true,
},
{
source: '/:year(\\d{4})/:month(\\d{2})/:slug',
destination: '/blog/:slug',
permanent: true,
},
// wp-login.php -- envie bots para 410
{
source: '/wp-login.php',
destination: '/gone',
permanent: true,
},
{
source: '/wp-admin/:path*',
destination: '/gone',
permanent: true,
},
]
},
}
Fase 4: Teste e Validação SEO (Semana 6)
- Execute Screaming Frog contra o novo site para verificar se cada URL antiga resolve ou redireciona.
- Valide que dados estruturados (JSON-LD) estão presentes em todas as páginas.
- Teste todos os formulários e recursos dinâmicos.
- Execute verificações Lighthouse e Core Web Vitals — você quase certamente verá melhorias já que agora está servindo de um CDN.
- Configure monitoramento com Vercel Analytics ou sua ferramenta preferida.
Fase 5: Lançamento e Cutover de DNS (Semana 6-7)
Deploy para Vercel ou Netlify, atualize DNS e configure monitoramento. Mantenha a instância WordPress antiga offline mas acessível por 30 dias caso você precise referenciar algo.
Se seu site tem tráfego significativo ou funcionalidade de ecommerce, considere uma integração headless CMS para gerenciamento de conteúdo e converse com a gente sobre Astro como frontend alternativo para sites com mucho conteúdo onde desempenho de build importa.
Endurecimento de Segurança Pós-Migração
Uma vez que você está no novo stack, aqui está sua checklist de segurança:
- Habilite RLS no Supabase em toda tabela. Sem exceções. Se uma tabela não tem políticas, ou é inacessível (bom padrão) ou está completamente aberta (ruim).
- Use variáveis de ambiente para todos os segredos. Vercel e Netlify ambos manipulam isso bem. Nunca commita chaves de API.
- Configure backups de banco de dados Supabase. Recuperação point-in-time está disponível em planos Pro ($25/mês).
- Configure headers Content Security Policy no middleware Next.js.
- Habilite proteção DDoS do Vercel (incluído em todos os planos).
- Configure monitoramento de uptime — nós usamos Better Uptime, mas Checkly e monitoramento integrado do Vercel também funcionam.
- Audite suas políticas RLS do Supabase trimestralmente. Use o editor SQL do Supabase para testar políticas com diferentes contextos de usuário.
// middleware.ts -- headers de segurança
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const response = NextResponse.next()
response.headers.set('X-Frame-Options', 'DENY')
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
response.headers.set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
)
response.headers.set(
'Permissions-Policy',
'camera=(), microphone=(), geolocation=()'
)
return response
}
Custo Real da Segurança do WordPress vs Migração
Vamos falar sobre dinheiro, porque isso é o que realmente impulsiona decisões.
| Categoria de Custo | WordPress (Anual) | Next.js + Supabase (Anual) |
|---|---|---|
| Hospedagem | $300-1.200 (WP gerenciado) | $0-240 (Vercel Pro) |
| Plugins de segurança (Wordfence/Sucuri) | $200-500 | $0 (não necessário) |
| SSL/CDN | $0-200 | $0 (incluído) |
| Limpeza de malware (se hackeado) | $500-2.500 por incidente | N/A |
| Tempo de desenvolvedor em patches de segurança | $2.000-5.000 | $500-1.000 |
| Banco de dados (Supabase) | Incluído em hospedagem | $0-300 (Tier Gratuito a Pro) |
| Total | $3.000-9.400 | $500-1.540 |
E isso é antes de você considerar o custo de downtime, perda de confiança do cliente e possíveis penalidades regulatórias se dados do cliente forem comprometidos. Uma única violação reportável sob GDPR pode custar dezenas de milhares em overhead legal e de conformidade.
A própria migração típicamente custa entre $10.000-40.000 dependendo da complexidade do site. Para a maioria dos negócios, isso se paga em 1-2 anos apenas em redução de gastos com segurança — e você ganha um site mais rápido e mais fácil de manter no processo. Verifique nossa página de preços para especificações em projetos de migração.
FAQ
WordPress é realmente tão inseguro, ou isso é exagerado?
WordPress core é mantido bem. O problema é que praticamente ninguém executa apenas core. O ecossistema de plugin é onde 96% das vulnerabilidades vivem, e você não pode executar um site WordPress útil sem plugins. Não é exagerado — Sucuri limpou malware de mais de 60.000 sites WordPress em 2024. A arquitetura exige que você confie em código PHP de terceiros no seu servidor, e essa confiança é explorada constantemente.
Não posso apenas usar plugins de segurança melhores em vez de migrar?
Plugins de segurança são eles próprios código PHP executando no seu servidor com acesso profundo ao sistema. Wordfence e Sucuri são bem mantidos, mas são band-aids em um problema arquitetural. Eles também adicionam carga de servidor, podem conflitar com outros plugins e tiveram suas próprias vulnerabilidades ao longo dos anos. Você está adicionando complexidade para resolver um problema de complexidade.
Quanto tempo uma migração de WordPress para Next.js tipicamente leva?
Para um site comercial padrão (10-50 páginas, blog, formulários de contato), tipicamente completamos migrações em 5-7 semanas. Sites de ecommerce com WooCommerce são mais complexos e podem levar 8-14 semanas dependendo do tamanho do catálogo de produtos e funcionalidade customizada. Se você tem um site mais simples, entre em contato conosco e podemos dar um prazo mais específico.
Perderei meus rankings SEO ao migrar do WordPress?
Não, se você fizer certo. Os passos críticos são: preservar todas as estruturas de URL ou configurar redirecionamentos 301 adequados, manter sua marcação de dados estruturados, manter seu conteúdo intacto e enviar sitemaps atualizados para Google Search Console. A maioria dos nossos clientes de migração vê melhorias de ranking dentro de 2-3 meses porque scores de Core Web Vitals melhoram dramaticamente quando você se move para um site estático servido por CDN.
E sobre edição de conteúdo? WordPress é fácil para usuários não técnicos.
Esta é uma preocupação legítima. Você tem opções: Supabase com um dashboard admin customizado, ou um CMS headless como Sanity, Contentful ou Payload CMS que dá aos editores de conteúdo uma experiência de edição visual similar ao WordPress. Manipulamos integrações headless CMS regularmente e podemos recomendar o ajuste certo para as necessidades do seu time.
Supabase é seguro o suficiente para uso em produção?
Supabase roda em infraestrutura AWS com conformidade SOC 2 Type II. O banco de dados subjacente é PostgreSQL, que tem um forte histórico de segurança. Row Level Security impõe controle de acesso no nível do banco de dados, que é realmente mais seguro que o sistema de permissões baseado em PHP do WordPress. Supabase também oferece recuperação point-in-time, conexões criptografadas e restrições de rede em planos pagos.
E se meu site WordPress foi hackeado e preciso de ajuda imediata?
Primeiro, coloque o site offline imediatamente para parar danos adicionais e vazamento de dados. Segundo, preserve evidência forense (dumps de banco de dados, logs de acesso, snapshots do sistema de arquivos). Terceiro, não apenas o limpe e coloque de volta — você provavelmente será reinfectado em poucas semanas. Use o incidente como catalisador para migrar. Entre em contato com nosso time e podemos ajudar com triagem imediata e planejamento de migração.
Preciso migrar tudo de uma vez, ou posso fazer incrementalmente?
Migração incremental é possível mas adiciona complexidade. Você pode executar Next.js como frontend enquanto mantém WordPress como um backend CMS headless temporariamente, depois remover WordPress completamente. Porém, isso significa WordPress ainda está executando e ainda precisa manutenção de segurança durante a transição. Para a maioria dos sites, um cutover limpo é mais rápido, mais barato e elimina risco de segurança mais rápido.