Skip to main content
Ricardo EsperCISO · CYBER
Menu
LinkedIn →
Back to all articles
Segurança da InformaçãoArquitetura

Superfície de ataque: o que responde, não o que você desenhou

Superfície de ataque, plugins de CMS e o raio do dano: por que 96% das vulnerabilidades do WordPress estão em plugins, por que remover do repositório não desinstala nada, e por que a origem pública não deveria saber escrever.

Superfície de ataque: o que responde, não o que você desenhou

Existe uma diferença entre a arquitetura que você desenhou e a superfície que você tem. A primeira está num slide. A segunda é tudo que responde a uma requisição — de qualquer lugar, para qualquer um, agora.

Superfície de ataque não é uma lista de servidores. É a resposta a três perguntas, feitas sobre cada coisa que atende: o que responde, de onde pode ser alcançado, e por quem. Um serviço que só escuta na rede interna e um serviço idêntico exposto na internet têm o mesmo código e superfícies incomparáveis.

E há uma assimetria cruel nisso: você defende o que conhece, e é atacado por tudo que existe. Todo item que responde e não está no seu inventário é uma vantagem que você entregou de graça.

Duas naturezas no mesmo endereço

Quero tratar de um caso específico, porque ele é comum, parece inofensivo e concentra vários problemas de uma vez: colocar o painel de administração — o CMS — na mesma origem do site público.

É a decisão mais natural do mundo. O site está em empresa.com.br, o painel vai em empresa.com.br/admin. Mesmo projeto, mesmo deploy, mesmo certificado, nada a configurar. E é justamente por ser tão natural que quase ninguém a submete a escrutínio.

Só que esses dois sistemas têm naturezas opostas:

| | Site público | Painel | |---|---|---| | Quem acessa | qualquer um, anônimo | poucas pessoas, identificadas | | O que faz | | escreve | | Volume | alto, cacheável | baixo, nunca cacheado | | Se cair | prejuízo | inconveniente | | Se for comprometido | inconveniente | prejuízo grave |

São perfis de risco invertidos. E quando compartilham origem, eles compartilham muito mais do que um domínio.

O que se compartilha junto com o endereço

A tabela de rotas. Esta é a mais subestimada. Quando o painel e o site público passam pelo mesmo roteador, uma falha de roteamento vira uma falha de autenticação — sem que ninguém tenha escrito uma linha de código de autenticação errada. Um caminho alternativo que chega ao mesmo recurso por outra grafia, um prefixo de idioma, uma barra a mais, uma normalização feita na ordem errada. A verificação de acesso continua correta; ela só não é chamada.

É um tipo de falha que revisão de código de autenticação não pega, porque o defeito não está lá.

O escopo do cookie. O cookie de sessão do administrador existe no mesmo contexto de origem que todas as páginas públicas. Isso significa que qualquer XSS em qualquer página pública — o campo de busca, um comentário, um parâmetro refletido, uma dependência de terceiro no rodapé — passa a ter o painel ao alcance. HttpOnly ajuda contra roubo do valor, mas não impede que o navegador da vítima faça requisições autenticadas. Origens separadas transformam esse ataque num problema de cross-origin, que é exatamente o que o navegador foi construído para barrar.

As dependências. O painel costuma ser a parte mais pesada da aplicação: editor de texto rico, upload, manipulação de imagem, geração de relatório, biblioteca de gráficos. É onde mora a maior quantidade de código de terceiros, e portanto a maior taxa de vulnerabilidades publicadas. Na mesma origem, esse código é entregue no mesmo perímetro que atende o mundo inteiro.

As regras de borda. WAF, cache, limite de requisições, cabeçalhos — tudo é ajustado para tráfego público. O painel precisa do oposto quase item a item. Convivendo, um afrouxa o outro: ou o painel quebra por causa de uma regra pensada para anônimos, ou a regra é afrouxada para o painel funcionar, e passa a valer para todo mundo.

O caminho de escrita. Este é o ponto central, e vale isolar.

O núcleo quase nunca é o problema

