Este documento foi produzido para uma apresentação em um grupo de discussão sobre CyberSecurity.

Na ocasião, estávamos aprendendo sobre o protocolo HTTP e cada participante ficou responsável por um header HTTP; o meu foi o Content-Type.

Sumário


Definição

Este header é utilizado para indicar o tipo de arquivo (MIME type) do recurso.

Faz parte dos headers das respostas do servidor e das requisições (especificamente em métodos como POST e PUT, para descrever o corpo da mensagem).

O Content-Type é um contrato de dados que busca garantir a interpretação correta, eficiente e segura do conteúdo.

  • Em geral, é obrigatório no lado do servidor e pode ser obrigatório ou opcional no lado do cliente (dependendo do método HTTP).

Esse é o mecanismo principal para que o navegador decida como processar os dados recebidos, sendo priorizado em relação à extensão do arquivo, pois o MIME type está relacionado à estrutura dos dados, enquanto a extensão é apenas uma convenção.


Especificações

  • MIME sniffing

    Por padrão, muitos navegadores realizam um processo chamado MIME sniffing, no qual tentam avaliar o conteúdo do recurso e adivinhar um tipo, processando-o de acordo com esse valor autodeclarado, mesmo que difira do valor determinado pelo servidor.

    É nesse ponto que reside a principal falha de segurança. Quando esse processo não é desativado, é possível realizar ataques de Cross-Site Scripting (XSS): recursos com tipos de mídia genéricos (text/plain) ou com Content-Type ausente, contendo código JavaScript, podem ser “sniffados” pelo navegador, que, ao identificar código executável, pode executá‑lo automaticamente.

  • Como desativar esse processo?

    O header adicional X-Content-Type-Options: nosniff desativa a adivinhação do MIME type; assim, o navegador é obrigado a confiar apenas no Content-Type fornecido pelo servidor.

    Quando o MIME type não é enviado e a opção nosniff está ativada, o navegador costuma bloquear o recurso, evitando a sua execução indevida.

    Esse comportamento surgiu porque muitos recursos eram nomeados incorretamente pelos desenvolvedores; a tentativa de “corrigir” no cliente tornou-se uma lacuna de segurança.

  • Como esse header é opcional?

    No lado do cliente, o header Content-Type pode estar ausente em algumas requisições; isso depende da tolerância a erros do protocolo HTTP. Ainda assim, é altamente recomendado enviar esse header.

    No lado do servidor, omitir o Content-Type é falha de implementação, pois deixa o cliente sem saber como interpretar os dados, prejudicando a experiência do usuário e representando risco de segurança caso não exista um header adicional de proteção.

  • Como funciona a exploração dessa falha?

    O sniffing ocorre no cliente; o perigo real surge quando o servidor permite upload de arquivos e um atacante envia um arquivo com MIME type de imagem, mas cujo conteúdo é um script malicioso. Na ausência do header X-Content-Type-Options: nosniff, outro usuário pode receber esse arquivo e o navegador, ao realizar o sniffing, pode executar o código.

  • Curiosidade

    Existe um padrão oficial — o MIME Sniffing Standard da WHATWG — que define como os navegadores devem proceder durante o sniffing, padronizando esse comportamento entre navegadores.


Objetivos

  • Performance e padronização

    • Cache e otimização: o tipo de dado correto permite ao navegador/servidor aplicar estratégias de cache e otimização de forma eficiente.
    • Parsing eficiente: quando o tipo corresponde ao recurso, o navegador pode usar o parser adequado, evitando tentativas de interpretação incorretas.
  • Segurança

    • Em conjunto com X-Content-Type-Options: nosniff, o Content-Type é uma camada importante de proteção contra ataques de XSS.

Diretivas

  • Charset

    • Indica o conjunto de caracteres utilizado, fundamental para a exibição correta de caracteres especiais e para evitar “caracteres quebrados”.
  • Boundary

    • Sempre que o MIME type é do tipo multipart (várias seções distintas no mesmo recurso), é necessário enviar a diretiva boundary.
    • Trata‑se da string utilizada como delimitador entre as partes; deve ter entre 1 e 70 caracteres e evitar caracteres que possam aparecer no conteúdo.

Exemplo — Exceção ao header

Não há impedimento técnico para que um arquivo PHP seja servido com Content-Type: text/css; se o arquivo PHP produzir conteúdo com estrutura válida de CSS, o navegador o tratará como CSS.

Contudo, quando o MIME type for genérico ou incorreto e o arquivo PHP for incluído como CSS em uma página HTML, o comportamento dependerá da tolerância a erros do navegador — e da presença de proteções como X-Content-Type-Options: nosniff. Em geral, confiar no contrato do Content-Type é a prática correta.


Referências: