Pular para o conteúdo
>_ITDITDPlataforma de Segurança Web

Guias de Segurança

Vulnerabilidades de upload de arquivos — como evitar web shells e RCE pelo design

Mal projetado, um upload vira uma falha grave: um atacante sem login envia um arquivo que o servidor executa (web shell → RCE), como na exploração em massa de extensões do Joomla em 2026. Defenda em camadas: autenticação, validação no servidor, fora da raiz web, sem execução.

Publicado 2026-07-08 Atualizado 2026-10-04 11 min de leitura

Para quem tem um app (ou uma extensão instalada) que recebe arquivos — formulários, painéis de administração, plugins de CMS, APIs. Nada de instruções de ataque aqui; só como tornar seguro o seu próprio recurso de upload, com base em fatos públicos. Relacionados: como corrigir de vez falhas em dependências no guia de correção de CVEs, e a linha de base de segurança para organizações.

Sem auth → RCE
A pior combinação; alvo de varredura indiscriminada
CWE-434
Upload irrestrito de tipo de arquivo perigoso
Só checar extensão
Driblado por falsificação e extensão dupla
Defesa em camadas
Se uma camada falha, a próxima ainda barra

O que acontece de fato (em termos simples)

A maioria dos apps tem um lugar para receber arquivos — "enviar uma imagem", "trocar um ícone", "anexar um documento". Onde isso é mal protegido, um atacante envia um arquivo de script disfarçado de imagem e consegue salvá-lo numa pasta servida pela web. Depois, basta abrir a URL desse arquivo no navegador — se o servidor roda o conteúdo como programa, o atacante consegue executar comandos à distância. Isso é uma web shell (um pequeno programa de controle remoto deixado para trás), e dela vêm a desfiguração do site, o roubo de dados, contas de administrador criadas às escondidas e a propagação para outros sistemas.

O problema é o local e a execução, não o recebimento do arquivo

Fazer upload é um recurso legítimo. O perigo é colocar o que você recebeu onde pode ser executado, num formato que pode ser executado. Por outro lado, mesmo que você receba um arquivo suspeito, não há dano se ele for parar num lugar que nunca executa nada, se o conteúdo for inspecionado e se o endpoint exigir autenticação. Mude a mentalidade de "barrar arquivos ruins" para "nunca deixar o local de armazenamento executar".

Os casos reais de 2026: extensões do Joomla exploradas em massa (mesmo padrão)

Em 2026, várias extensões do Joomla divulgaram, uma após a outra, exatamente o mesmo padrão de upload sem autenticação → RCE e foram amplamente exploradas. Segundo os relatos, elas combinavam "nenhuma verificação de autenticação + nenhuma validação de tipo de arquivo + armazenamento sob a raiz web" — uma combinação típica. O problema foi além dos construtores de páginas e chegou a uma extensão de calendário de eventos, e a CISA definiu prazos curtos de correção.

Três casos reais (com base na divulgação pública)
SP Page Builder (CVE-2026-48908)
Da JoomShaper. Afeta ≤ 6.6.1, corrigido na 6.6.2. Segundo os relatos, o upload de ícones personalizados não fazia verificação de autenticação nem de tipo; CVSS 10.0, explorado ativamente (listado no CISA KEV). Alerta: CVE-2026-48908.
iCagenda (CVE-2026-48939)
Da joomlic — uma extensão de calendário de eventos. Afeta 3.2.1–3.9.14 / 4.0.0–4.0.7, corrigido na 3.9.15 / 4.0.8. Segundo os relatos, o controle de acesso do tratamento de anexos do formulário público de inscrição em eventos só era aplicado na camada de visualização; CVSS 10.0, explorado ativamente (listado no CISA KEV). Alerta: CVE-2026-48939.
Page Builder CK (CVE-2026-56290)
Da joomlack.fr. Afeta ≤ 3.5.10, corrigido na 3.6.0 (linhas antigas com backport para 3.1.1 / 3.4.10). Segundo os relatos, o mesmo upload sem autenticação levando a RCE; CVSS 10.0.
O que têm em comum
Exploráveis sem login = alvo de varredura indiscriminada. Os ataques relatados se concentraram em manter o acesso: criar contas de administrador ocultas e plantar web shells para que o atacante continue com acesso mesmo depois que a vulnerabilidade é corrigida.
A primeira correção
Atualize a extensão afetada para a versão corrigida (e faça inventário e remova as extensões que você não usa). Além disso, o design e a configuração abaixo, em camadas.

Lição: uma extensão sem uso costuma ser a fraqueza mais explorada

Os casos têm uma coisa em comum: uma extensão esquecida, mas ainda instalada, foi usada para entrar. Cada plugin ou extensão de CMS que você adiciona é mais superfície de ataque. Só inventariar e apagar o que você não usa já reduz o que esse tipo de exploração em massa pode atingir (como inventariar os seus ativos).

Cada etapa do ataque e como barrá-la

Esse padrão tem um lugar para barrá-lo em cada etapa. Leia como onde pode ser barrado, não como instruções.

1. Um arquivo é enviado a um endpoint sem autenticação

Qualquer pessoa alcança o tratamento de upload e envia um script.

Correção: autenticação + verificação de permissão + token CSRF

↓

2. Ele passa pela validação de tipo e é armazenado

