Skip to main content

Ataques de clickjacking: definición y mecanismos de prevención

¿Qué es y cómo se lleva acabo un ataque de clickjacking?

Los ataques de clickjacking (secuestro de clics) son también conocidos como ataques de redirección de la interfaz del usuario y pertenecen a la categoría de ataques de falsificación de información crítica en la interfaz de usuario [0]. Para llevar a cabo un ataque de clickjacking un atacante crea un sitio web malicioso combinando múltiples capas (transparentes y opacas) para poder engañar a los usuarios, quienes creen estar haciendo clic en un botón o enlace de la página que están visualizando, pero en realidad están haciendo clic en un elemento invisible superior [1]. Esta misma técnica también puede ser usada para "secuestrar" las teclas presionadas cuando el usuario escribe dentro de un campo de texto del sitio web malicioso.

Para poder preparar un sitio web con estas características, el atacante necesita lo siguiente:
  1. Poder embeber dentro del sitio web malicioso el contenido de otro sitio o aplicación web (víctima del ataque) a cuyos usuarios pretende engañar. Esto se puede lograr utilizando un elemento frame o iframe de HTML. Por ejemplo, podría embeber el sitio web de un banco.
  2. Ajustar el diseño del sitio web malicioso utilizando hojas de estilo CSS para que el contenido insertado en el punto anterior sea invisible y el usuario no lo visualice. Luego, el atacante agrega una nueva capa visible pero ubicada por detrás del contenido insertado. En esta nueva capa define elementos prolijamente colocados detrás de los elementos del contenido insertado e invisible. Por ejemplo, si la página del banco tiene una sección para realizar transferencias con un botón "Transferir fondos", el atacante podría agregar en una capa visible (pero ubicada por detrás) un botón perfectamente alineado al original del sitio del banco pero con un llamativo mensaje como "Obtener tablet gratis". Al hacer esto, el sitio web malicioso estaría mostrando un botón sobre el cual el usuario podría hacer clic pero en realidad lo estaría haciendo sobre el botón invisible superior que confirma la transferencia de fondos sin que el usuario lo haya notado.

En las próximas dos figuras (créditos Open Web Application Security Project) se puede apreciar gráficamente como sería la superposición entre la capa invisible superior de la web embebida y la capa visible inferior que el usuario finalmente visualiza y con la que intenta interactuar [2].


Figura 1: Descripción del ataque


Figura 2: Sitio web original embebido e invisible

Es importante aclarar dos puntos sobre lo mencionado:
  1. Se utilizó como ejemplo del ataque el sitio web de un banco, pero en la práctica un atacante puede intentar insertar cualquier otro sitio web existente.
  2. Hay varios mecanismos para prevenir este tipo de ataque sobre un sitio web. Para ello, hay que realizar algunos ajustes de configuración y/o programación con el objetivo de que el sitio web no pueda ser embebido desde otro sitio web externo.


¿Cómo puedo saber si mi sitio web es potencialmente vulnerable a un ataque de clickjacking?

La forma más simple es crear un código HTML como el siguiente, pero reemplazando dentro del elemento iframe la URL del sitio que queremos analizar. En este caso el valor que habría que reemplazar por otro es https://www.openminds.com.ar.
<html>
  <head>
    <title>Verificar vulnerabilidad de clickjacking</title>
  </head>
  <body>
    <p>Resultado de la prueba:</p>
    <iframe src="https://www.openminds.com.ar" width="500" height="500">
    </iframe>
  </body>
</html>
Una vez creado el archivo con el código HTML anterior, simplemente hay que abrirlo desde un navegador. Si al hacerlo el sitio web embebido se puede visualizar (como se muestra en la figura 3) es porque es vulnerable a un ataque de clickjacking. En cambio, si el sitio no se visualiza (como se muestra en la figura 4) es porque tiene implementado algún mecanismo de protección contra este tipo de ataque (aunque esto no garantiza que el sitio sea totalmente inmune).


Figura 3: Sitio web vulnerable
Figura 4: Sitio web no vulnerable

Otra forma de verificar esto es utilizar alguna herramienta web. Por ejemplo, se puede usar esta aplicación web de clickjacker.io, que es muy completa e intuitiva [19]. O también esta otra aplicación web de www.lookout.net, que básicamente hace la misma prueba que el código HTML anterior [3].


¿Cómo se puede mitigar esta vulnerabilidad?