Vale olhar de perto o item das dependências, porque num CMS ele deixa de ser um detalhe de implementação e vira a arquitetura inteira.

Um CMS maduro como o WordPress não é um sistema. É uma plataforma onde você monta código de terceiros. E os números do ecossistema contam uma história muito específica:

Em 2024, foram catalogadas 7.966 novas vulnerabilidades no ecossistema WordPress. Dessas, 96% estavam em plugins, 4% em temas — e sete no núcleo do WordPress. Sete. No primeiro semestre de 2025 o padrão se repetiu: 6.700 novas vulnerabilidades, 89% em plugins, praticamente nada no núcleo.

A leitura correta desses números não é "WordPress é inseguro". É quase o contrário: o núcleo é maduro, auditado e bem mantido. O problema não é o que você instalou — é o que você instalou em cima.

E há um detalhe que muda a gravidade de tudo: no primeiro semestre de 2025, 57,6% das vulnerabilidades podiam ser exploradas sem nenhuma credencial. Sem login, sem conta, sem convite. Basta alcançar o endereço.

Um plugin não é um convidado. É um sócio.

A raiz do problema é de modelo de privilégio, e ela é simples de enunciar: um plugin roda com os mesmos privilégios que o núcleo. Não há caixa de areia, não há separação de permissões, não há "este plugin só pode mexer no formulário de contato".

O plugin de galeria de fotos pode ler a tabela de usuários inteira. O plugin de formulário pode escrever arquivo no disco. O plugin de banner pode executar código. Nenhum deles precisa disso — todos podem.

O que significa que a sua postura de segurança não é a média dos seus plugins. É o pior deles. Cada um que você instala é uma decisão de confiar, com acesso total, em um autor que você nunca vai conhecer, por tempo indeterminado.

O abandono é silencioso

Aqui está a parte que mais me incomoda, e é a menos discutida.

Um plugin costuma ser mantido por uma pessoa, de graça, no tempo livre. Um dia essa pessoa muda de emprego, perde o interesse, adoece, morre. O plugin continua no seu site, funcionando perfeitamente, e para de receber correção.

Em 2024, 1.614 plugins e temas foram removidos do repositório oficial por problemas de segurança não corrigidos. E aqui está o detalhe cruel: remover do repositório não desinstala nada. O plugin continua rodando em todos os sites que já o tinham. O que a remoção faz é interromper o canal de atualização — em silêncio. Nada aparece no painel. Nenhum aviso. O item simplesmente nunca mais é atualizado, e continua parecendo normal.

Some a isso um dado que inverte a intuição de quem acha que dá para esperar: em 2024, 33% das vulnerabilidades já eram públicas antes de existir correção. Um terço das divulgações não trouxe remédio junto.

A janela

E é aqui que a divulgação responsável cobra o seu preço.

Quando uma vulnerabilidade é publicada, publica-se junto o mapa: onde está, como se chega, o que faz. Isso é certo e necessário — sem divulgação, só o atacante sabe. Mas significa que a partir do anúncio, a corrida começa e você está atrasado, porque quem varre a internet automatiza em horas e você atualiza em dias.

O núcleo do WordPress atualiza sozinho as versões menores desde 2016. Plugins, não — a atualização automática existe, mas vem desligada, e precisa ser habilitada item por item. A configuração padrão do ecossistema deixa justamente a camada de 96% das vulnerabilidades esperando alguém lembrar.

O que fazer é pouco e é chato, que é o motivo de não ser feito:

  • Conte quantos plugins você tem. O número costuma surpreender, e todo plugin que não está em uso é risco sem contrapartida. Desativado não basta: código presente é código alcançável.
  • Veja a data da última atualização de cada um. Mais de um ano sem toque, com o WordPress evoluindo, é sinal de abandono.
  • Ligue a atualização automática no que você mantiver.
  • Prefira um plugin a mais no núcleo do que um plugin a mais no site. Se a funcionalidade existe nativamente, mesmo pior, use a nativa.

