Defaults.Exposed

Defaults.ExposedCorreções › Proteção contra MIME-sniffing (X-Content-Type-Options)

Como corrigir Proteção contra MIME-sniffing (X-Content-Type-Options)

Um cabeçalho de uma linha que impede os navegadores de adivinharem o que um ficheiro realmente é. Sem ele, um ficheiro que alguém carregue para o seu site — ou um ficheiro nas suas próprias páginas — pode ser mal interpretado pelo navegador e executado como código, que é exatamente como alguns ataques transformam um carregamento de aparência inofensiva numa forma de roubar as sessões dos seus clientes.

O essencial para o seu negócio: A ausência deste cabeçalho é um sinal claro e detetável de que o básico não está implementado. Por si só raramente deita um site abaixo, mas combinado com um formulário de carregamento de ficheiros ou conteúdo gerado por utilizadores abre caminho a que um atacante execute código malicioso nos navegadores dos seus visitantes — sequestrando sessões autenticadas, roubando dados de cartão ou de início de sessão e colocando-o do lado errado de uma conversa sobre violação de dados. É uma das correções mais baratas em segurança: uma linha, gratuita, cerca de cinco minutos.

Quanto isto lhe pode custar

Por que importa. Quando um servidor é vago sobre o que é um ficheiro, os navegadores tentam adivinhar («sniff») o tipo de conteúdo. Os atacantes exploram esse palpite: carregam um ficheiro que o servidor rotula como imagem, mas constroem o seu conteúdo de forma a que o navegador decida que é, na verdade, JavaScript — e o execute. O cabeçalho X-Content-Type-Options: nosniff diz a cada navegador para parar de adivinhar e confiar no tipo declarado pelo servidor, fechando toda essa categoria de truques. É uma verificação pontuada que vale 25 pontos e é classificada com severidade média quando está em falta.

A versão curta para o proprietário

Há um pressuposto silencioso embutido em todos os navegadores: quando descarrega um ficheiro do seu site, tenta perceber que tipo de ficheiro é. Normalmente confia no seu servidor. Mas se o seu servidor for vago, o navegador vai adivinhar — e a essa adivinhação chama-se MIME-sniffing.

O problema é que os atacantes conseguem manipular o palpite. Conseguem construir um ficheiro que o seu servidor acredita honestamente ser uma imagem inofensiva, mas que o navegador, deixado a adivinhar, decide ser, na verdade, um pedaço de código — e depois executa-o, mesmo dentro do navegador do seu cliente, no seu domínio.

Existe uma instrução de uma linha que desliga a adivinhação: X-Content-Type-Options: nosniff. Diz a cada navegador: «não adivinhes — confia exatamente no que o meu servidor te diz.» É essa toda a correção. É gratuita, demora cerca de cinco minutos e, num site bem construído, não parte nada.

Esta verificação procura esse cabeçalho. Se estiver em falta, perde 25 pontos e é classificado como problema de severidade média — não porque o cabeçalho, sozinho, seja uma catástrofe, mas porque a sua ausência é um sinal fiável de que o básico não foi protegido.

O que isto lhe pode custar

São cenários realistas, ao nível do negócio — não teatro de pior caso.

Nenhum destes cenários exige um atacante sofisticado. O abuso de MIME-sniffing é bem compreendido e automatizado, que é exatamente por que os analisadores assinalam o cabeçalho em falta com tanta firmeza.

O que isto é, na realidade

Quando um navegador recebe um ficheiro, o servidor deve rotulá-lo com um tipo de conteúdo (por exemplo, image/png para uma imagem PNG ou text/html para uma página web). Historicamente, os navegadores não confiavam totalmente nesse rótulo — em parte porque alguns servidores erravam — por isso espreitavam os bytes reais do ficheiro e decidiam por si. Essa espreitadela é o MIME-sniffing.

Era uma conveniência que se tornou um passivo. Se um atacante conseguir pôr um ficheiro no seu site (através de um formulário de carregamento, um campo de comentários, um documento importado) e influenciar o seu conteúdo, pode construir algo que o servidor rotula de forma inócua mas que o navegador deteta como script executável. O navegador executa-o então no seu domínio, com toda a confiança que o seu domínio carrega.

O X-Content-Type-Options: nosniff elimina por completo a adivinhação. Com ele definido, diz-se ao navegador: usa o tipo declarado pelo servidor e mais nada. Um ficheiro rotulado como imagem é tratado como imagem, ponto final — mesmo que o seu conteúdo pareça script. O vetor de ataque fecha-se.

O que é «bom»: cada resposta do seu site — páginas e recursos por igual — carrega exatamente este cabeçalho:

X-Content-Type-Options: nosniff

Não há outro valor válido nem nada a afinar. Se a sua CDN e o seu servidor o adicionarem ambos (de modo que vê nosniff, nosniff), está bem e conta na mesma como aprovado.

Como corrigir (gratuito, ~5 minutos)

Entregue esta secção a quem gere o seu site — o seu responsável de TI, o seu programador web ou o apoio de alojamento. A correção é gratuita e rápida; não há nada a comprar. O que está a pedir é simples: «Adiciona o cabeçalho de resposta X-Content-Type-Options: nosniff a cada página e recurso do site.»