Básicamente hay tres formas de defenderse contra un ataque de clickjacking, las cuales son independientes entre sí pero pueden combinarse para obtener mejores resultados: [4]:
  1. Usar las cabeceras HTTP X-Frame-Options [5] y/o Content Security Policy (CSP) [6][7]: Esta es una técnica de protección del lado del servidor web. Ambas cabeceras HTTP permiten especificar si el sitio web puede ser embebido dentro de otro sitio, pero tienen algunas diferencias entre sí que veremos a continuación:

  2. X-Frame-Options: Esta cabecera permite indicarle al navegador si está permitido o no embeber el sitio web a través de los elementos HTML frame, iframe, object o embed [8]. Los valores posibles para esta cabecera son:
    • X-Frame-Options: "DENY"
    • X-Frame-Options: "SAMEORIGIN"
    • X-Frame-Options: "ALLOW-FROM https://www.owasp.org"
    En el primer caso, se asigna el valor DENY que significa que el sitio web no puede ser embebido. En el segundo caso, el valor SAMEORIGIN especifica que sólo puede ser embebido dentro del mismo sitio web. Y en el tercer caso, el valor ALLOW-FROM define que sólo puede ser embebido dentro del sitio web externo www.owasp.org (utilizando sólo el protocolo HTTPS y el puerto por defecto 443).

    Las limitaciones de utilizar esta cabecera son las siguientes [4]:
    • Es necesario incluir la cabecera dentro del código HTML de todas las páginas del sitio web que se busca proteger.
    • No permite definir una lista blanca de dominios o sitios externos que puedan incrustar el sitio web.
    • El valor ALLOW-FROM fue agregado en el año 2012 y todavía no está completamente soportado por algunos navegadores.
    • No acepta múltiples valores (por ejemplo, no se pueden usar SAMEORIGIN y ALLOW-FROM al mismo tiempo).
    • Si bien actualmente está parcialmente soportada por la mayoría de los navegadores, el uso de esta cabecera está deprecado en favor de usar la directiva frame-ancestors de la cabecera HTTP Content Security Policy (CSP).

    Se puede verificar la compatibilidad de esta cabecera HTTP con los diferentes navegadores en los siguientes enlaces: [9][10].

    Content Security Policy (CSP): Esta cabecera permite especificar el valor de la directiva frame-ancestors para indicarle al navegador si está permitido o no embeber el sitio web a través de los elementos HTML frame, iframe, object, embed o applet [11][12]. A continuación se detallan algunos ejemplos del uso de esta directiva:
    • Content-Security-Policy: frame-ancestors 'none';
    • Content-Security-Policy: frame-ancestors 'self';
    • Content-Security-Policy: frame-ancestors 'self' *.openminds.com.ar https://www.owasp.org;
    En el primer caso, se asigna el valor none a la directiva frame-ancestors que significa que el sitio web no puede ser embebido. En el segundo caso, el valor self especifica que sólo puede ser embebido dentro del mismo sitio web. Y en el tercer caso, el valor asignado significa que puede ser embebido dentro del mismo sitio web, dentro de cualquier sitio del dominio openminds.com.ar (utilizando cualquier protocolo) y dentro del sitio www.owasp.org (utilizando sólo el protocolo HTTPS y el puerto por defecto 443).

    Las limitaciones de utilizar esta directiva son las siguientes [4]:
    • Todavía no está totalmente soportada por los principales navegadores.
    • La cabecera X-Frame-Options tiene prioridad.

    Se puede verificar la compatibilidad de esta directiva con los diferentes navegadores en los siguientes enlaces: [13][14].

  3. Establecer el atributo SameSite en las cookies de sesión del sitio web con el valor strict o lax [15][18]. Al hacer esto, las cookies de sesión no son incluidas por el navegador en las solicitudes generadas desde otro sitio web a través de una llamada indirecta, como sucede al utilizar un elemento HTML iframe. Esta es una técnica utilizada principalmente para defenderse de ataques cross-site request forgery (CSRF) pero también se puede utilizar para ataques de clickjacking.

  4. Las limitaciones de utilizar este mecanismo de defensa son las siguientes [4]:
    • Si el sitio web no requiere que el usuario se autentique esta mecanismo no aporta ninguna protección.
    • Si bien este atributo está soportado por todos los navegadores modernos, aún existen muchos usuarios que utilizan navegadores obsoletos que no tienen este soporte.

    Se puede verificar la compatibilidad del atributo SameSite con los diferentes navegadores en el siguiente enlace: [16].

  5. Usar un código framebusting o framebreaking: Es un técnica de protección del lado del cliente. Consiste en incluir un código javascript dentro del sitio web para prohibir que su contenido sea embebido dentro de otro sitio. Esta técnica no es muy efectiva y puede ser evadida de muchas formas, por lo que sólo debería usarse como protección básica si se desea mantener compatibilidad con navegadores obsoletos [17].


Conclusión

En la actualidad no hay un único mecanismo que permita defenderse contra todos los posibles ataques de clickjacking. Debido a esto, la mejor técnica de defensa es combinar las distintas opciones analizadas. Lo ideal sería combinar el uso de las cabeceras HTTP X-Frame-Options y Content Security Policy (CSP). Adicionalmente, si el sitio web a proteger requiere que los usuarios se autentiquen, es recomendable definir el atributo SameSite en las cookies de sesión como vimos anteriormente. Finalmente, si el sitio web necesita mantener compatibilidad con navegadores viejos (que no tienen soporten para las cabeceras HTTP mencionadas ni para el atributo SameSite en las cookies de sesión) es recomendable agregar alguna técnica de framebusting o framebreaking.

En la próxima publicación de nuestro blog vamos a desarrollar un ejemplo práctico de como implementar el uso de las cabeceras HTTP X-Frame-Options y Content Security Policy (CSP) para mitigar la posibilidad de un ataque de clickjacking en un determinado sitio o aplicación web.

Nos leemos pronto!


Referencias:
[0] https://cwe.mitre.org/data/definitions/451.html
[1] https://www.owasp.org/index.php/Clickjacking
[2] https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009)
[3] https://www.lookout.net/test/clickjack.html
[4] https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
[5] https://tools.ietf.org/html/rfc7034
[6] https://w3c.github.io/webappsec-csp/
[7] https://tools.ietf.org/html/rfc7762
[8] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
[9] https://docs.w3cub.com/browser_support_tables/x-frame-options/
[10] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options#Browser_compatibility
[11] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
[12] https://w3c.github.io/webappsec-csp/#frame-ancestors
[13] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors#Browser_compatibility
[14] https://docs.w3cub.com/browser_support_tables/contentsecuritypolicy2/
[15] https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-5.3.7
[16] https://docs.w3cub.com/browser_support_tables/same-site-cookie-attribute/
[17] https://www.netsparker.com/blog/web-security/clickjacking-attacks/
[18] https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/
[19] https://clickjacker.io/