Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Clickjacking: receita do ataque e a defesa que funciona

Headers e tags que controlam o comportamento da sua aplicação — e por que ignorá-las é pedir pra ser hackeado

Nos últimos posts do Instagram eu comecei a falar sobre headers e tags que você pode (e deveria) usar no dia a dia. Aqui, com mais espaço, explico por que isso é tão importante — e como aplicar na prática.

Entendendo o conceito

Quando você faz um CRUD, está guiando o comportamento do usuário — o que ele pode clicar, enviar, editar.

Mas quando falamos de headers e tags como

X-Frame-Options

, Content-Security-Policy ou .htaccess, estamos guiando o comportamento da aplicação: como o browser e o servidor devem se comportar. E isso muda tudo.

Por que isso importa

Esses comportamentos geralmente são definidos no servidor. Muitos devs nunca mexem neles — até o dia em que um atacante usa um iframe pra carregar seu site dentro de outro, rouba credenciais e ainda te faz parecer vulnerável.

Exemplo de golpe visual

Sem o header certo, qualquer um pode colocar seu site dentro de outro:

<iframe src="https://seusite.com" width="100%" height="100%"></iframe>

E aí o “hacker” adiciona um banner falso por cima:

<div style="position:absolute; top:0; left:0; width:100%; height:100%; background:black; color:white; font-size:24px; display:flex; align-items:center; justify-content:center;">
  ESTE SITE FOI HACKEADO 😈
</div>

Mesmo que a URL no navegador continue sendo a sua, a aparência passa a ser controlada por outro site. Resultado: queda de credibilidade e possível roubo de dados do usuário.

Como bloquear isso

Opção 1 — via header no servidor (Node.js + Express)

Exemplo com helmet no Express:

import express from "express";
import helmet from "helmet";

const app = express();

// bloqueia clickjacking e iframes externos
app.use(helmet.frameguard({ action: "deny" }));

// ou permita apenas o mesmo domínio
// app.use(helmet.frameguard({ action: "sameorigin" }));

app.get("/", (req, res) => {
  res.send("Seu site protegido 😎");
});

app.listen(3000);

Opção 2 — via configuração no Nginx

add_header X-Frame-Options "DENY";
# ou
# add_header X-Frame-Options "SAMEORIGIN";

Opção 3 — via .htaccess (Apache / WordPress)

<IfModule mod_headers.c>
  Header always set X-Frame-Options "DENY"
</IfModule>

O poder do .htaccess

O arquivo .htaccess é como um mini firewall de comportamento. Ele define redirecionamentos, bloqueios, reescritas e restrições. Por exemplo, o WordPress redireciona tudo para index.php usando regras de rewrite:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Mas você também pode usar .htaccess para proteger diretórios de uploads:

# Impede listagem de diretórios
Options -Indexes

# Bloqueia acesso direto a arquivos .php dentro de /uploads
<FilesMatch "\.php$">
  Deny from all
</FilesMatch>

Sem essas regras, qualquer pessoa poderia abrir diretamente seus arquivos enviados (ex.: /uploads/foto.png), e às vezes até executar scripts não desejados.

A maioria dos devs ignora isso

Essas pequenas configurações moldam o comportamento da aplicação — e a ausência delas abre portas silenciosas. Gerenciar headers e entender tags como .htaccess, CSP e X-Frame-Options é o que separa quem só desenvolve de quem pensa segurança.

Conclusão

Pequenas linhas. Grande diferença.

Headers como X-Frame-Options e Content-Security-Policy não são luxo — são o mínimo necessário para manter seu site confiável. Se você usa WordPress, Express, Nginx ou Apache, a proteção está a duas linhas de distância.

Quer ver isso funcionando ao vivo? Nos próximos vídeos no YouTube eu vou mostrar como testar se seu site está vulnerável e como aplicar essas regras em produção, passo a passo.

Post anterior

Posts Relacionados

Para desenvolvedores que pensam além do código.

CONTATO

NO YOUTUBE

Copyright © 2025 Café com Java. Todos os direitos reservados.