Eis o pormenor para eles, por plataforma comum.

Cloudflare (ou uma CDN/proxy semelhante) — muitas vezes o sítio mais rápido para o fazer, cobrindo todo o site de uma vez:

Nginx — adicione dentro do bloco server (ou location) relevante:

add_header X-Content-Type-Options "nosniff" always;

A palavra-chave always garante que é enviado também nas respostas de erro. Recarregue o Nginx depois de guardar.

Apache — requer o mod_headers ativado; na configuração do site ou no .htaccess:

Header always set X-Content-Type-Options "nosniff"

IIS / alojamento Windows — no web.config, dentro de <system.webServer>:

<httpProtocol>
  <customHeaders>
    <add name="X-Content-Type-Options" value="nosniff" />
  </customHeaders>
</httpProtocol>

Node / Express — defina-o para cada resposta:

app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  next();
});

(Ou use o pacote helmet, que define este e vários outros cabeçalhos de segurança por omissão.)

Sites Google Workspace / Microsoft 365: estes gerem o seu e-mail e documentos, não o alojamento do seu site público, por isso o cabeçalho não se define aí — define-se onde o seu site é realmente servido (a sua CDN, servidor web ou construtor de sites). Se usa um construtor de sites alojado (Squarespace, Wix, Shopify e semelhantes), muitos adicionam este cabeçalho por si automaticamente; verifique o resultado em vez de assumir, e pergunte ao apoio deles se estiver em falta.

Depois de implementar, verifique. Volte a correr a análise, ou peça ao seu programador para verificar os cabeçalhos de resposta nas ferramentas de programador do navegador (separador Network → clicar em qualquer pedido → Response Headers) e confirmar que X-Content-Type-Options: nosniff está presente. Teste o site brevemente para confirmar que nada estilizado ou com script partiu — num site bem construído, nada partirá.

Erros comuns

Entregue isto ao seu responsável de TI

O resumo técnico: esta verificação inspeciona os cabeçalhos de resposta HTTP e é aprovada quando X-Content-Type-Options está presente e o seu valor (sem distinção de maiúsculas/minúsculas) contém nosniff — incluindo o caso multi-origem nosniff, nosniff, em que uma CDN e a origem o definem ambas. Ausente ou qualquer valor que não seja nosniff falha. É uma verificação pontuada P2 que vale 25 pontos, classificada com severidade média quando falha, e mapeia para o OWASP Top 10 A05 (Security Misconfiguration). A remediação é um único cabeçalho de resposta estático aplicado a todas as respostas; não há parâmetros nem valores alternativos válidos. Defina-o na borda (CDN) para cobertura de todo o site, ou no servidor web com semântica always para que seja emitido também nas respostas de erro, depois confirme nos cabeçalhos de resposta.

Perguntas frequentes

Não permitimos que ninguém carregue ficheiros. Mesmo assim precisamos disto?

Sim, e continua a valer a pena. O cabeçalho é defesa em profundidade: também impede o navegador de interpretar mal scripts, folhas de estilo e ficheiros de dados servidos pelo seu próprio site, o que protege contra vários truques de cross-site scripting mesmo em sites sem formulário de carregamento. Não custa nada e nunca parte um site corretamente configurado, por isso não há razão para o saltar.

Adicionar isto vai partir alguma coisa no nosso site?

Quase nunca. O nosniff limita-se a fazer os navegadores respeitarem o tipo de conteúdo que o seu servidor já envia. A única forma de causar problemas é se o seu servidor estiver a rotular ficheiros incorretamente — por exemplo, a enviar uma folha de estilo ou um script com o tipo errado. Se algo partir, isso é um bug real que o nosniff expôs e não causou, e vale a pena corrigi-lo de qualquer forma. Teste uma vez após implementar.

O que é, na prática, «bom»?

Um único cabeçalho de resposta em cada página e recurso: X-Content-Type-Options: nosniff. Essa é a configuração correta na íntegra — não há outros valores válidos nem afinações a fazer.

A nossa CDN (Cloudflare ou semelhante) e o nosso servidor adicionam-no ambos — isso é problema?

Não. Ver o valor duas vezes («nosniff, nosniff») porque tanto a CDN como a origem o definem está perfeitamente bem e continua a passar. Não precisa de remover nenhum.

Corrigir isto custa dinheiro?

Não. A correção é uma linha de configuração gratuita no seu servidor web ou CDN. Quem lhe cobrar para adicionar um único cabeçalho está a cobrar a mais. As únicas coisas que valem a pena pagar nesta área são monitorização contínua, uma vista de carteira sobre muitos sites ou uma auditoria formal — não a correção em si.

Em que difere isto de uma Content Security Policy (CSP)?

São complementares. A CSP controla que scripts e recursos podem, de todo, carregar; o nosniff impede o navegador de classificar mal um ficheiro que carrega. Quer os dois. O nosniff é muito mais simples e rápido de adicionar, por isso é um bom primeiro passo no caminho para uma CSP completa.