Headers de segurança HTTP: o que fazem, como verificar e como configurar

HSTS, nosniff, Referrer-Policy e CSP: o que cada header evita, o que o scanner verifica e como configurar do jeito certo.

Severidade típica: Média · Verificado pelo módulo da NovaPentest: HTTP Headers

O que é

Headers de segurança HTTP são headers de resposta que dizem ao navegador como tratar o seu site. Não custam nada em tempo de execução e são configurados uma única vez, no servidor web, no proxy reverso ou na aplicação.

O Strict-Transport-Security (HSTS) instrui o navegador a usar HTTPS no seu domínio por um período definido, mesmo quando o usuário digita http:// ou clica em um link antigo. Depois da primeira visita em HTTPS, o navegador converte as requisições HTTP em HTTPS antes que elas saiam da máquina.

O X-Content-Type-Options: nosniff faz o navegador confiar no Content-Type que você enviou, em vez de tentar adivinhar o tipo pelo conteúdo do arquivo. Isso impede que um arquivo de texto ou imagem enviado por upload seja interpretado como script ou HTML.

O Referrer-Policy controla quanto da URL atual vai no header Referer quando o usuário segue um link ou a página carrega um recurso de terceiros. Sem ele, caminhos completos e query strings podem chegar a provedores de analytics, CDNs e a qualquer site externo para o qual você aponta.

O Content-Security-Policy (CSP) restringe de onde scripts, estilos, frames e outros recursos podem ser carregados, e é a principal defesa do lado do navegador para limitar o estrago de um script injetado. Ele merece uma implantação cuidadosa à parte, por isso aparece aqui só de passagem.

Dois headers vão na direção oposta: Server e X-Powered-By. Eles não protegem nada e só anunciam o software, e às vezes a versão exata, que roda por trás do site.

Nenhum desses headers corrige um bug no seu código. Eles reduzem o que um atacante consegue fazer com ele e fecham brechas entre o navegador e o seu servidor.

Como é explorada

Sem HSTS, a primeira requisição do navegador ao seu site costuma ser em HTTP puro: o domínio digitado na barra, um favorito salvo há anos, um link em um e-mail antigo. Em uma rede compartilhada ou hostil, como um Wi-Fi público, quem controla a rede pode responder a essa requisição no lugar do seu servidor e manter o usuário em uma cópia sem criptografia do site. O usuário vê uma página aparentemente normal, sem o cadeado, e tudo o que digita, incluindo senhas e cookies de sessão sem a flag Secure, pode ser lido no caminho. O HSTS elimina esse primeiro salto sem criptografia para quem já visitou o site.

Sem X-Content-Type-Options: nosniff, o navegador que recebe um arquivo com tipo vago ou errado pode decidir sozinho o que ele é. Se o seu site aceita upload e devolve os arquivos a partir do próprio domínio, um arquivo que passou na validação como imagem pode ser tratado como HTML ou script, rodando na sua origem com acesso às sessões dos usuários.

Sem Referrer-Policy, navegadores mais antigos e algumas configurações enviam a URL completa da página para todo destino externo. URLs costumam carregar mais do que deveriam: tokens de redefinição de senha, links de convite, termos de busca, IDs internos de registros. Tudo isso acaba em logs de terceiros que você não controla.

Sem CSP, se existir um bug de injeção em qualquer parte do site, o script injetado pode carregar código de qualquer domínio e enviar dados para qualquer lugar.

Os headers Server e X-Powered-By não criam uma falha sozinhos, mas uma string de versão exata torna trivial cruzar o seu site com listas de versões vulneráveis conhecidas, o que encurta o trabalho da varredura automatizada.

Como detectar