E — voltando ao ponto deste texto — nada disso importa tanto quanto a pergunta anterior: o que um plugin comprometido alcança a partir de onde ele roda? Se ele está na mesma origem que atende o público, com caminho de escrita no banco e credencial de produção no ambiente, ele alcança tudo. Se o que atende o público não sabe escrever, o mesmo plugin comprometido é um estrago muito menor.

Plugin vulnerável é inevitável — você não controla o código de terceiros nem a vida do autor. O raio do dano, esse você projeta.

O princípio: a origem pública não deveria saber escrever

Se o servidor que atende o público não tem nenhum caminho capaz de alterar dados, comprometê-lo não permite alterar dados. Não é uma barreira a mais — é a remoção da capacidade.

Isso reordena o problema inteiro. Deixa de ser "quão boa é a minha autenticação no painel" e passa a ser "o que um atacante consegue fazer mesmo com o pior resultado possível na origem pública". A segunda pergunta é muito melhor, porque a resposta não depende de nenhum código estar correto.

Em ordem de força, e sendo honesto sobre o custo:

  1. Desacoplar de verdade. O CMS escreve num repositório de dados; o site público apenas lê — ou nem isso, sendo gerado estaticamente a cada publicação. É a separação mais forte e, para sites de conteúdo, muitas vezes a mais barata.
  2. Origem separada. O painel em outro hostname, outro deploy, outro certificado. Resolve cookie, roteamento e regras de borda de uma vez. Custa configuração, não arquitetura.
  3. Controle de rede na frente. Lista de IPs permitidos, mTLS, ou acesso por zero trust. Ótimo quando aplicável; ruim para quem publica de qualquer lugar.
  4. No mínimo: que a rota administrativa não passe pela mesma normalização de caminho do site público, e que a autenticação seja verificada sobre o caminho já normalizado — nunca sobre o que o cliente digitou.

Nenhuma dessas medidas é exótica. A primeira é uma decisão de projeto; a segunda é uma tarde de trabalho.

A superfície que ninguém inventaria

Fecho com a categoria que mais cresce e menos aparece: ambientes que existem sem ninguém decidir que existem.

Ambientes de preview criados a cada alteração de código. Homologação levantada para um teste específico. Aquela máquina de 2019 que "ainda tem uma coisinha rodando". O subdomínio temporário que ficou. São cópias funcionais do sistema, muitas vezes com dados e credenciais parecidos com os de produção, em endereços que não estão em inventário nenhum.

A boa notícia é que aqui o remédio é simples e as plataformas modernas já o oferecem pronto: ambiente efêmero fica atrás de autenticação e fora do índice dos buscadores. Quando isso está ligado, o preview deixa de ser superfície anônima — continua sendo superfície, porque é código real rodando com credenciais reais, mas exige identidade para ser alcançado. Quando não está, você publicou o seu sistema num endereço que só o atacante vai auditar.

A regra prática é uma só: se responde, está no inventário. Não importa se é temporário, se é de teste, ou se "ninguém sabe o endereço". Endereço que ninguém sabe é o que um varredor de certificados descobre em minutos, porque todo certificado emitido é registrado publicamente.

O que eu levo

A pergunta que eu faria primeiro, numa organização que eu não conheço, não é sobre firewall nem sobre política. É esta: me mostre a lista de tudo que responde na internet com o nome de vocês.

A lista quase nunca existe. E quando existe, ela está errada — não porque alguém foi relapso, mas porque superfície cresce por decisões pequenas, tomadas por gente diferente, em momentos diferentes, cada uma delas perfeitamente razoável isolada.

É a diferença entre risco aceitável e risco esquecido. O risco aceitável você mediu, entendeu e decidiu correr. O esquecido é o que você nunca soube que estava correndo — e ele quase sempre entrou pela porta mais conveniente, aquela que ninguém pensou duas vezes antes de abrir, porque abrir era o caminho mais curto.

Segurança boa raramente parece heroica. Quase sempre parece com alguém dizendo "isso não precisa estar aqui" — e tirando.


Fontes dos números citados: Patchstack, State of WordPress Security in 2025 (dados de 2024) e 2025 Mid-Year Vulnerability Report (primeiro semestre de 2025).