O que são os headers de segurança
Os headers (cabeçalhos) de segurança HTTP são headers de resposta que o servidor envia para dizer ao navegador como tratar a página: quais origens podem carregar scripts, se a página pode ser exibida dentro de um frame, se o HTTPS deve ser obrigatório, quanto da URL pode vazar no Referer, quais recursos sensíveis do navegador a página pode usar. São instruções para o navegador, e quem as aplica é o próprio navegador. O servidor decide adotá-las (é um opt-in); o navegador que entende o header aplica a restrição.
Eles importam porque é no navegador que acontece a maior parte do estrago de uma vulnerabilidade web. Uma falha de cross-site scripting roda no navegador. O clickjacking acontece no navegador. Um cookie de sessão roubado é reutilizado a partir de um navegador. Os headers de segurança permitem que o servidor limite o que o navegador vai fazer, e assim, mesmo quando alguma coisa escapa, o raio de impacto é menor.
Defesa em profundidade, não substituto
Um erro comum é achar que acrescentar headers deixa a aplicação segura. Não deixa. Os headers são uma segunda camada. Se o seu código concatena entrada não confiável dentro do HTML, você tem um bug de cross-site scripting, e a Content-Security-Policy está ali para reduzir o estrago, não para corrigir o bug. Corrija o bug e mantenha o header como rede de proteção para o bug que você ainda não encontrou.
O modelo mental certo é o de camadas que falham de forma independente. O tratamento da entrada é a primeira camada. Uma Content-Security-Policy forte é a segunda. As flags de cookie são a terceira. O (HTTP Strict Transport Security) elimina uma classe inteira de downgrade no transporte. Nenhuma delas basta sozinha; o valor está em empilhá-las, para que uma fraqueza não vire um comprometimento completo.
Os headers que têm mais peso
Poucos headers fazem a maior parte do trabalho, e o analisador dá a cada um o peso correspondente:
O Strict-Transport-Security (HSTS) obriga o navegador a usar HTTPS com aquele host e fecha a janela de downgrade em que um atacante na rede transforma uma requisição https:// em HTTP puro. É, sozinho, o controle de transporte de maior impacto. Veja HSTS e a exigência de HTTPS.
A Content-Security-Policy (CSP) é o principal controle de defesa em profundidade contra cross-site scripting e injeção de conteúdo. Uma boa política restringe de onde podem vir scripts, estilos e outros recursos, e uma política forte elimina o 'unsafe-inline'. Veja Content Security Policy, diretiva por diretiva.
O X-Content-Type-Options: nosniff impede o navegador de adivinhar o tipo de uma resposta e de executar, por exemplo, uma imagem enviada por upload como se fosse script. É um header curto e sem efeito colateral, então a ausência dele sempre merece um alerta.
O X-Frame-Options e o frame-ancestors da CSP decidem se outros sites podem colocar a sua página dentro de um iframe, que é a base do clickjacking. O controle moderno é o frame-ancestors; o header legado é o X-Frame-Options. Veja Clickjacking e controle de enquadramento.
A Referrer-Policy define quanto da URL atual é enviado quando o usuário sai para outra página, o que é uma questão de privacidade e de vazamento de informação quando as URLs contêm identificadores ou tokens.
A Permissions-Policy restringe o acesso a recursos sensíveis do navegador, como câmera, microfone e geolocalização, para que um script comprometido ou embutido não chegue a eles em silêncio.
Os atributos de cookie (Secure, HttpOnly, SameSite e os prefixos __Host- e __Secure-) protegem os cookies de sessão contra roubo e contra uso indevido entre sites. Eles vão no Set-Cookie, e não num header próprio, mas fazem parte da mesma postura. Veja Flags de segurança de cookies.
Os headers de cross-origin () decidem quais outros sites podem ler uma resposta. O caso perigoso é uma origem wildcard combinada com credenciais, que expõe dados autenticados a qualquer site.
Como a nota é calculada
O analisador dá pontos aos headers de proteção que consegue avaliar, pondera cada um pela importância e depois aplica um pequeno conjunto de travas que refletem como o risco funciona na vida real, em vez de deixar que um monte de pequenos acertos esconda uma falha crítica:
- Se o HSTS estiver ausente ou fraco, ou se a CSP estiver ausente, a nota tem um teto, porque cada um desses casos deixa aberta uma classe inteira de ataque. Se os dois estiverem ausentes, o teto é mais baixo.
- Um cookie com atributos fracos limita a nota, porque um cookie de sessão que pode ser roubado compromete todo o resto.
- Uma política de CORS que combina origem wildcard com credenciais limita a nota, porque expõe dados diretamente.
- Headers que revelam a versão do servidor ou do framework custam uma pequena penalidade cada um. Eles não quebram nada, mas dão uma vantagem inicial ao atacante.
A nota em letra é um resumo. O que importa são os achados logo abaixo dela: cada header aparece marcado como forte, adequado, fraco, ausente ou informativo, com o motivo explicado.
Como analisar uma resposta
Cole uma resposta completa (a linha de status mais os headers) ou só um bloco de headers. Você pode copiá-los do painel de rede do navegador, do curl -I ou de um scanner. A ferramenta faz o parsing dos headers, avalia cada um, lista os cookies à parte, com a situação das flags de cada um, e mostra a postura de cross-origin. Os itens ausentes e fracos vão para o topo, para que as falhas sejam a primeira coisa que você vê, e cada header de proteção ausente vem com um valor recomendado que você pode adotar.
O que a ferramenta não verifica
O analisador lê uma resposta. Ele não vê os headers de requisição (como o Origin ou o conjunto Sec-Fetch-*), porque quem os envia é o navegador, e não o servidor. Ele não avalia a sua configuração de TLS, o certificado nem as cipher suites; esses são outros assuntos, com ferramentas próprias. E ele não consegue saber se uma configuração permissiva é um problema real ou uma escolha consciente para um endpoint público e sem credenciais. Ele aponta a postura e explica o trade-off; a decisão sobre a intenção é sua.
Esta série, em ordem
Este artigo abre a série Os headers de segurança do navegador. Ele explica por que os headers são uma camada por cima do código seguro e quais têm mais peso; as partes da série tratam desses headers um de cada vez, do transporte para cima: o próprio HTTPS, o cookie de sessão, as leituras cross-origin, a política de scripts (duas vezes: diretiva por diretiva e depois do jeito que o navegador a interpreta) e o controle de enquadramento (framing).
- HSTS e a exigência de HTTPS. Como o Strict-Transport-Security fecha a janela de downgrade, o que fazem o max-age, o includeSubDomains e o preload, e os erros que o desativam.
- Flags de segurança de cookies. Secure, HttpOnly e SameSite, por que o SameSite=None exige o Secure, e os prefixos __Host- e __Secure-.
- CORS explicado: o controle de fronteira do navegador. A same-origin policy é o muro e o CORS é a porta: requisições simples, preflights e para que serve o OPTIONS.
- Content Security Policy, diretiva por diretiva. Uma CSP diretiva por diretiva: o default-src, o que o unsafe-inline e o unsafe-eval entregam, nonces, hashes e o report-only.
- Uma Content Security Policy, lida como o navegador a lê. O algoritmo que o navegador usa para ler um header CSP, e os passos exatos em que a maioria das políticas com defeito falha em silêncio.
- Clickjacking e controle de enquadramento. Como o framing permite o clickjacking, o X-Frame-Options contra o frame-ancestors, e por que o ALLOW-FROM está obsoleto.