¿Qué ocurre cuando utilizamos target="_blank"?
Supongamos que estamos visitando:
ayuda.svigo.es
Y encontramos un enlace hacia otra página:
<a href="https://otraweb.com/" target="_blank">
Visitar otra web
</a>
Cuando hacemos clic, el navegador abre la página de destino en una nueva pestaña.
Podemos imaginarlo de esta manera:
Pestaña 1
┌─────────────────────┐
│ ayuda.svigo.es │
└──────────┬──────────┘
│
│ abre
▼
Pestaña 2
┌─────────────────────┐
│ otraweb.com │
└─────────────────────┘
Las dos páginas permanecen abiertas al mismo tiempo.
¿Qué es window.opener?
Cuando una página abre otra ventana o pestaña, el navegador puede proporcionar a la nueva página una referencia hacia la página que la abrió.
Esa referencia se encuentra disponible mediante:
window.opener
Por ejemplo, conceptualmente podríamos tener:
ayuda.svigo.es
│
│ abre otra pestaña
▼
otraweb.com
│
└── window.opener
│
▼
ayuda.svigo.es
Esto no significa que la página nueva tenga acceso al servidor de ayuda.svigo.es ni a sus archivos.
El problema está en que puede existir una referencia a la ventana o pestaña original del navegador.
¿Puede una página externa modificar nuestra web?
No puede modificar los archivos de nuestro servidor simplemente por utilizar window.opener.
Es importante distinguir entre el servidor y lo que está mostrando el navegador.
Si nuestra web está almacenada en un servidor, una página externa no obtiene por este mecanismo acceso a los archivos PHP, HTML, bases de datos o configuraciones del servidor.
El problema afecta al navegador del usuario.
Históricamente, una página maliciosa podía intentar utilizar la referencia window.opener para cambiar la ubicación de la ventana que la había abierto.
Por ejemplo, una página podría intentar ejecutar algo parecido a:
window.opener.location = "https://web-maliciosa.com";
De esta manera podría intentar redirigir la pestaña original hacia otra página.
¿Qué problema podría provocar?
Imaginemos que tenemos una página que contiene un enlace aparentemente legítimo:
<a href="https://web-externa.com/" target="_blank">
Más información
</a>
El usuario hace clic y se abre la página externa en una nueva pestaña.
Si esa página fuese maliciosa y pudiera utilizar window.opener, históricamente podría intentar actuar sobre la pestaña que la abrió.
Esto podía utilizarse, por ejemplo, para intentar sustituir la página original por una página falsa.
El riesgo es especialmente interesante cuando el usuario cree que sigue navegando por la web original y la nueva página intenta llevarlo a una página que imita a otra.
¿Qué ocurre si no utilizamos target="_blank"?
Esta es una diferencia importante.
Si tenemos un enlace normal:
<a href="https://otraweb.com/">
Visitar otra web
</a>
la navegación normalmente se realiza en la misma pestaña.
El navegador sustituye la página que estamos viendo:
ayuda.svigo.es
│
▼
otraweb.com
La página anterior ya no permanece abierta como una ventana independiente que la nueva página pueda controlar mediante window.opener.
Por tanto, si posteriormente pulsamos el botón Atrás del navegador, no significa que la página que acabamos de abandonar pueda modificar la página anterior.
¿Y qué ocurre con rel="noopener"?
Para evitar que la nueva página mantenga esa relación con la página que la abrió existe el atributo:
rel="noopener"
Por ejemplo:
<a href="https://otraweb.com/" target="_blank" rel="noopener">
Visitar otra web
</a>
Con noopener, la página abierta no recibe una referencia utilizable mediante window.opener.
De esta forma se elimina ese tipo de relación entre las dos páginas.
¿Sigue siendo necesario utilizar noopener?
Aquí hay una cuestión importante.
Cuando se desarrolló originalmente esta protección, añadir:
rel="noopener"
era una recomendación importante para los enlaces que utilizaban target="_blank".
Sin embargo, los navegadores modernos han cambiado este comportamiento y actualmente aplican de forma automática un comportamiento equivalente a noopener cuando se utiliza target="_blank".
Por este motivo, un enlace como:
<a href="https://otraweb.com/" target="_blank">
Visitar otra web
</a>
ya está protegido frente al problema histórico en los navegadores modernos.
Aun así, escribir explícitamente:
rel="noopener"
sigue siendo válido y puede ser una buena práctica para dejar clara la intención del código, especialmente cuando queremos mantener una política de seguridad explícita o cuando debemos tener en cuenta navegadores antiguos.
¿Es noopener un sistema de seguridad para el servidor?
No.
noopener no protege directamente nuestro servidor, nuestra base de datos ni nuestros archivos.
Su función está relacionada con la comunicación entre ventanas o pestañas del navegador.
Podemos resumirlo así:
| Elemento | Qué protege |
|---|---|
noopener |
La relación entre ventanas o pestañas del navegador |
| Servidor web | Archivos, aplicaciones y recursos del servidor |
| Base de datos | Los datos almacenados en el servidor |
¿Qué deberíamos hacer actualmente?
Si estamos escribiendo HTML y queremos abrir un enlace en una nueva pestaña, podemos utilizar:
<a href="https://www.ejemplo.com/" target="_blank" rel="noopener">
Visitar la web
</a>
Es una forma clara de indicar nuestra intención.
En navegadores modernos, el aislamiento de window.opener ya se aplica automáticamente para target="_blank", pero utilizar noopener explícitamente sigue siendo perfectamente válido.
Una última aclaración: el botón Atrás
Una duda bastante habitual es pensar que una página maliciosa podría modificar la página anterior simplemente porque el usuario pulsa el botón Atrás del navegador.
No funciona de esa manera.
Si navegamos de:
ayuda.svigo.es
↓
otraweb.com
y posteriormente pulsamos Atrás, el navegador vuelve a mostrar la página anterior utilizando su historial de navegación.
La página externa que acabamos de abandonar no obtiene por ello permiso para modificar la página anterior.
El problema histórico de window.opener estaba relacionado con otro escenario: una página abierta en una nueva pestaña que mantenía una referencia hacia la página que la había abierto.
Conclusión
target="_blank" permite abrir un enlace en una nueva pestaña.
Históricamente, esto podía crear una relación entre la nueva página y la página que la había abierto mediante window.opener.
El atributo:
rel="noopener"
impide esa relación y evita que la página abierta pueda utilizar window.opener para acceder a la ventana que la abrió.
Actualmente los navegadores modernos ya aplican esta protección automáticamente para los enlaces con target="_blank", por lo que el problema tiene mucha menos relevancia que hace unos años.
Aun así, conocer cómo funciona window.opener es útil para entender la seguridad de los enlaces y para escribir código HTML de forma consciente.
Importante: noopener no tiene como objetivo mejorar el posicionamiento SEO. Es una medida relacionada con la seguridad y el comportamiento de las ventanas del navegador.
