O clickjacking engana você para clicar num botão de uma página oculta por baixo da que você vê. Veja como ele funciona e como preveni-lo de forma confiável (sem passos de ataque).
O que é alvo
Tudo que seja "um clique, feito, e valioso".
| Alvo provável | Por quê |
|---|---|
| Confirmar uma transferência/compra | Um clique move dinheiro |
| Mudança de configuração (visibilidade, apps conectados) | Prepara um sequestro de conta ou acesso a dados mais tarde |
| OAuth / "Permitir" permissão | Aprova silenciosamente uma vinculação de conta |
| Seguir / curtir / postar em redes sociais | Abusado para disseminação e fazenda de curtidas |
Por que funciona
Os navegadores podem carregar outro site num iframe e empilhá-lo por cima. O atacante torna esse iframe transparente (opacity 0), de modo que o usuário só vê a interface-isca colocada por baixo. Quando o usuário clica no "botão falso", o botão real posicionado logo acima recebe o clique.
Parece-se com o CSRF, mas o CSRF envia uma requisição nos bastidores, enquanto o clickjacking faz o usuário operar a tela real — então tokens CSRF sozinhos não o impedem.
Caso real: a caixa de permissões de um plugin de navegador (2008)
Em outubro de 2008, a Adobe publicou um aviso de segurança (APSA08-08) sobre um problema de clickjacking que afetava vários navegadores. Segundo a imprensa, ao sobrepor de forma invisível a caixa de configurações do Flash Player, um site podia fazer o usuário conceder acesso à câmera e ao microfone sem perceber. A Adobe lançou versões corrigidas do Flash Player e, como solução provisória, orientou os usuários a escolher "sempre negar" no "Settings Manager" (o gerenciador de configurações do Flash Player).
A lição: botões de transferência não são o único alvo. Qualquer tela em que um único clique entrega uma permissão ("Permitir", "Concordo", "Conectar") entra no escopo. A MITRE classifica essa fraqueza como CWE-1021 (Improper Restriction of Rendered UI Layers or Frames).
Defesa: não deixe outros sites embutirem o seu
Defina CSP frame-ancestors (o mais importante)
Adicione Content-Security-Policy: frame-ancestors 'self' (apenas sua própria origem pode colocá-lo em frame). Se ninguém precisa embutir você, 'none' é o mais seguro. Liste domínios apenas para os parceiros que você permite explicitamente.
Adicione X-Frame-Options também (compatível com versões antigas)
Para clientes mais antigos, envie também X-Frame-Options: DENY (ou SAMEORIGIN). Isso cobre tanto navegadores antigos quanto novos.
Adicione uma etapa de confirmação para ações críticas
Proteja transferências e concessões de permissão atrás de reautenticação, de uma caixa de confirmação ou de uma verificação de intenção — mais difícil de conduzir por uma sobreposição silenciosa.
Torne os cookies de sessão SameSite
SameSite=Lax/Strict contém o envio automático entre sites. Não é uma correção completa de clickjacking por si só, mas enfraquece a classe mais ampla de "ação iniciada a partir de outro site".
X-Frame-Options vs CSP frame-ancestors
Os dois cabeçalhos impedem que outros sites embutam o seu, mas diferem nos detalhes.
| X-Frame-Options | CSP frame-ancestors | |
|---|---|---|
| Valores | DENY (bloqueia tudo) / SAMEORIGIN (só a mesma origem) | 'none' / 'self' / uma lista de domínios permitidos |
| Vários sites autorizados a embutir | Não é possível (ALLOW-FROM não funciona nos navegadores modernos) | Possível |
| Configurar via meta tag | Sem efeito | Sem efeito |
| Quando os dois estão presentes | Ignorado pelos navegadores compatíveis | Tem prioridade |
| Papel | Reserva para navegadores antigos | A defesa principal hoje |
Ao enviar os dois, mantenha o mesmo significado: combine frame-ancestors 'none' com DENY, e frame-ancestors 'self' com SAMEORIGIN.
Erros comuns de configuração
- Supor que o
default-srcdo CSP cobre isso. Oframe-ancestorsnão herda dodefault-src. Mesmo comdefault-src 'none', a incorporação continua permitida se você não escreverframe-ancestors - Colocar numa meta tag: o
<meta http-equiv>não tem efeito aqui, então envie como cabeçalho de resposta - Deixar como
Content-Security-Policy-Report-Only: isso só relata violações e não bloqueia a incorporação. Passe para o cabeçalho que aplica a regra depois de confirmar que funciona - Configurar só em algumas páginas: as pessoas verificam a página inicial e esquecem a página de login, as de configurações ou as de erro. Confirme também que uma CDN ou um proxy não está removendo o cabeçalho
Como verificar seu próprio site
Verifique com uma ferramenta de cabeçalhos
Informe a URL do seu site no verificador de cabeçalhos de segurança e veja se X-Frame-Options e o frame-ancestors do CSP são retornados. Verifique não só a página inicial, mas também as páginas de configurações com login e as páginas de transferência ou de concessão de permissões.
Verifique nas ferramentas de desenvolvedor do navegador
Recarregue a página com a aba Network (Rede) aberta e veja os cabeçalhos da resposta HTML. Confira também se o cabeçalho não é enviado duas vezes ou com valores conflitantes.
Configure em um só lugar
Adicioná-lo a todas as respostas em um só lugar (o servidor web, como nginx ou Caddy, o proxy reverso ou o framework) evita tanto lacunas quanto duplicações. Se você vai escrever um CSP novo, o gerador de CSP monta um que inclui o frame-ancestors.
A visão deste site: uma linha de cabeçalho é a correção mais eficaz, então verifique seu próprio site primeiro
A defesa contra clickjacking não é código complexo; são uma ou duas linhas de cabeçalho de resposta que bloqueiam a incorporação. Aplique-as em todo o site no framework ou no proxy reverso (Caddy/nginx) para que nada escape. A falha mais comum é um cabeçalho que você achou que tinha configurado, mas que na verdade está ausente, então, depois de configurar, confirme com os passos acima que ele está de fato sendo retornado.
Fontes (primárias)
- OWASP, "Clickjacking Defense Cheat Sheet" — cheatsheetseries.owasp.org (frame-ancestors, X-Frame-Options, SameSite; ALLOW-FROM não funciona mais; meta tags não têm efeito; limites do frame busting)
- MDN, "CSP: frame-ancestors" — developer.mozilla.org (valores permitidos, sem herança do default-src, sem suporte em meta)
- RFC 7034, "HTTP Header Field X-Frame-Options" — rfc-editor.org
- IPA, "How to Secure Your Web Site, 1.9 Clickjacking" (em japonês) — ipa.go.jp
- Adobe, "Security Advisory for Flash Player (APSA08-08)" (7 de outubro de 2008) — adobe.com
- Computerworld, "Clickjackers could hijack webcams, microphones, Adobe warns" (outubro de 2008) — computerworld.com (o alvo era a caixa de permissão da câmera e do microfone)
- MITRE, "CWE-1021: Improper Restriction of Rendered UI Layers or Frames" — cwe.mitre.org
Leia a seguir
- Glossário: O que é CSRF · O que é XSS
- Guia: Escolhendo cabeçalhos de segurança (o que ainda é necessário e o que ficou obsoleto) (em inglês)
- Verifique: Verificador de cabeçalhos de segurança · Gerador de CSP