Voltar ao blog

Cabeçalhos de segurança: HSTS, CSP, X-Frame-Options e outros

· 7 min de leitura

Em resumo: Os cabeçalhos HTTP de segurança são linhas que o servidor adiciona a cada resposta HTTP para dizer ao navegador como tratar o teu site. Corretamente configurados eliminam classes inteiras de ataques (XSS, clickjacking, MITM) - e são grátis.

Em resumo: Os cabeçalhos HTTP de segurança são linhas que o servidor adiciona a cada resposta HTTP para dizer ao navegador como tratar o teu site. Corretamente configurados eliminam classes inteiras de ataques (XSS, clickjacking, MITM) - e são grátis.

Porque importam

Uma aplicação pode ser perfeitamente segura do lado backend, mas sem cabeçalhos corretos continua vulnerável a ataques do lado navegador: cross-site scripting (XSS), clickjacking, protocol downgrade, MIME confusion. Os cabeçalhos de segurança movem a defesa para o navegador.

Strict-Transport-Security (HSTS)

Força HTTPS para todas as visitas futuras. Após a primeira visita HTTPS o navegador lembra-se do domínio e ele mesmo reescreve qualquer link http:// para https://, mesmo se o utilizador clicar numa resposta má.

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
  • max-age=63072000 = válido 2 anos
  • includeSubDomains = a regra aplica-se também a todos os subdomínios (atenção: se tens um subdomínio HTTP-only, parte-o)
  • preload = permite inclusão na lista HSTS preload integrada no Chrome / Firefox / Safari

Atenção: HSTS com preload demora 6+ meses a ser removido da lista. Não incluas preload antes de verificares que HTTPS funciona estável também para todos os subdomínios.

Content-Security-Policy (CSP)

O cabeçalho mais poderoso mas também mais difícil de configurar. Whitelist de onde o navegador pode carregar scripts, estilos, imagens, iframes. Sem CSP um atacante que pode injetar tag <script> pode executar qualquer JS - com CSP apenas código de fontes aprovadas.

Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-...'; img-src 'self' data: https://cdn.example.com; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'

Diretivas comuns:

  • default-src 'self' = por defeito permitir apenas recursos do meu domínio
  • script-src = fontes JS (especificar hash ou nonce para scripts inline)
  • style-src = fontes CSS
  • img-src = imagens
  • connect-src = AJAX, WebSocket, EventSource
  • frame-ancestors 'none' = ninguém pode embed a página em iframe (melhor que X-Frame-Options)
  • report-uri /csp-report = o navegador envia JSON em cada violação (tu apanhas no backend e fazes log)

X-Frame-Options

Alternativa mais antiga ao frame-ancestors. Previne clickjacking - o atacante insere a tua página como iframe e cobre com botões invisíveis.

X-Frame-Options: DENY

Valores: DENY (ninguém), SAMEORIGIN (apenas o meu domínio), ALLOW-FROM uri (deprecated).

X-Content-Type-Options

X-Content-Type-Options: nosniff

Desliga o MIME sniffing - o navegador vai respeitar o Content-Type que o servidor devolveu. Sem isso um atacante pode fazer upload de ficheiro com tipo errado (ex. imagem que é na realidade HTML com script) e o navegador pode executá-lo como web page.

Referrer-Policy

Referrer-Policy: strict-origin-when-cross-origin

Controla quanta informação sobre a página anterior o navegador envia no cabeçalho Referer ao clicar. O default em navegadores modernos já é strict-origin-when-cross-origin, mas o cabeçalho declarativo explícito assegura consistência.

Permissions-Policy

Desliga as APIs que não precisas - câmara, microfone, GPS, geolocation. Um atacante via XSS não pode pedir estas APIs.

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

Configuração prática em nginx

server {
  listen 443 ssl http2;
  server_name example.com;

  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
  add_header X-Content-Type-Options "nosniff" always;
  add_header X-Frame-Options "DENY" always;
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

  # CSP é extensa - define conforme a tua aplicação
  add_header Content-Security-Policy "default-src 'self'; script-src 'self'; ..." always;
}

A chave é always - sem ele o nginx omite cabeçalhos em respostas de erro (4xx, 5xx).

Audit do estado atual

Mais fácil via ferramenta online. O nosso header check vai mostrar-te que cabeçalhos faltam e quais estão errados. Para audit aprofundado também o securityheaders.com dá pontuação A-F.

Conclusão

Os cabeçalhos de segurança são um dos melhores investimentos em rácio esforço-ganho na área de segurança - tipicamente meia hora de setup no reverse proxy contra uma categoria inteira de ataques do lado navegador. Audit uma vez por meio ano no âmbito de manutenção regular é mínimo razoável.

Audit grátis de security headers

Sem registo, resultado em três segundos.

Testar o site →


Experimente o ePulz.io grátis - 7 dias sem cartão de crédito.

Criar conta