En el mundo del phishing y la ingeniería social, existen técnicas que no requieren explotar vulnerabilidades técnicas del navegador, sino las vulnerabilidades cognitivas del usuario. Uno de estos métodos es el tabnabbing, un ataque silencioso pero efectivo que manipula pestañas inactivas del navegador para engañar al usuario y robar credenciales.

Este artículo revisa qué es tabnabbing, cómo funciona técnicamente, qué riesgos representa hoy, y cómo prevenirlo desde una perspectiva de desarrollo seguro y seguridad ofensiva/defensiva.

¿Qué es el Tabnabbing?

El tabnabbing es una técnica de phishing descrita por primera vez por Aza Raskin (Mozilla) en 2010. Se basa en aprovechar que el usuario mantiene varias pestañas abiertas simultáneamente y confía en que el contenido de las pestañas no cambia cuando no las está viendo.

Funcionamiento básico:

  1. El usuario abre una página aparentemente inocua, que permanece inactiva en segundo plano.
  2. Pasados unos segundos (o detectando inactividad mediante blur, visibilitychange o timers), la página maliciosa reemplaza su contenido por una réplica de una web legítima, como Gmail, Office 365 o su banco.
  3. Cuando el usuario vuelve a esa pestaña, cree estar en un sitio confiable y es inducido a ingresar sus credenciales.

Este ataque es puramente visual y psicológico: no se explota una falla del navegador, sino una suposición equivocada del usuario.

Causas y vectores técnicos

Los vectores del tabnabbing se dividen en dos tipos:

1. Tabnabbing clásico (forward)

  • Mecanismo: el atacante induce a la víctima a visitar un sitio malicioso que simula ser legítimo solo después de estar inactivo.
  • Tecnología: uso de setTimeout, document.hasFocus(), window.onblur, o eventos como visibilitychange para detectar si el usuario dejó de mirar la pestaña.
  • Cambio de contenido: puede hacerse con document.location.href = 'fake-login.html' o sobreescribiendo el DOM directamente.
document.addEventListener("visibilitychange", function() {
  if (document.hidden) {
    setTimeout(() => {
      document.location.href = "https://phishing-site.com/login";
    }, 10000); // tras 10 segundos fuera de foco
  }
});

2. Reverse tabnabbing

  • Mecanismo: una pestaña maliciosa abierta por un sitio legítimo manipula la pestaña de origen a través de window.opener.
  • Condición necesaria: que la página original haya usado target="_blank" sin rel="noopener", lo que deja expuesto window.opener.
window.opener.location = 'https://phishing-site.com/login';

Este vector es más frecuente cuando los sitios permiten contenido dinámico con enlaces inseguros (<a target="_blank">) y sin controles.

Riesgos reales y escenarios de explotación

El tabnabbing puede parecer menos técnico que ataques XSS o CSRF, pero su tasa de éxito en phishing dirigido (spear phishing) es considerable.

Ejemplos reales:

  • Caso APT28 (Fancy Bear): campañas de phishing contra políticos europeos, donde los atacantes abrían pestañas falsas que luego cambiaban para simular interfaces de Gmail, OWA o ProtonMail. El usuario, al volver a la pestaña, caía en un clon y entregaba sus credenciales sin sospechar nada.
  • Campañas bancarias en LATAM y España: clonación de interfaces de banca online donde la pestaña maliciosa reemplaza su contenido tras unos segundos de inactividad.
  • Entornos corporativos: usuarios que acceden a plataformas como Office 365, SAP o Salesforce y mantienen sesiones abiertas, se exponen a perder el control si reintroducen credenciales en un contexto alterado.

Cómo prevenir el tabnabbing (medidas técnicas y de código seguro)

1. Siempre usa rel="noopener" y/o noreferrer en enlaces externos

Esto rompe el vínculo entre la pestaña nueva y la original, evitando el reverse tabnabbing.

<a href="https://sitio-externo.com" target="_blank" rel="noopener noreferrer">
  Ir al sitio
</a>

⚠️ Muchos CMS y frameworks aún no lo hacen por defecto. Validar manualmente.

2. Usa la cabecera Cross-Origin-Opener-Policy

Incluir en las respuestas HTTP:

Cross-Origin-Opener-Policy: same-origin

Esto aísla el contexto de ejecución de la pestaña, impidiendo que scripts externos accedan a window.opener.

3. Evita confiar en target="_blank" en contenido generado por el usuario

Si tu sistema (blog, foro, etc.) permite HTML en comentarios o entradas, filtra o sanitiza los atributos target y obliga el uso de rel="noopener".

4. Controla programáticamente window.open()

const nuevaVentana = window.open(url, "_blank");
if (nuevaVentana) nuevaVentana.opener = null;

Esto corta cualquier posibilidad de que la pestaña hija manipule la principal.

5. Usa Content Security Policy (CSP)

Aunque CSP no bloquea directamente el tabnabbing, ayuda a limitar el alcance de scripts y conexiones externas.

Content-Security-Policy: default-src 'self'; frame-ancestors 'none';

Herramientas y extensiones útiles

  • Lighthouse / SonarQube / ESLint plugins – Detectan automáticamente target="_blank" sin rel="noopener".
  • Extensión “Don’t Touch My Tabs!” (Firefox) – Impide que nuevas pestañas accedan a window.opener.
  • Burp Suite / ZAP – Pueden identificar intentos de reverse tabnabbing en pruebas dinámicas.
  • React ESLint (jsx-no-target-blank) – Lanza warning si olvidas rel="noopener".

Recomendaciones para usuarios y empresas

Aunque las medidas técnicas deben estar implementadas desde el lado del desarrollo, también es importante:

  • Cerrar pestañas no activas con información sensible.
  • Verificar la URL antes de escribir contraseñas, incluso si crees que ya estabas en esa página.
  • Activar extensiones de navegador que previenen la manipulación de pestañas.
  • Educar a los usuarios sobre el comportamiento sospechoso de pestañas que cambian inesperadamente.

Conclusión

El tabnabbing demuestra que los ataques más efectivos no siempre dependen de fallas técnicas complejas, sino de la manipulación del comportamiento humano y lagunas en la lógica de navegación.

Como profesionales de la ciberseguridad, debemos tomar en serio estas amenazas “pasivas” y aplicar sistemáticamente buenas prácticas de desarrollo seguro, incluyendo políticas de cabeceras, sanitización de enlaces y aislamiento de contexto entre pestañas.

Un enlace externo sin rel="noopener" es una puerta trasera visual. Asegúrate de cerrarla.