Aprenda / Segurança web

IntermediárioAula 13 de 1617 min0% da trilha

Cabeçalhos HTTP que blindam sua aplicação

Um punhado de headers de resposta faz o navegador da vítima recusar sozinho boa parte dos ataques mais comuns.

Além de tudo que já foi visto (sanitização, hashing, autorização), existe uma camada extra de defesa que vive inteiramente em headers de resposta — instruções que o servidor manda pro navegador seguir, mesmo que alguma outra defesa falhe antes. Nenhum desses headers substitui as defesas anteriores; eles são justamente a "defesa em profundidade" da lição 1 em forma concreta.

Content-Security-Policy — uma segunda camada contra XSS

A lição 7 mostrou como escapar/sanitizar input evita XSS. Content-Security-Policy (CSP) é uma camada adicional: mesmo que um script malicioso consiga, de algum jeito, se infiltrar na página, o CSP diz ao navegador exatamente de quais origens ele tem permissão de carregar e executar script — um script injetado inline, ou vindo de um domínio não listado, é simplesmente recusado pelo navegador antes de rodar.

header CSP restringindo origem de script
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.exemplo.com

default-src 'self' diz "por padrão, só carregue recursos do próprio domínio"; script-src refina isso especificamente pra scripts, permitindo também um CDN confiável. Um script injetado via XSS, hospedado em atacante.com ou inserido inline sem estar na lista permitida, é bloqueado pelo navegador mesmo que tenha passado por toda sanitização do servidor — é literalmente uma segunda chance depois que a primeira falhou.

X-Frame-Options — evitando clickjacking

Clickjacking é um ataque que não injeta código nenhum — ele engana visualmente. O atacante embute o site legítimo (ex.: banco.com/transferir) dentro de um <iframe> invisível (opacidade zero), posicionado exatamente sobre um botão inofensivo de uma página que ele controla ("Clique aqui para ganhar um prêmio"). A vítima acha que está clicando no botão do prêmio, mas na verdade está clicando no botão real de banco.com, escondido embaixo — e, como o iframe carrega a página legítima de verdade, o cookie de sessão da vítima vai junto normalmente.

header impedindo que o site seja embutido em iframe
X-Frame-Options: DENY
// ou, permitindo iframe só do próprio domínio:
X-Frame-Options: SAMEORIGIN

Com DENY, o navegador simplesmente recusa renderizar a página dentro de qualquer <iframe>, não importa de qual site — o truque do iframe invisível deixa de funcionar porque não existe mais nada pra sobrepor.

X-Content-Type-Options — impedindo o navegador de "adivinhar" o tipo de arquivo

Por padrão, alguns navegadores tentam "adivinhar" o tipo real de um arquivo servido, mesmo que o servidor já tenha declarado um Content-Type — um comportamento chamado MIME sniffing. Isso vira risco quando um arquivo pensado como inofensivo (uma imagem enviada por um usuário, por exemplo) é reinterpretado pelo navegador como HTML/JavaScript executável, abrindo mais uma via de XSS indireta.

desativando esse comportamento
X-Content-Type-Options: nosniff

O antes e depois, lado a lado

Resposta sem headers de proteção
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 4821
Resposta com headers de proteção
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 4821
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff

Exercício

Um site de banco não tem X-Frame-Options configurado. Um atacante cria uma página com um <iframe> invisível carregando banco.com/transferir?valor=5000&destino=atacante, posicionado sobre um botão falso de "Baixar cupom". Explique por que isso funciona mesmo que banco.com tenha proteção CSRF via token — e o que o header resolveria.

Quiz rápido

Por que o CSP é descrito como uma 'segunda camada' contra XSS, e não a defesa principal?
O que torna o clickjacking diferente de CSRF, mesmo os dois envolvendo enganar a vítima?