July 25, 2026
Upload de arquivos não é apenas uma funcionalidade: é uma fronteira de segurança
Como reduzir riscos envolvendo extensões falsas, Magic Bytes, arquivos poliglotas, malware, path traversal, processamento inseguro e…

By Cristiano Junior
11 min read
- 1 Como reduzir riscos envolvendo extensões falsas, Magic Bytes, arquivos poliglotas, malware, path traversal, processamento inseguro e exposição acidental
- 2 Extensão de arquivo não comprova o conteúdo
- 3 O Content-Type também pode ser falsificado
- 4 Magic Bytes: identificando a assinatura real do arquivo
- 5 Arquivos poliglotas: um arquivo, múltiplas interpretações
Como reduzir riscos envolvendo extensões falsas, Magic Bytes, arquivos poliglotas, malware, path traversal, processamento inseguro e exposição acidental
O upload de arquivos costuma ser tratado como uma funcionalidade simples: o usuário seleciona um arquivo, a aplicação valida a extensão, salva o conteúdo e retorna uma URL.
Essa percepção é perigosa.
Sempre que uma aplicação aceita arquivos enviados por usuários, ela passa a processar conteúdo que não controla. O arquivo pode estar malformado, adulterado, disfarçado, corrompido ou deliberadamente construído para explorar uma vulnerabilidade.
Uma implementação insegura pode resultar em:
- execução remota de código;
- armazenamento e distribuição de malware;
- exposição de arquivos privados;
- negação de serviço;
- sobrescrita de arquivos;
- exploração de bibliotecas de processamento;
- ataques de Cross-Site Scripting;
- comprometimento da infraestrutura;
- consumo excessivo de CPU, memória ou armazenamento.
A segurança de upload não deve depender de uma única validação. Ela precisa ser estruturada em múltiplas camadas de defesa.
Extensão de arquivo não comprova o conteúdo
Um dos erros mais comuns é validar apenas o nome do arquivo.
Um atacante pode renomear facilmente:
payload.phppayload.phppara:
foto.jpgfoto.jpgA extensão mudou, mas o conteúdo continua sendo o mesmo.
Até mesmo o nome original informado pelo navegador deve ser tratado como dado não confiável. Ele pode conter caracteres especiais, múltiplas extensões, nomes excessivamente longos ou sequências criadas para confundir pessoas e sistemas.
Alguns exemplos problemáticos:
foto.jpg.php
documento.pdf.exe
imagem.png%00.php
arquivo.PHpfoto.jpg.php
documento.pdf.exe
imagem.png%00.php
arquivo.PHpDependendo do servidor, sistema operacional, proxy ou biblioteca utilizada, esses nomes podem ser interpretados de maneiras diferentes.
A extensão pode ser utilizada como parte da validação, mas nunca deve ser considerada prova suficiente do formato real.
O Content-Type também pode ser falsificado
Durante o upload, o cliente normalmente envia um cabeçalho indicando o tipo MIME do arquivo:
image/jpeg
application/pdf
image/pngimage/jpeg
application/pdf
image/pngEsse valor é útil, mas não é confiável.
O cliente controla a requisição e pode declarar qualquer tipo de conteúdo. Um arquivo executável pode ser enviado como image/jpeg, por exemplo.
Portanto, o MIME type informado pelo navegador deve ser considerado apenas uma pista inicial. A aplicação deve determinar o tipo real do arquivo no servidor, utilizando mecanismos de inspeção de conteúdo.
Magic Bytes: identificando a assinatura real do arquivo
Muitos formatos possuem uma assinatura binária no início do arquivo. Essa sequência é conhecida como Magic Bytes, file signature ou assinatura mágica.
Ela ajuda o sistema a identificar o formato real independentemente do nome ou do MIME declarado pelo cliente.
Alguns formatos conhecidos possuem assinaturas características:
- JPEG;
- PNG;
- GIF;
- PDF;
- ZIP;
- executáveis PE;
- arquivos ELF;
- documentos baseados em contêineres ZIP.
A inspeção de Magic Bytes é significativamente mais segura do que confiar apenas na extensão. Ainda assim, ela não resolve todo o problema.
Verificar os primeiros bytes confirma que o arquivo se parece com determinado formato, mas não garante que:
- o restante do conteúdo seja válido;
- o arquivo não contenha dados adicionais;
- o parser não possua vulnerabilidades;
- o arquivo não seja um poliglota;
- o conteúdo seja seguro para processamento;
- o arquivo não contenha macros, scripts ou payloads incorporados.
Magic Bytes devem fazer parte da estratégia, mas não ser a única barreira.
Arquivos poliglotas: um arquivo, múltiplas interpretações
Um arquivo poliglota é construído para ser interpretado como mais de um formato válido.
Por exemplo, um mesmo conteúdo pode ser reconhecido como imagem por uma biblioteca e como código ou arquivo compactado por outro componente.
Isso acontece porque formatos diferentes podem:
- ignorar determinados bytes;
- permitir metadados extensos;
- tolerar conteúdo adicional após o fim lógico;
- interpretar regiões diferentes do mesmo arquivo;
- utilizar estruturas compatíveis entre si.
Esse tipo de arquivo pode passar por validações superficiais de assinatura e ainda conter conteúdo perigoso.
O risco aumenta quando diferentes camadas da arquitetura interpretam o arquivo de maneiras distintas. O backend pode reconhecê-lo como imagem, enquanto o servidor web, uma CDN, o navegador ou uma biblioteca downstream pode tratá-lo de outra forma.
A segurança depende de consistência: todas as camadas devem concordar sobre o tipo, o uso e o nível de confiança daquele conteúdo.
Validar é diferente de decodificar
Uma estratégia mais robusta para imagens consiste em realmente decodificar o conteúdo com uma biblioteca apropriada.
Não basta verificar se o início do arquivo corresponde a PNG ou JPEG. O sistema deve tentar interpretar completamente a estrutura.
Caso o arquivo esteja corrompido, truncado ou fora do padrão esperado, ele deve ser rejeitado.
Mesmo assim, decodificar não significa necessariamente preservar o arquivo original.
Uma abordagem ainda mais segura é:
- receber o arquivo;
- validar seus limites;
- decodificar o conteúdo;
- gerar uma nova versão;
- descartar o arquivo original;
- armazenar apenas o resultado reconstruído.
Esse processo é conhecido como re-encoding, normalização ou sanitização por reconstrução.
Ao recriar uma imagem, muitos metadados, bytes adicionais e estruturas inesperadas deixam de ser propagados. Essa técnica reduz a superfície de ataque, embora não elimine a necessidade de bibliotecas atualizadas e isolamento operacional.
O processamento do arquivo também pode ser explorado
O arquivo não precisa ser executável para causar dano.
Bibliotecas responsáveis por processar imagens, vídeos, PDFs, documentos compactados ou arquivos de áudio podem conter vulnerabilidades.
Um arquivo malicioso pode explorar falhas durante:
- geração de thumbnails;
- extração de metadados;
- redimensionamento de imagens;
- conversão entre formatos;
- compactação e descompactação;
- leitura de PDFs;
- transcodificação de vídeos;
- indexação de conteúdo;
- análise antivírus.
Isso significa que até um upload aparentemente legítimo pode comprometer a aplicação no momento em que é processado.
O processamento deve ocorrer em ambientes restritos, com:
- baixo privilégio;
- limites de memória;
- limites de CPU;
- timeout;
- isolamento de rede;
- sistema de arquivos limitado;
- bibliotecas atualizadas;
- filas assíncronas;
- monitoramento de falhas.
Executar transformações pesadas diretamente durante a requisição HTTP também aumenta o risco de indisponibilidade.
Limites de tamanho não são suficientes
Definir um tamanho máximo é essencial, mas não impede todas as formas de abuso.
Um arquivo pequeno pode consumir muitos recursos ao ser processado.
Um exemplo clássico são imagens com dimensões extremamente grandes. O arquivo compactado pode ocupar poucos megabytes, mas exigir uma quantidade enorme de memória após ser decodificado.
Esse tipo de ataque é conhecido como decompression bomb, image bomb ou, em arquivos compactados, ZIP bomb.
A aplicação deve limitar não apenas o tamanho recebido, mas também:
- largura e altura máximas;
- quantidade total de pixels;
- duração de vídeos e áudios;
- número de páginas;
- quantidade de arquivos internos;
- profundidade de diretórios;
- taxa de compressão;
- tamanho total após descompactação;
- tempo máximo de processamento;
- memória máxima permitida.
O objetivo é controlar o custo computacional real, não apenas o tamanho do arquivo no upload.
Arquivos compactados ampliam a superfície de ataque
ZIP, TAR e outros formatos compactados exigem atenção especial.
Além de bombas de descompressão, eles podem conter nomes de arquivo preparados para escapar do diretório de extração.
Esse ataque é frequentemente chamado de Zip Slip.
Um arquivo compactado pode conter entradas como:
../../config/app.env../../config/app.envCaso a extração concatene caminhos sem normalização adequada, o atacante pode sobrescrever arquivos fora do diretório esperado.
A extração segura exige:
- validar cada caminho interno;
- rejeitar caminhos absolutos;
- rejeitar sequências de navegação;
- bloquear links simbólicos;
- limitar profundidade;
- limitar quantidade de entradas;
- limitar tamanho total descompactado;
- extrair em diretório isolado;
- nunca confiar na estrutura interna do pacote.
Arquivos compactados devem ser aceitos somente quando houver uma necessidade de negócio clara.
Nomes originais não devem definir o armazenamento
Salvar o arquivo usando diretamente o nome fornecido pelo usuário cria diversos riscos:
- colisões;
- sobrescrita;
- path traversal;
- caracteres incompatíveis;
- inconsistências entre sistemas operacionais;
- exposição de informações;
- previsibilidade de URLs;
- ambiguidades de extensão.
O nome físico deve ser gerado pela aplicação, preferencialmente com um identificador aleatório e não previsível.
O nome original pode ser armazenado apenas como metadado, após normalização e limitação de tamanho, caso seja necessário exibi-lo ao usuário.
O caminho de armazenamento também não deve ser derivado diretamente de parâmetros enviados pelo cliente.
Não armazene uploads executáveis no diretório público
Arquivos enviados por usuários não devem ser armazenados em um local onde o servidor web possa executá-los.
Mesmo que a aplicação aceite apenas imagens, uma falha de validação pode permitir o envio de scripts.
Caso o diretório de upload esteja dentro da raiz pública e o servidor interprete extensões executáveis, o atacante poderá transformar uma falha de upload em execução remota de código.
O ideal é utilizar:
- object storage;
- bucket privado;
- diretório fora da raiz pública;
- domínio separado para conteúdo;
- servidor sem capacidade de execução;
- URLs assinadas quando necessário.
Além disso, o domínio utilizado para servir uploads não deve compartilhar cookies sensíveis com o domínio principal da aplicação.
Essa separação reduz o impacto de conteúdos ativos, interpretações inesperadas e falhas de navegador.
O navegador também faz inferências
Mesmo quando o servidor define um Content-Type, navegadores podem tentar inferir o tipo real do conteúdo.
Esse comportamento, conhecido como MIME sniffing, pode fazer com que um arquivo seja interpretado de maneira diferente da esperada.
Por isso, respostas de arquivos devem utilizar cabeçalhos defensivos adequados, incluindo a instrução para não reinterpretar o tipo fornecido pelo servidor.
Arquivos que não precisam ser exibidos diretamente devem ser entregues como download.
Conteúdos potencialmente ativos, como SVG e HTML, merecem controles mais rígidos.
SVG não é apenas uma imagem
SVG é um formato baseado em XML e pode conter elementos ativos.
Dependendo de como é servido, incorporado ou sanitizado, um SVG pode incluir:
- scripts;
- referências externas;
- eventos;
- links;
- objetos incorporados;
- estruturas XML perigosas;
- conteúdo utilizado em ataques de XSS.
Permitir SVG sem um sanitizador específico é arriscado.
Em muitos sistemas, a escolha mais segura é não aceitar SVG enviado por usuários. Quando o formato for necessário, o conteúdo deve passar por uma política de sanitização rigorosa e ser servido de forma isolada.
Tratar SVG da mesma maneira que JPEG ou PNG é um erro conceitual.
PDFs e documentos também podem conter conteúdo ativo
PDFs e documentos de escritório podem carregar mais do que texto e imagens.
Eles podem conter:
- JavaScript;
- formulários;
- ações automáticas;
- links;
- anexos;
- objetos incorporados;
- macros;
- referências externas;
- metadados sensíveis.
Um antivírus pode detectar malware conhecido, mas não garante que todo comportamento perigoso seja removido.
Dependendo do contexto, pode ser necessário:
- rejeitar documentos com macros;
- remover conteúdo ativo;
- converter o arquivo para um formato controlado;
- gerar uma visualização segura;
- entregar o conteúdo somente como download;
- utilizar sandbox para análise.
A estratégia depende do motivo pelo qual o arquivo será aceito e de como será consumido.
Antivírus é uma camada, não uma garantia
A análise antivírus é recomendável em sistemas que recebem documentos, pacotes, executáveis ou arquivos compartilhados entre usuários.
Contudo, ela possui limitações.
Um antivírus pode não detectar:
- malware inédito;
- payloads ofuscados;
- vulnerabilidades lógicas;
- arquivos poliglotas;
- exploração de parsers;
- conteúdo ativo legítimo, mas perigoso;
- ataques específicos contra a própria aplicação.
O antivírus deve ser utilizado como defesa complementar.
Uma arquitetura comum é colocar o arquivo inicialmente em uma área de quarentena. Somente após validação, análise e processamento ele é promovido para o armazenamento definitivo.
Durante esse intervalo, o arquivo não deve estar disponível publicamente.
Quarentena e estados de processamento
Uploads complexos não devem ser considerados confiáveis imediatamente após o recebimento.
É útil trabalhar com estados explícitos, como:
- recebido;
- aguardando validação;
- em análise;
- aprovado;
- rejeitado;
- em processamento;
- disponível;
- removido.
Essa separação evita que um arquivo fique acessível antes da conclusão das verificações.
Também facilita:
- auditoria;
- reprocessamento;
- investigação de incidentes;
- limpeza de uploads abandonados;
- tratamento de falhas;
- aplicação de políticas de retenção.
O cliente não deve controlar o estado final do arquivo. Essa decisão pertence ao servidor.
Upload direto para object storage exige controle
Uploads diretos para serviços compatíveis com S3 reduzem carga no backend, mas introduzem novos cuidados.
Uma URL pré-assinada não deve permitir que o cliente envie qualquer conteúdo para qualquer caminho.
Ela deve restringir, quando possível:
- chave do objeto;
- tempo de validade;
- tamanho máximo;
- operação permitida;
- tipo esperado;
- propriedade do recurso;
- escopo do usuário;
- quantidade de uploads;
- prefixo de armazenamento.
Após o envio, o backend ainda deve confirmar o objeto e validar:
- existência;
- tamanho real;
- tipo real;
- associação com o usuário;
- integridade;
- estado do fluxo;
- expiração da intenção de upload.
Gerar uma URL pré-assinada não significa confiar no objeto que aparecerá posteriormente no bucket.
Buckets públicos ampliam o impacto
Tornar todo o bucket público pode simplificar a entrega, mas reduz o controle.
Arquivos sensíveis, temporários ou ainda não analisados podem ficar acessíveis por erro de configuração.
Uma estratégia mais segura utiliza:
- bucket privado;
- URLs assinadas;
- políticas por prefixo;
- CDN controlada;
- separação entre arquivos públicos e privados;
- bloqueio explícito de acesso anônimo;
- logs de acesso;
- lifecycle policies.
Também é importante impedir listagem de objetos e garantir que identificadores não sejam facilmente enumeráveis.
Autorização continua necessária depois do upload
A segurança não termina quando o arquivo é salvo.
Cada operação posterior precisa validar autorização:
- visualizar;
- baixar;
- substituir;
- confirmar;
- excluir;
- compartilhar;
- associar a uma entidade;
- gerar URL temporária.
Um usuário não deve conseguir acessar o arquivo de outro usuário apenas alterando um identificador na URL.
Isso é particularmente importante em fluxos com arquivos temporários. Um objeto enviado por um usuário não deve poder ser associado a uma conta, grupo, anúncio ou documento pertencente a outra pessoa.
A propriedade do upload precisa ser persistida e verificada no servidor.
Deduplicação também pode vazar informações
Alguns sistemas calculam o hash do arquivo para evitar armazenamento duplicado.
Essa prática pode ser útil, mas exige cuidado.
Caso a API informe que um determinado hash já existe, um atacante pode inferir que outro usuário enviou aquele conteúdo.
Em contextos sensíveis, isso pode revelar a existência de documentos privados.
Deduplicação deve respeitar limites de autorização e isolamento entre usuários ou organizações.
O hash também não substitui análise de segurança. Ele identifica conteúdo igual, mas não determina se o conteúdo é seguro.
Metadados podem expor informações
Fotos, documentos, vídeos e áudios podem conter metadados como:
- localização geográfica;
- modelo do dispositivo;
- nome do autor;
- software utilizado;
- data e hora;
- identificadores internos;
- histórico de edição;
- caminhos locais;
- nomes de usuário.
Uma foto aparentemente comum pode revelar onde foi capturada.
Quando esses dados não forem necessários, é recomendável removê-los durante a normalização do arquivo.
Privacidade também faz parte da segurança de upload.
Controle de volume e abuso
Mesmo arquivos válidos podem ser utilizados para abusar da plataforma.
Sem limites, um atacante pode:
- esgotar armazenamento;
- aumentar custos de CDN;
- saturar filas;
- consumir CPU;
- gerar milhões de objetos pequenos;
- disparar análises antivírus;
- ocupar conexões;
- explorar políticas de retenção.
A aplicação deve adotar controles como:
- rate limiting;
- cotas por usuário;
- cotas por organização;
- limite de uploads simultâneos;
- limite diário;
- limite total de armazenamento;
- expiração de arquivos temporários;
- cobrança ou bloqueio progressivo;
- detecção de padrões anômalos.
O custo financeiro também é uma superfície de ataque.
Observabilidade e auditoria
Um fluxo de upload seguro precisa ser observável.
Registros úteis incluem:
- usuário responsável;
- endereço IP;
- tamanho declarado;
- tamanho real;
- MIME declarado;
- MIME detectado;
- extensão original;
- tipo aprovado;
- hash;
- resultado do antivírus;
- motivo de rejeição;
- duração do processamento;
- biblioteca utilizada;
- falhas de parsing;
- destino final;
- ações posteriores.
Os logs não devem armazenar o conteúdo completo do arquivo nem dados sensíveis desnecessários.
Métricas também ajudam a detectar abuso:
- aumento de rejeições;
- crescimento de arquivos inválidos;
- picos de processamento;
- timeouts;
- falhas do antivírus;
- crescimento de armazenamento;
- uploads por usuário;
- divergências entre extensão e tipo real.
Uma política de allowlist é superior a uma blocklist
Bloquear algumas extensões perigosas não é suficiente.
Existem muitas extensões, variações, formatos compostos e diferenças de interpretação entre servidores.
Em vez de perguntar:
Quais arquivos perigosos devemos bloquear?
A aplicação deve perguntar:
Quais formatos são estritamente necessários para esta funcionalidade?
Se o recurso precisa apenas de fotos de perfil, talvez seja suficiente aceitar:
- JPEG;
- PNG;
- WebP.
Não há motivo para aceitar PDF, ZIP, SVG, HTML, documentos ou formatos desconhecidos.
Quanto menor a lista de formatos permitidos, menor a superfície de ataque.
A validação deve considerar o contexto de uso
Não existe uma política universal para todos os uploads.
Uma imagem de avatar, um comprovante em PDF, um pacote ZIP e um vídeo possuem riscos diferentes.
A política deve considerar:
- quem envia;
- quem acessa;
- como o conteúdo será exibido;
- se será processado;
- se será compartilhado;
- se ficará público;
- quais bibliotecas irão interpretá-lo;
- por quanto tempo será armazenado;
- qual impacto financeiro está envolvido;
- qual impacto ocorreria em caso de comprometimento.
Aceitar um formato porque ele é tecnicamente suportado não significa que ele deva ser permitido.
Arquitetura recomendada em camadas
Um fluxo robusto pode seguir esta sequência:
1. Autenticação e autorização
Antes de iniciar o upload, verificar se o usuário pode realizar aquela ação e se possui acesso ao recurso relacionado.
2. Criação de uma intenção de upload
Registrar no servidor:
- usuário;
- finalidade;
- tipos permitidos;
- tamanho máximo;
- prazo;
- destino esperado.
3. Recebimento em área temporária
O arquivo entra em um local privado e isolado, sem disponibilidade pública.
4. Validação preliminar
Verificar:
- tamanho;
- extensão;
- MIME informado;
- MIME detectado;
- Magic Bytes;
- nome;
- limites específicos do formato.
5. Processamento isolado
Executar parsing, re-encoding, extração de metadados e análise antivírus com restrições de recursos.
6. Reconstrução ou sanitização
Quando aplicável, gerar um novo arquivo controlado em vez de preservar integralmente o original.
7. Promoção para armazenamento definitivo
Somente arquivos aprovados deixam a quarentena.
8. Entrega segura
Utilizar domínio isolado, cabeçalhos corretos, URLs assinadas e regras de autorização.
9. Monitoramento e retenção
Registrar eventos, remover temporários e aplicar políticas de expiração.
Checklist prático
Antes de disponibilizar upload em produção, verifique se a aplicação:
- utiliza allowlist de formatos;
- não confia apenas na extensão;
- não confia no MIME enviado pelo cliente;
- inspeciona Magic Bytes;
- valida a estrutura completa;
- limita tamanho e custo descompactado;
- limita dimensões e quantidade de pixels;
- normaliza ou recria imagens;
- trata SVG como conteúdo ativo;
- restringe documentos com macros;
- mantém uploads fora da raiz executável;
- utiliza nomes gerados pelo servidor;
- impede path traversal;
- protege extração de arquivos compactados;
- aplica autenticação e autorização;
- verifica propriedade do objeto;
- utiliza quarentena;
- executa antivírus quando aplicável;
- processa arquivos com baixo privilégio;
- configura timeout e limites de recursos;
- utiliza bucket privado quando necessário;
- protege URLs pré-assinadas;
- remove metadados desnecessários;
- aplica rate limits e cotas;
- registra eventos relevantes;
- atualiza bibliotecas de processamento;
- testa arquivos malformados e cenários de abuso.
Conclusão
Upload de arquivos não é apenas transferência de dados. É a introdução de conteúdo não confiável dentro da arquitetura.
Extensão, MIME type e Magic Bytes são controles importantes, mas isoladamente não garantem segurança.
Uma implementação robusta combina:
- validação em profundidade;
- formatos estritamente permitidos;
- reconstrução do conteúdo;
- isolamento de processamento;
- armazenamento privado;
- autorização;
- análise de malware;
- limites de recursos;
- observabilidade;
- políticas de retenção.
A pergunta correta não é apenas:
Este arquivo possui uma extensão permitida?
A pergunta correta é:
O que acontecerá quando cada componente da arquitetura tentar interpretar este arquivo?
Essa mudança de perspectiva transforma o upload de uma validação superficial em um processo de segurança completo.