Clickjacking



I. Descripción

Clickjacking es un ataque basado en la interfaz de usuario, donde un atacante engaña a la víctima para que realice clics (u otras interacciones) en un elemento de un sitio web legítimo oculto o transparente, mientras la víctima cree estar interactuando con contenido legítimo en un sitio web señuelo. Técnicamente, se logra mediante el uso de:

  • iframing: incrustar la página objetivo dentro de un <iframe> en el sitio del atacante.

  • CSS: manipular la posición, opacidad y superposición de ese iframe, de manera que la víctima no lo vea o piense que está haciendo clic en otro elemento.

1. Diferencia con CSRF

A diferencia de un ataque CSRF, donde las acciones se realizan sin interacción del usuario (se falsifica una petición completa), el clickjacking requiere que la víctima sí haga clic o interactúe con un elemento, aunque sea engañosamente.

Ejemplos de acciones comprometidas

  • Eliminar la cuenta o cambiar ajustes importantes.

  • Transferir fondos a una cuenta de un atacante.

  • Ejecutar un ataque XSS (cuando el click gatilla un script malicioso).

  • Comprar productos en un e-commerce sin que el usuario se percate.

En todos los casos, el servidor ve las acciones como completamente legítimas, ya que provienen de la sesión válida de la víctima y ocurren dentro de la misma aplicación, solo que en un iframe en otro sitio.


2. PoC

1. ¿Cómo funciona el Clickjacking?

  • El atacante incrusta la aplicación objetivo (p.ej., vulnerable-website.com) en un iframe en su propio sitio (el sitio señuelo).

  • Superpone elementos visuales o botones “de engaño” (un falso “Gana un premio”, “Haz clic aquí”, etc.) por encima del iframe transparentado o con opacidad mínima.

  • Cuando la víctima hace clic en la parte visible del sitio señuelo, en realidad está pulsando un botón o link en el sitio legítimo, ejecutando la acción que el atacante desea (eliminar una cuenta, transferir dinero, cambiar correo, etc.).

2. Construyendo un Clickjacking

  • Según PortSwigger, la forma más sencilla de montar un ataque de clickjacking es:

<html>
  <head>
    <style>
      #target_website {
        position: relative;
        width: 300px; 
        height: 200px;
        opacity: 0.01;
        z-index: 2;
      }
      #decoy_website {
        position: absolute;
        z-index: 1;
      }
    </style>
  </head>
  <body>
    <div id="decoy_website">
      <h1>¡Haz clic para ganar un premio!</h1>
    </div>
    <iframe id="target_website"
            src="https://vulnerable-website.com/critical-action">
    </iframe>
  </body>
</html>
  • El <iframe> con src="vulnerable-website.com" está posicionado y casi transparente (opacity:0.01).

  • El usuario ve únicamente el contenido señuelo (¡Haz clic para ganar!), pero su clic impacta en lo que hay debajo (el botón real en vulnerable-website.com).

a. Automatización con Clickbandit

Herramientas como Clickbandit permiten crear rápidamente un PoC de clickjacking sin escribir HTML/CSS a mano.

3. Formularios prellenados

Algunos sitios permiten rellenar un formulario vía parámetros GET. El atacante puede:

  • Modificar la URL para inyectar valores predeterminados en campos (por ejemplo, email=attacker@malicious.com).

  • Incrustar esa URL en un iframe, superponer el botón “Enviar” con un señuelo, y engañar al usuario para que envíe el formulario con datos maliciosos.

4. Frame busters y scripts de ruptura

Muchos sitios implementan frame busters en JavaScript para impedir ser incrustados:

if (window.top !== window.self) {
  window.top.location = window.self.location;
}

Sin embargo, PortSwigger indica que esto puede eludirse de varias maneras neutralizando el framebuster

  • Usando el atributo sandbox="allow-forms" (o similar) en el <iframe>, que restringe el script de la página incrustada impidiendo detectar que está dentro de un frame.

  • Desactivando JavaScript a través de extensiones o proxies que eliminan el script de ruptura.

  • Navegadores o configuraciones que ignoran el script.

<iframe sandbox="allow-forms"
        src="https://victim-website.com">
</iframe>

5. Combinación con DOM XSS

El clickjacking también puede usarse como “portador” de otro ataque, por ejemplo un DOM XSS. Si el sitio objetivo tiene un botón que, al hacer clic, evalúa un payload XSS en el contexto del usuario, el atacante enmarca esa URL con el payload incluido, y obliga a la víctima a dar clic.


6. Clickjacking en varios pasos

Es posible requerir que la víctima realice múltiples clics secuenciales (agregar al carrito, luego confirmar compra, luego cerrar un diálogo, etc.). Para ello se:

  • Incrustan varias capas o se manipulan las posiciones en el iframe tras el primer clic (por ejemplo, con dos <div> señuelo: “Haz clic primero”, “Haz clic después”)

  • Cada clic está alineado con un botón diferente del sitio legítimo (p.ej. “Eliminar cuenta” y luego “Confirmar”)

7. Ejemplos y payloads comunes

  • Eliminar cuenta:

    <iframe src="http://vulnerable.com/delete-account" 
            style="opacity:0;">
    </iframe>
  • Transferir fondos:

    <iframe src="http://vulnerable.com/transfer?amount=1000&to=attacker" 
            style="opacity:0;">
    </iframe>
  • Cambio de configuración:

    <iframe src="http://vulnerable.com/change-settings?email=attacker@xyz.com"
            style="opacity:0;">
    </iframe>

III. Impacto

  • Acciones críticas sin el conocimiento del usuario como eliminación de cuentas, compras no deseadas, cambios de correo o credenciales.

  • Facilitar ataques más graves como son el encadenamiento con DOM XSS para inyectar scripts maliciosos.

  • permiten realizar múltiples pasos en sitios de comercio electrónico o banca en línea.

  • Pérdida de confidencialidad y control sobre el sitio ya que el usuario cree estar viendo contenido legítimo, pero sus clics repercuten en una acción maliciosa.

  • Daño a la reputación de la aplicación vulnerable y posible responsabilidad legal si no se implementan protecciones.


IV. Mitigación

  • Habilitar header X-Frame-Options con el fin de restringir el framing de la aplicación:

    • X-Frame-Options: deny: Impide cualquier iframe

    • X-Frame-Options: sameorigin: Permite iframes solo desde el mismo origen

    • X-Frame-Options: allow-from https://normal-website.com: Permite iframes únicamente desde un dominio específico

IMPORTANTE

La sentencia allow-from no es soportada por todos los navegadores

  • Mantener habilitada la política CSP

  • Agregar directiva frame-ancestors en header Content-Security-Policy:

    • Content-Security-Policy: frame-ancestors 'none';: Equivale a deny

    • Content-Security-Policy: frame-ancestors 'self';: Equivale a sameorigin

    • Content-Security-Policy: frame-ancestors https://normal-website.com;: Permite iframes solo desde el dominio especificado

  • Habilitar token CSRF o validaciones adicionales para operaciones sensibles