Um site criado por IA pode parecer correto até a publicação e então perder o CSS, falhar ao executar um módulo ou receber HTML no lugar de JavaScript. Muitas vezes o arquivo existe; o problema está na resposta: Content-Type ausente, genérico ou incompatível com o uso do recurso.
X-Content-Type-Options: nosniff pede ao navegador que verifique o tipo declarado em vez de tolerar certos conteúdos como se fossem outro formato. Isso reduz ambiguidades perigosas, mas também expõe configurações erradas que estavam escondidas por comportamento permissivo.
Este guia mostra como inventariar recursos, corrigir tipos MIME na origem, ativar nosniff na camada certa e validar a URL publicada sem tratar extensão de arquivo como prova suficiente.
Separe extensão, conteúdo e resposta HTTP
Três informações precisam concordar:
- o conteúdo real do arquivo;
- a forma como ele será usado na página;
- o
Content-Typeenviado na resposta.
Um caminho terminado em .js não obriga o servidor a responder com um tipo JavaScript. Para recursos obtidos por HTTP, a extensão não substitui o header da resposta.
O MIME Sniffing Standard explica por que navegadores historicamente examinaram bytes para contornar servidores com tipos incorretos e por que interpretações divergentes podem criar problemas de segurança.
Com nosniff, o Fetch Standard determina bloqueio para destinos de script quando o tipo não é JavaScript e para folhas de estilo quando a essência do tipo não é text/css.
Isso significa duas coisas importantes:
nosniffnão valida magicamente todo formato de asset;- o primeiro trabalho é corrigir
Content-Type, não remover o header quando um recurso legítimo quebra.
Faça um inventário da build
Liste os arquivos publicados e onde são consumidos:
caminho:extensão:conteúdo real:uso na página:Content-Type esperado:URL final:origem responsável:redirects:Content-Type observado:Inclua:
- scripts clássicos e módulos;
- bundles carregados por import dinâmico;
- service workers, workers e worklets;
- CSS próprio e de terceiros;
- JSON, manifests e mapas de origem;
- SVG, fontes, áudio, vídeo e downloads;
- endpoints que devolvem arquivos;
- rotas fallback de aplicações de página única;
- assets carregados apenas depois de consentimento ou interação.
Compare fonte, diretório de build e Network. Um import pode virar outro nome depois da build; uma rota pode responder com index.html por fallback quando o asset não existe.
Use uma matriz de tipos esperados
Adapte a lista ao projeto:
| Recurso | Content-Type esperado |
|---|---|
| documento HTML | text/html; charset=utf-8 |
| folha de estilos | text/css; charset=utf-8 |
| JavaScript ou módulo | tipo MIME JavaScript compatível |
| JSON | application/json |
| WebAssembly | application/wasm |
| SVG | image/svg+xml |
| manifesto web | application/manifest+json |
| WOFF2 | font/woff2 |
| arquivo desconhecido | application/octet-stream quando for download |
Não copie a tabela para um servidor sem verificar o formato. Um arquivo chamado .json que contém HTML de erro continua errado; mudar apenas o header mascararia a origem do problema.
Encontre respostas erradas antes de ativar o header
Na build, confirme que os caminhos referenciados existem:
rg -n '<script|stylesheet|import\(|new Worker|serviceWorker' distNa URL publicada, inspecione exemplos de cada classe:
curl -sS -D - -o /dev/null https://exemplo.com/assets/app.jscurl -sS -D - -o /dev/null https://exemplo.com/assets/app.csscurl -sS -D - -o /dev/null https://exemplo.com/manifest.webmanifestConfira status, redirects e Content-Type. Um 200 text/html para app.js costuma indicar fallback ou página de erro, não sucesso.
Procure estes padrões:
text/plainpara JavaScript ou CSS;application/octet-streamem um script executável;- HTML retornado por rota de asset ausente;
Content-Typeduplicado ou concatenado;- redirect para login que devolve HTML;
- CDN com metadata antiga depois de substituir o objeto;
- parâmetro de charset malformado;
- compressão ou proxy alterando headers entre origem e navegador.
Corrija a origem responsável
Tipos podem vir de lugares diferentes:
- servidor estático inferindo pela extensão;
- metadata salva junto ao objeto em storage;
- framework gerando a resposta;
- Worker, proxy ou CDN sobrescrevendo headers;
- API devolvendo um arquivo;
- fornecedor externo controlando o recurso.
Corrija onde a resposta nasce. Não adicione JavaScript para reescrever headers no cliente: quando o código roda, o navegador já decidiu como tratar a resposta.
No contrato atual do Site no Ar, o upload registra o Content-Type dos arquivos e a publicação serve um conjunto conhecido de extensões com tipos definidos. Ainda assim, a prova é a resposta final. Caminho errado, formato não suportado, metadata declarada incorretamente ou uma camada intermediária podem produzir resultado diferente do esperado.
Se o formato não estiver no conjunto reconhecido, avalie converter para um formato suportado ou confirmar a camada que entregará o tipo correto. Não renomeie bytes incompatíveis apenas para obter uma extensão conhecida.
Entenda o escopo real de nosniff
O valor válido é direto:
X-Content-Type-Options: nosniffPelo algoritmo atual do Fetch Standard, a checagem específica de nosniff considera destinos de script — incluindo scripts, workers, service workers e worklets — e o destino style.
Para scripts, a resposta precisa ter um tipo MIME JavaScript reconhecido. Para estilos, a essência precisa ser text/css. Se o tipo estiver ausente ou incompatível, o recurso é bloqueado.
Não conclua daí que imagens, fontes e downloads dispensam revisão. Eles seguem regras próprias de processamento, CORS, CORP, CSP e formato. nosniff é uma peça do modelo, não um validador universal de arquivos.
Teste os casos que mais quebram
Aplicação de página única
Um fallback que entrega index.html para qualquer caminho pode devolver HTML quando um chunk foi removido do deploy. Com nosniff, o navegador bloqueia esse HTML como script. A correção é publicar o chunk correto e fazer assets ausentes responderem como ausentes, não flexibilizar o tipo.
Módulos e imports dinâmicos
Percorra rotas e interações que carregam chunks tardios. A home pode funcionar enquanto uma tela secundária falha por tipo incorreto.
Service workers e workers
Teste instalação, atualização e execução. Um service worker antigo pode manter referências a assets de outra versão; registre cache e estratégia de atualização ao investigar.
CDN e storage de objetos
Substituir bytes sem atualizar metadata pode preservar um Content-Type antigo. Invalide cache quando necessário e inspecione a resposta em mais de um ponto de presença se houver divergência.
Recursos de terceiros
Você não controla o header do fornecedor. Confirme a resposta real e a documentação do serviço. Se ele entrega tipo incompatível, hospede localmente um asset que você tem autorização para manter, troque de endpoint ou remova a dependência.
Entregue o header na camada correta
X-Content-Type-Options é header HTTP. O contrato de Publicação envia os arquivos do site, mas não transforma um _headers incluído no pacote em configuração da resposta.
Confirme uma origem, proxy ou capacidade explícita da plataforma que controle os headers. Se essa camada não estiver disponível, mantenha a proposta registrada e valide os tipos que o fluxo atual já entrega; não marque nosniff como ativo por existir em um arquivo local.
O guia de cabeçalhos de segurança ajuda a coordenar nosniff com CSP, Referrer Policy e outras políticas sem misturar responsabilidades.
Faça rollout com testes funcionais
Em um ambiente representativo:
- corrija todos os
Content-Typeconhecidos; - adicione
X-Content-Type-Options: nosniffna camada de resposta; - limpe cache controladamente;
- abra DevTools antes do carregamento;
- percorra rotas e estados que carregam código sob demanda;
- teste offline e atualização se houver service worker;
- filtre Network por JS e CSS;
- trate bloqueios de tipo como falha de entrega.
Mantenha uma matriz:
| Jornada | Recursos críticos | Evidência esperada |
|---|---|---|
| primeira visita | HTML, CSS e bundle inicial | status e tipos corretos |
| navegação interna | chunks dinâmicos | módulos executados |
| formulário | scripts e endpoint | validação e envio funcionando |
| consentimento | Analytics e terceiros aprovados | carregamento somente quando devido |
| offline ou atualização | service worker e cache | versão nova instalada corretamente |
| página 404 | documento e assets | nenhum HTML entregue como script |
Uma varredura da home não cobre recursos tardios. Execute as jornadas reais em viewport móvel e desktop.
Publique, inspecione e republique
Depois de corrigir fonte e build, publique a versão aprovada. Verifique URL padrão e cada domínio próprio, porque proxy, cache e hostname podem alterar a resposta observada.
Use um comando focado:
curl -sS -D - -o /dev/null https://exemplo.com/assets/app.js \ | rg -i '^(content-type|x-content-type-options):'Confirme também o corpo em um download separado quando o status ou tipo parecer suspeito. Não imprima conteúdo sensível em logs compartilhados.
Se houver correção, republique o mesmo Site e repita toda a matriz. Preserve o endereço para comparar a versão anterior com a nova.
Registre:
Site ID:versão:asset e URL:Content-Type esperado:Content-Type observado:nosniff observado:cache limpo ou preservado:jornadas executadas:erros e correções:Prompt copiável para o agente
Revise tipos MIME e a adoção de X-Content-Type-Options: nosniff sem publicar ainda.
Fonte: [caminho]Build: [caminho]URL atual: [URL]Domínios: [lista]
- Inventarie HTML, CSS, scripts, módulos, workers, manifests, fontes e downloads.- Compare extensão, bytes, uso e Content-Type na resposta.- Identifique fallbacks que devolvem HTML para caminhos de asset.- Corrija os tipos na origem responsável antes de adicionar nosniff.- Teste chunks dinâmicos, service worker, CDN e terceiros.- Confirme o header na resposta HTTP real.- Não presuma que um arquivo _headers será interpretado.- Entregue diff, matriz de jornadas e evidências antes de publicar.Checklist final
- arquivos e usos foram inventariados;
- extensão, conteúdo e
Content-Typeconcordam; - scripts e estilos têm tipos reconhecidos;
- assets ausentes não recebem fallback HTML silencioso;
- chunks, workers e service worker foram testados;
- metadata de CDN ou storage foi atualizada;
- terceiros incompatíveis foram corrigidos ou removidos;
-
nosniffaparece na resposta real, quando suportado; - nenhuma configuração local foi confundida com header ativo;
- URL padrão e domínios próprios foram comparados;
- console e Network estão limpos nas jornadas críticas;
- evidências correspondem à versão publicada.
nosniff funciona melhor como teste de honestidade da entrega: cada recurso precisa declarar o que realmente é e chegar pelo caminho em que será usado. Quando tipo, bytes e destino concordam, o header reforça o contrato em vez de revelar uma build frágil em produção.
