Recientemente he tenido un proyecto de página web que funcionaba perfectamente cuando se hacía directamente en el navegador, pero cuando intentaba meter el contenido en un iframe para integrarlo con otra parte de la web no conseguía que se mantuviese la sesión. Esto, además de un malestar insidioso, me produjo curiosidad, ya que hacía mucho que no utilizaba iframes y, parece, que la forma en que tratan estos ha cambiado un poco con las últimas versiones de los navegadores.
Aunque podría deciros la solución ya mismo, vamos a darle un poco de dramatismo y os voy a explicar porqué un iframe no se comporta exactamente igual que la navegación en el browser y como eso hace que puedas perder la sesión.
¿Cual es la diferencia?
Un iframe no es más que un marco que se inserta dentro de una página web y cuyo contenido es cargado de una dirección distinta de internet, eso tiene la ventaja de que puedes enriquecer la página con contenido que no tienes que generar desde tu servidor, o que puedes reaprovechar cosas que ya tienes hechas en otros sistemas y el usuario podría no notar que esa parte del contenido proviene de otro sitio. Precisamente por este detalle (que los usuarios no son conscientes de donde viene ese contenido) se abren posibilidades de ataques Cross Site Request Forgery (CSRF), que significa que podrían recuperar una cookie de un dominio distinto desde una iframe, por ejemplo, y secuestrar la sesión original o cualquier credencial de usuario que viaje con las cookies.
Precisamente para evitar estos ataques en 2016 se estableció un atributo para las cookies (SameSite) que prevenía que se pudieran enviar cookies a dominios distintos de los que se estaba navegando (de lo que veíamos en la barra de navegación). Los posibles valores de estos atributos son:
None
: las cookies se mandan a todos los dominios.Strict
: Las cookies solo se enviaran al dominio que coincide con el de la barra de direccionesLax
: Las cookies se enviarán al contexto principal y con las navegaciones de primer nivel.
Antes de tener este atributo todas las cookies eran tratadas como si fuese None y los iframes podían recibir las cookies (entre ellas las de sesión), pero a partir de que los navegadores adoptaron el atributo, la cosa cambió y ahora si la cookie no declaraba el SameSite se consideraba que este era del tipo Lax y esto hace que la navegación dentro de un iframe que está en otro dominio no pase las cookies.
¿Cómo arreglarlo?
Básicamente lo único que tienes que hacer (esto ya depende mucho del framework que tengas) es declarar las cookies con este encabezado:
Set-Cookie: session=your_session; SameSite=None; Secure
Con esto declaramos que las cookies podrán ser retransmitidas, pero además que solo se transmitirán a dominios seguros (con https). Esta pequeña modificación hace que se pueda navegar ya dentro del iframe, pero, ¡cuidado! te añade un potencial problema de seguridad CSRF.