Extensão / Content-Type falsificados; disfarçado de "imagem".

Correção: allow-list no servidor + inspeção do conteúdo (magic bytes)

↓

3. Ele vai parar sob a raiz web, acessível por URL

Salvo num caminho adivinhável, que pode ser aberto direto no navegador.

Correção: guardar fora da raiz web / nomes de arquivo aleatórios

↓

4. O servidor o executa como script

Execução habilitada na pasta de armazenamento = web shell → RCE.

Correção: desativar a execução de scripts na área de upload

Cada etapa tem um lugar onde o ataque pode ser barrado. Defesa em profundidade significa ter vários deles, não depender de um único controle.

Configuração insegura vs. configuração segura

A configuração que falha

  • O endpoint não tem verificação de autenticação / permissão (qualquer um alcança)
  • Decisões tomadas só pela extensão ou pelo Content-Type (falsificados, extensão dupla)
  • Arquivos recebidos salvos direto sob a raiz web
  • O local de armazenamento ainda permite rodar scripts
  • Nomes de arquivo fornecidos pelo usuário / adivinháveis

A configuração que resiste

  • Autenticação + permissão + CSRF exigidos no endpoint
  • Allow-list do tipo, e inspeção dos bytes reais (magic bytes)
  • Armazenado fora da raiz web (servido por um tratamento dedicado)
  • A área de upload tem a execução de scripts desativada
  • Renomeado para um nome aleatório; caminhos do usuário nunca são confiáveis

Como implementar (em ordem de prioridade)

1

Exija autenticação, permissão e CSRF no endpoint

O endpoint que trata uploads deve ser acessível só por um usuário logado com a permissão certa, e deve verificar um token CSRF. Segundo os relatos, os casos do Joomla em 2026 não tinham exatamente essa verificação de autenticação e permissão. Primeiro, acabe com o estado de "qualquer um pode chamar".

2

Use allow-list e inspecione o conteúdo no servidor

Nunca confie em verificações no lado do cliente nem no Content-Type enviado pelo navegador. No servidor, permita só tipos sabidamente bons por meio de uma allow-list, e inspecione os bytes reais do arquivo (magic bytes) para confirmar que ele é mesmo daquele tipo. Normalize extensões duplas, maiúsculas e minúsculas e pontos no final antes de decidir.

3

Guarde fora da raiz web (ou desative a execução)

Salve os arquivos recebidos onde não possam ser abertos diretamente por URL, e sirva-os por um controller dedicado (com um Content-Disposition adequado). Se isso for difícil, pelo menos desative a execução de scripts na área de upload (configuração do servidor web). Com isso garantido, nem um arquivo malicioso vai rodar. Isso protege você quando os outros controles falham.

4

Use nomes aleatórios; adicione limites de tamanho e de taxa

Renomeie para um nome aleatório escolhido pelo servidor e nunca confie em caminhos ou nomes de arquivo fornecidos pelo usuário (evitando path traversal). Adicione limites de tamanho e de taxa e, onde possível, uma verificação de malware.

5

Inventarie e atualize as suas extensões/CMS

Faça o inventário das extensões e plugins que você usa, apague o que não usa e mantenha o resto atualizado. Na exploração em massa de 2026, os atacantes entraram por extensões que ficaram sem atualização. Seguindo o guia de correção de CVEs, adicione detecção de mudanças para perceber quando elas voltarem.

Onde isso se sobrepõe ao modo como este site é construído

O problema central desse padrão é colocar uma entrada não confiável onde ela pode ser executada, num formato que pode ser executado. Os princípios deste site são o oposto: não confiar no que se recebe, isolar o que importa e defender em camadas. Além dos uploads, "validar a entrada no servidor" e "isolar segredos e áreas executáveis" são a mesma defesa. Veja também os erros de posicionamento em não coloque segredos em diretórios públicos.

Leia a seguir

FAQ

QPor que uma falha de upload de arquivos permite que atacantes tomem o servidor?
A

Se um atacante consegue colocar um arquivo que o servidor vai executar (um script), basta abri-lo no navegador para rodar código no servidor (uma web shell → execução remota de código, RCE). A partir daí: desfiguração do site, roubo de dados, contas de administrador criadas às escondidas e propagação para outros sistemas. O ponto-chave não é que um arquivo foi recebido — é que o arquivo pode ser executado onde foi parar.

QVerificar a extensão do arquivo é suficiente?
A

Não. A extensão e o Content-Type enviado pelo navegador são falsificados com facilidade. Extensões duplas (foto.php.jpg), truques com maiúsculas e minúsculas, pontos ou bytes nulos no final e extensões executáveis menos conhecidas driblam verificações ingênuas. Defenda combinando uma allow-list (permitir só o que é sabidamente bom), a inspeção dos bytes reais do arquivo (magic bytes) e — acima de tudo — não deixar o local de armazenamento executar nada. Não dependa de uma deny-list.

QSites pequenos são alvo?
A

Sim. Esse tipo de falha é explorável sem autenticação, então os atacantes varrem a internet inteira e atingem versões vulneráveis indiscriminadamente. Na exploração em massa das extensões de construção de páginas do Joomla em 2026, toda instalação afetada era alvo, independentemente do tamanho. 'Somos pequenos demais para sermos atacados' não se sustenta.