O módulo HTTP Headers da NovaPentest envia uma requisição GET para a URL alvo, segue redirecionamentos e analisa os headers da resposta final. Ele reporta a ausência de Strict-Transport-Security como Alta, a ausência de Content-Security-Policy como Média e a ausência de X-Content-Type-Options ou de Referrer-Policy como Baixa. Também reporta, como Info, qualquer header Server ou X-Powered-By encontrado, com o valor como evidência. O módulo roda no scanner passivo gratuito em novapentest.com/scan e também nos scans completos.

Saiba o que essa verificação não faz. Ela testa, na maior parte, só se cada header está presente, não se o valor é adequado. A exceção é o HSTS: max-age=0 é reportado, porque desliga a proteção, e o HSTS só é verificado em respostas HTTPS, onde o navegador o respeita. Um CSP que libera tudo ainda passa nessa verificação. Ela olha uma única página, então headers que a aplicação define em algumas rotas e esquece em outras não aparecem. E o header Server é reportado sempre que existe, mesmo que diga apenas nginx, sem versão.

Para conferir manualmente, busque os headers da página inicial com curl -sI https://example.com e procure as linhas esperadas. Acrescente -L para seguir redirecionamentos como o navegador faz e repita em alguns caminhos representativos, como a página de login, um endpoint de API e um arquivo estático, porque é comum uma camada adicionar os headers e outra não. Um resultado correto inclui linhas como Strict-Transport-Security: max-age=31536000; includeSubDomains, X-Content-Type-Options: nosniff e Referrer-Policy: strict-origin-when-cross-origin. Confira os valores, não só os nomes: um max-age de poucos segundos quase não protege. As ferramentas de desenvolvedor do navegador mostram o mesmo na aba Network, em Response Headers.

Como corrigir

1. Defina onde os headers serão configurados. Escolha uma camada, normalmente o proxy reverso ou a aplicação, para que eles saiam em todas as respostas, inclusive páginas de erro e arquivos estáticos. Configurar o mesmo header em duas camadas pode gerar duplicatas que os navegadores tratam de forma inconsistente.

2. Ative o HSTS só depois que todos os subdomínios estiverem acessíveis em HTTPS, porque o includeSubDomains vale para todos eles. Comece com um max-age curto, como 300, confirme que nada quebrou e depois suba para 31536000. No nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; No Apache: Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains". No ASP.NET Core, chame app.UseHsts() em produção; no Express, o pacote helmet já envia o header por padrão. O navegador ignora HSTS recebido em HTTP, então basta enviá-lo em HTTPS.

3. Adicione X-Content-Type-Options: nosniff em tudo e garanta que cada resposta tenha um Content-Type correto, principalmente nos uploads de usuários. No nginx: add_header X-Content-Type-Options "nosniff" always;

4. Adicione Referrer-Policy: strict-origin-when-cross-origin como padrão razoável, ou no-referrer nas páginas cujas URLs carregam tokens. No IIS, inclua os dois headers em system.webServer/httpProtocol/customHeaders no web.config.

5. Remova ou reduza os headers que expõem tecnologia. No nginx, use server_tokens off; no Apache, ServerTokens Prod e ServerSignature Off; no Express, app.disable('x-powered-by'); no ASP.NET Core com Kestrel, options.AddServerHeader = false.

6. Planeje o CSP separadamente. Comece com Content-Security-Policy-Report-Only para ver o que seria bloqueado, corrija as violações e só então aplique a política.

7. Rode curl -sI em vários caminhos a cada deploy e inclua a verificação no pipeline, para que uma mudança de configuração não remova os headers sem ninguém perceber. Atenção: no nginx, diretivas add_header dentro de um bloco location substituem, em vez de complementar, as definidas no nível do server.

Verifique o seu próprio site

Comece pelo scan passivo gratuito: não precisa de conta e você recebe uma nota de A a F cobrindo cabeçalhos, TLS, cookies, DNS e outras configurações que qualquer visitante consegue observar. Ele não envia payloads de ataque, então não confirma todas as classes de falha. O scan completo, disponível com uma conta gratuita, executa as verificações ativas, incluindo a descrita nesta página.

Escaneie seu site grátis