Todos os guias
Severidade MédiaCabeçalhos de segurança

Clickjacking e X-Frame-Options: mantenha suas páginas fora de iframes

O clickjacking engana os usuários para clicarem em controles ocultos da sua página, carregando-a dentro de um iframe transparente em um site controlado pelo atacante. X-Frame-Options — ou a moderna diretiva frame-ancestors da CSP — diz aos navegadores para se recusarem a incorporar a sua página, fechando o ataque por completo.

O que é

Um ataque de clickjacking funciona enquadrando o seu site dentro de um iframe invisível ou translúcido na página do atacante. A vítima vê um conteúdo-isca e clica no que parece um botão inofensivo; o iframe oculto captura o clique real na sua página — uma transferência bancária, uma mudança de configuração, uma autorização de OAuth — sem que o usuário perceba.

X-Frame-Options é um cabeçalho de resposta HTTP com dois valores úteis: DENY (recusa o enquadramento por qualquer um) e SAMEORIGIN (só permite o enquadramento por páginas da sua própria origem). A diretiva frame-ancestors da CSP faz o mesmo trabalho com controle mais fino — você pode listar origens confiáveis específicas — e ela substitui X-Frame-Options nos navegadores compatíveis com CSP.

Por que importa

Qualquer página com uma ação relevante — configurações de conta, confirmação de pagamento, preferências de e-mail ou um botão de administração — é um alvo de clickjacking. Um usuário logado que cai em uma página maliciosa pode ser enganado a realizar ações reais que nunca pretendeu, sem nenhum sinal visível de que algo está errado.

Adicionar X-Frame-Options não custa nada e é suportado por todo navegador moderno. Omiti-lo em páginas que executam ações sensíveis é, pura e simplesmente, um erro de configuração, não uma funcionalidade faltando.

Como corrigir

Adicione X-Frame-Options globalmente no Next.js

Defina o cabeçalho no next.config.js para que ele se aplique a todas as rotas. DENY é o padrão seguro para apps que não precisam ser incorporados.

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: "/:path*",
        headers: [{ key: "X-Frame-Options", value: "DENY" }],
      },
    ];
  },
};
Adicione frame-ancestors à sua CSP

A diretiva frame-ancestors da CSP substitui X-Frame-Options nos navegadores modernos e te dá controle por origem. Adicione-a ao cabeçalho Content-Security-Policy que você já define.

// extend your existing CSP string
const csp = [
  // ... your other directives ...
  "frame-ancestors 'none'",
].join("; ");
Use SAMEORIGIN se você incorpora dentro do seu próprio domínio

Se você incorpora páginas legitimamente no seu próprio site — um iframe de pré-visualização ou um widget incorporado na mesma origem — use X-Frame-Options: SAMEORIGIN em vez de DENY, ou frame-ancestors 'self'.

Configure o nginx

Se você serve as respostas através de um proxy nginx, adicione o cabeçalho no seu bloco server.

add_header X-Frame-Options "DENY" always;

FAQ

X-Frame-Options ou frame-ancestors da CSP — qual devo usar?

Use os dois. X-Frame-Options cobre os navegadores antigos; frame-ancestors na CSP te dá granularidade por origem e é o padrão moderno. Eles convivem sem problema — os navegadores compatíveis com CSP usam frame-ancestors e ignoram X-Frame-Options.

O DENY quebra a incorporação dos meus próprios widgets ou painéis de análise?

Sim — o DENY bloqueia todo enquadramento, inclusive da sua própria origem. Se você precisa incorporar uma página específica em um iframe no seu próprio domínio, use SAMEORIGIN ou frame-ancestors 'self'. Afrouxe apenas nas páginas que realmente precisam ser incorporadas.

Que severidade o AppSafe reporta para um X-Frame-Options ausente?

Média. Não é, por si só, um vetor imediato de roubo de dados, mas qualquer página que execute ações de conta corre um risco real de clickjacking sem ele.

Seu app está afetado?

O AppSafe verifica isso e dezenas de outros problemas em um único escaneamento grátis.

Escanear meu app grátis