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; preload

Esse 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: DENY

Para configurar no Apache:

Header always append X-Frame-Options DENY

No 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-origin

Para 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

Exercícios

  1. 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.
  2. Qual é a diferença entre os valores DENY e SAMEORIGIN do X-Frame-Options? Em que cenário você usaria cada um?

    ✓ Resposta: DENY impede que a página seja exibida em qualquer frame, mesmo no mesmo domínio. SAMEORIGIN permite que a página seja exibida somente em frames da mesma origem. Use DENY quando a página não precisa ser embutida em nenhum contexto (ex.: páginas de login), e SAMEORIGIN quando você permite que a própria aplicação a exiba em iframes (ex.: widgets internos).
  3. 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).
  4. 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.
  5. 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.