AldeaCode Logo
Security Clickjacking: X-Frame-Options vs CSP frame-ancestors
Security AldeaCode Architecture

Clickjacking: X-Frame-Options vs CSP frame-ancestors

Cómo prevenir ataques de clickjacking con X-Frame-Options y CSP frame-ancestors. Configuración de cabeceras en Nginx, Apache y Cloudflare.

Que es el clickjacking en realidad

El clickjacking es cuando un atacante carga tu sitio dentro de un iframe invisible en su propia pagina, y coloca un boton llamativo justo donde esta tu boton real. El usuario hace clic en el boton visible que ve. El navegador registra el clic en tu pagina oculta.

Un ejemplo clasico. El atacante monta una pagina de “Gana un iPhone gratis” con un boton “Reclamar Premio”. Encima de ese boton, con opacity: 0, tiene cargada la pantalla de confirmacion de transferencia de tu banco o el checkout de Amazon. El usuario pulsa “Reclamar Premio” y en realidad pulsa “Confirmar Transferencia”.

El truco funciona porque el clic ocurre de verdad sobre tu pagina legitima. El navegador no se equivoca. El usuario si. No hay inyeccion de scripts ni XSS, solo una capa transparente.

Las dos cabeceras que lo arreglan

Detienes el clickjacking diciendole al navegador: nadie puede meter mi pagina en un iframe, salvo que yo lo permita. Dos cabeceras hacen esto.

X-Frame-Options

La antigua. Simple, muy soportada, solo dos valores importan en la practica:

  • DENY: nadie puede embeber tu pagina, ni siquiera tu. Es el valor seguro por defecto.
  • SAMEORIGIN: solo paginas de tu propio dominio pueden embeberla. Util si tu aplicacion usa iframes internos.

Existe un tercer valor, ALLOW-FROM, pero nunca tuvo soporte consistente entre navegadores. Olvidalo.

CSP frame-ancestors

La nueva, parte de Content Security Policy. Hace el mismo trabajo que X-Frame-Options pero te deja autorizar dominios concretos. Esa es la diferencia que importa: con XFO no puedes decir “que partner.com me embeba pero nadie mas”, solo “todos o nadie”. Con frame-ancestors si puedes.

Si las dos cabeceras estan presentes, los navegadores siguen frame-ancestors e ignoran X-Frame-Options. Asi lo dice el estandar CSP Nivel 2.

Dos variantes que conviene conocer

Cursorjacking. El atacante oculta el cursor real con cursor: none y dibuja uno falso desplazado unos pixeles. Tu crees que estas pulsando el elemento seguro sobre el que ves el cursor falso. El clic real cae en otro sitio.

Drag-and-drop clickjacking. El atacante te hace arrastrar algo desde un iframe invisible (un token de sesion mostrado en una pagina oculta, un email) hasta un campo en su pagina. La defensa es la misma: impedir que la pagina se pueda embeber.

Las dos variantes mueren en cuanto tu pagina rechaza cargarse en un iframe.

Una nota sobre el consentimiento

Si un usuario “acepta” cookies o nuevos terminos de privacidad porque le engañaron para pulsar un boton oculto, ese consentimiento no es legalmente valido. Asi que esto no es solo un control de seguridad, es parte de como mantienes limpio tu mecanismo de consentimiento bajo el RGPD.

Para una proteccion en capas, asegurate ademas de que tu sitio fuerza HTTPS con HSTS.

Configurar las cabeceras en Next.js

Las pones globalmente en next.config.js:

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'X-Frame-Options', value: 'DENY' },
          { key: 'Content-Security-Policy', value: "frame-ancestors 'none';" }
        ],
      },
    ]
  },
}

DENY mas frame-ancestors 'none' te cubre tanto en navegadores antiguos como en los modernos.

Cuando si necesitas permitir embebido

Si vendes un widget para integrar, un chat de soporte, un reproductor de video, un panel que tus clientes pegan en su sitio, no puedes usar DENY. Necesitas frame-ancestors con los dominios concretos autorizados:

Content-Security-Policy: frame-ancestors 'self' https://dominio-cliente.com https://otro-cliente.com;

Manten esa lista bajo tu control. Añade un dominio cuando un cliente se da de alta, quitalo cuando se va. No uses comodines.

FAQ

Lo que hacemos

Webs honestas, sin atajos.

Ingeniería real y diseño cuidado. Si te ha gustado el post, hablemos del tuyo.

Hablemos →

Te puede interesar

Ver todos los artículos →