Segurança de Headers HTTP
Esta aula aborda a segurança de headers HTTP, com foco em CSP, HSTS, X-Frame-Options e Referrer-Policy. Você aprenderá como configurar esses cabeçalhos para proteger aplicações web contra ataques como XSS, clickjacking e vazamento de informações. Inclui exemplos práticos, boas práticas e exercícios com respostas.
Os cabeçalhos HTTP (HTTP headers) são componentes essenciais da comunicação entre clientes e servidores na web. Embora muitas vezes passem despercebidos, eles carregam metadados cruciais sobre a requisição e a resposta, como tipo de conteúdo, codificação, cache e, mais importante para a segurança, políticas de proteção. Configurar corretamente os cabeçalhos de segurança pode mitigar uma série de ataques comuns, como Cross-Site Scripting (XSS), clickjacking, downgrade de protocolo e vazamento de informações de referência.
Nesta aula, vamos explorar quatro cabeçalhos de segurança fundamentais: Content Security Policy (CSP), HTTP Strict Transport Security (HSTS), X-Frame-Options e Referrer-Policy. Cada um deles desempenha um papel específico na defesa da aplicação, e entender como implementá-los é uma habilidade indispensável para qualquer profissional de segurança da informação. Vamos analisar suas diretivas, exemplos de configuração em servidores web comuns e as melhores práticas para evitar armadilhas.
CSP (Content Security Policy)
O Content Security Policy é um cabeçalho HTTP que permite controlar quais recursos o navegador pode carregar para uma determinada página. Ele é uma das defesas mais eficazes contra ataques de Cross-Site Scripting (XSS) e injeção de conteúdo, pois permite que você defina uma lista de fontes confiáveis para scripts, estilos, imagens, fontes e outros tipos de recursos. Quando um site tenta carregar um recurso que não está na política, o navegador bloqueia a requisição e exibe um erro no console.
O CSP é configurado por meio de diretivas que especificam as fontes permitidas. Por exemplo, a diretiva default-src define a política padrão para todos os tipos de recurso, enquanto script-src, style-src, img-src etc. permitem sobrescrever para tipos específicos. Além disso, o CSP pode ser entregue via cabeçalho HTTP ou via meta tag no HTML, mas o cabeçalho é mais seguro e recomendado, pois a meta tag pode ser contornada em alguns casos.
Exemplo de cabeçalho CSP:
Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:;Nesse exemplo, definimos que, por padrão, todos os recursos devem vir do mesmo domínio ('self'). Scripts podem ser carregados do próprio domínio e de https://apis.example.com, estilos podem ser inline (com 'unsafe-inline', embora não seja recomendado) e imagens podem ser do próprio domínio ou em formato data URI. É importante notar que o CSP pode ser testado em modo de relatório usando a diretiva report-uri ou report-to, para monitorar violações sem bloquear recursos.
Para implementar CSP em um servidor web, você pode adicionar o cabeçalho na configuração. Por exemplo, no Apache, você pode usar a diretiva Header set; no Nginx, add_header. Em aplicações Express (Node.js), você pode usar o middleware helmet ou definir manualmente. Sempre comece com uma política restritiva e vá liberando conforme a necessidade, testando em ambiente de homologação.
HSTS (HTTP Strict Transport Security)
O HSTS é um cabeçalho que instrui o navegador a acessar o site somente via HTTPS, forçando conexões seguras e prevenindo ataques de downgrade (como SSL stripping) e interceptação de tráfego. Quando um servidor envia o cabeçalho HSTS, o navegador registra o domínio como "HTTPS-only" por um período definido (max-age) e automaticamente converte qualquer link HTTP para HTTPS antes de fazer a requisição.
A configuração do HSTS envolve dois parâmetros principais: max-age, que define o tempo em segundos que a política deve ser lembrada, e includeSubDomains, que aplica a política a todos os subdomínios. Também existe a opção preload, que permite incluir o domínio na lista de pré-carregamento do navegador, mas para isso é necessário submeter o domínio ao site hstspreload.org.
Exemplo de cabeçalho HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadEsse exemplo define uma política de 1 ano, aplicada a subdomínios e marcada para pré-carregamento. É crucial que o site já esteja totalmente acessível via HTTPS antes de ativar o HSTS, pois uma vez que o navegador recebe o cabeçalho, ele deixará de aceitar conexões HTTP, o que pode causar indisponibilidade se o servidor não estiver configurado corretamente.
Para implementar o HSTS, adicione o cabeçalho em seu servidor web ou aplicação. No Nginx, por exemplo:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;Lembre-se de que o HSTS só é eficaz se o primeiro acesso ao site for via HTTPS, pois se o usuário digitar HTTP, o navegador não terá conhecimento da política. Por isso, é recomendado redirecionar HTTP para HTTPS no servidor, além de considerar o envio do cabeçalho em todas as respostas.
X-Frame-Options
O cabeçalho X-Frame-Options é uma medida de proteção contra clickjacking, um ataque em que uma página maliciosa incorpora a página alvo em um iframe transparente e engana o usuário a clicar em elementos ocultos. Esse cabeçalho informa ao navegador se a página pode ser exibida dentro de um frame (<iframe>, <frame>, <object>).
Existem três valores possíveis: DENY impede qualquer exibição em frame, mesmo se a origem for a mesma; SAMEORIGIN permite que a página seja exibida em frames somente se a origem do frame for a mesma do site; e ALLOW-FROM (obsoleto) permitia especificar uma origem específica, mas não é mais suportado em navegadores modernos. A recomendação atual é usar DENY ou SAMEORIGIN.
Exemplo de cabeçalho:
X-Frame-Options: DENYPara configurar no Apache:
Header always append X-Frame-Options DENYNo Nginx:
add_header X-Frame-Options DENY always;É importante notar que o X-Frame-Options é uma medida legada e que o CSP fornece uma alternativa mais flexível por meio da diretiva frame-ancestors. A diretiva CSP frame-ancestors permite especificar quais origens podem embutir a página em um frame, e é suportada em navegadores modernos. Se você já usa CSP, pode substituir o X-Frame-Options por essa diretiva, mas muitos sites ainda usam ambos para compatibilidade com navegadores antigos.
Referrer-Policy
O cabeçalho Referrer-Policy controla quanta informação de referência (a URL da página de origem) é enviada na requisição quando um usuário clica em um link ou navega para outro site. Isso é relevante para a privacidade, pois a URL de referência pode conter dados sensíveis, como tokens de sessão ou parâmetros de busca. O cabeçalho permite definir políticas que limitam o envio dessa informação.
Existem várias políticas, como no-referrer (não envia nenhuma informação), same-origin (envia somente para requisições do mesmo domínio), strict-origin-when-cross-origin (envia a origem completa para o mesmo domínio, mas apenas a origem para outros domínios, e nada se a conexão for insegura) e unsafe-url (envia a URL completa, inclusive em requisições cross-origin, o que é perigoso). A política recomendada é strict-origin-when-cross-origin, que é o padrão de muitos navegadores modernos.
Exemplo de cabeçalho:
Referrer-Policy: strict-origin-when-cross-originPara configurar no Nginx:
add_header Referrer-Policy "strict-origin-when-cross-origin" always;Além do cabeçalho, a política de referrer também pode ser definida via meta tag <meta name="referrer" content="..."> no HTML, mas o cabeçalho tem precedência. É importante testar o comportamento do referrer em diferentes cenários para garantir que a política não quebre funcionalidades que dependem de informações de referência, como análise de tráfego ou autenticação em sistemas legados.
Boas Práticas e Observações Finais
Ao implementar cabeçalhos de segurança, é fundamental testar exaustivamente antes de aplicar em produção. Use ferramentas como o SecurityHeaders.com para analisar a configuração atual e identificar pontos de melhoria. Além disso, considere a ordem de prioridade e compatibilidade: por exemplo, o CSP é mais poderoso que o X-Frame-Options, mas pode ser mais complexo de configurar. Sempre comece com políticas restritivas e monitore os relatórios de violação para ajustar sem quebrar a funcionalidade.
Outra prática recomendada é usar middleware ou bibliotecas que já implementam essas configurações de forma segura, como o Helmet para Node.js, que define automaticamente vários cabeçalhos de segurança com opções de personalização. No entanto, entenda o que cada cabeçalho faz para ajustar conforme as necessidades da sua aplicação.
Por fim, lembre-se de que os cabeçalhos são apenas uma camada de defesa. Eles não substituem outras medidas, como validação de entrada, sanitização de saída, controle de acesso e monitoramento contínuo. A segurança é um processo contínuo, e a configuração correta desses cabeçalhos é um passo importante para proteger seus usuários e seus dados.
Referências
- MDN - Content Security Policy (CSP)
- MDN - Strict-Transport-Security (HSTS)
- MDN - X-Frame-Options
- MDN - Referrer-Policy
- OWASP Secure Headers Project
- SecurityHeaders.com - Analisador de cabeçalhos
- Helmet - Middleware de segurança para Express
Exercícios
- Explique por que o CSP é eficaz contra ataques de XSS e dê um exemplo de política que bloqueie scripts inline.✓ Resposta: O CSP bloqueia a execução de scripts que não estão na lista de fontes permitidas. Ao definir
script-src 'self', por exemplo, o navegador só executa scripts do próprio domínio, impedindo que scripts injetados (como via XSS) sejam executados. Um exemplo de política que bloqueia scripts inline é:Content-Security-Policy: script-src 'self'. Isso impede o uso de<script>...</script>inline. - Qual é a diferença entre os valores
DENYeSAMEORIGINdo X-Frame-Options? Em que cenário você usaria cada um?✓ Resposta:DENYimpede que a página seja exibida em qualquer frame, mesmo no mesmo domínio.SAMEORIGINpermite que a página seja exibida somente em frames da mesma origem. UseDENYquando a página não precisa ser embutida em nenhum contexto (ex.: páginas de login), eSAMEORIGINquando você permite que a própria aplicação a exiba em iframes (ex.: widgets internos). - Como o HSTS ajuda a prevenir ataques de downgrade? O que acontece se um usuário acessa o site via HTTP pela primeira vez?✓ Resposta: O HSTS força o navegador a usar HTTPS automaticamente após a primeira visita, impedindo que um atacante faça downgrade para HTTP (SSL stripping). Se o usuário acessa via HTTP pela primeira vez, o navegador não conhece a política HSTS, então a conexão inicial pode ser interceptada. Por isso, é recomendado redirecionar HTTP para HTTPS no servidor e, se possível, usar a lista de pré-carregamento (preload).
- Qual é a política Referrer-Policy mais segura e por quê? Dê um exemplo de cabeçalho.✓ Resposta: A política mais segura é
strict-origin-when-cross-origin, pois envia a URL completa para requisições do mesmo domínio, mas apenas a origem para outros domínios, e não envia nada se a conexão for insegura (HTTP). Isso minimiza o vazamento de dados sensíveis. Exemplo:Referrer-Policy: strict-origin-when-cross-origin. - Considere um site que precisa permitir que apenas um domínio parceiro (https://parceiro.com) exiba suas páginas em iframes. Como você configuraria o cabeçalho X-Frame-Options e/ou CSP para atender a essa necessidade?✓ Resposta: O X-Frame-Options não suporta múltiplas origens (o valor ALLOW-FROM é obsoleto). A melhor abordagem é usar CSP com a diretiva
frame-ancestors:Content-Security-Policy: frame-ancestors https://parceiro.com. Isso permite que apenas o domínio parceiro embuta a página. Se precisar de compatibilidade com navegadores antigos, você pode usar X-Frame-Options: ALLOW-FROM (mas não é suportado) ou servir uma página intermediária.