Safari 13+ iframe bloquea las cookies CORS

9

Safari completamente no le permite configurar cookies en iframes de dominios diferentes al dominio principal, maldita sea las cabeceras CORS del lado del servidor.

Para aclarar: el usuario está en domainA.com. Un iframe para domainB.com está abierto e intenta autenticar al usuario en domainB.com dentro del iframe. El encabezado Set-Cookie se devuelve desde el servidor dentro del iframe de domainB.com, con todos los encabezados necesarios, pero Safari no lo devuelve en llamadas posteriores.

Una solución alternativa anterior era enviar un formulario desde el iframe y establecer la cookie en la respuesta. Supongo que les gustó el hecho de que el usuario estaba haciendo clic en algo para enviar el formulario. Tendría que sondear la cookie para ver cuándo regresó la respuesta, ya que los envíos de formularios no tienen devoluciones de llamada, y en el caso de las cookies HttpOnly no puede, pero ¡hey, funcionó! Hasta que no lo hizo.

Luego, una solución más reciente fue redirigir al usuario al dominio del iframe en una nueva ventana / pestaña, estableciendo una cookie aleatoria allí, y desde ese momento, ese subdominio fue "confiable" dentro del iframe. Nuevamente, se requirió un clic para abrir la nueva ventana / pestaña, e incluso hubo una indicación visual de la apertura de la nueva pestaña. Mucha seguridad, tales estándares.

Y ahora, a partir de Safari 13: no más soluciones alternativas. No más configuración segura de cookies de iframe 🤬

Cualquier otro esquema de autenticación no es bueno para nosotros (por ejemplo, encabezado Auth-X). Necesitamos usar una cookie segura HttpOnly, ya que no queremos que el token sea accesible de ninguna manera por parte del cliente javascript.

Para ser claros, todo funciona muy bien en cualquier otro navegador.

Relevante WebKit Bugzilla

¿Alguien tiene alguna sugerencia?

Editar:

Gracias por el enlace @tomschmidt, esa parece ser la dirección correcta. Intenté usar la API de acceso de almacenamiento de Apple, pero desafortunadamente, aunque me estoy asegurando de solicitar acceso antes de inicializar mi lógica de inicio de sesión con la API:

requestStorageAccess = async() => {
    return new Promise(resolve => {
      //@ts-ignore
      document.requestStorageAccess().then(
        function () {
          console.log('Storage access was granted');
          resolve(true);
        },
        function () {
          console.log('Storage access was denied');
          resolve(false);
        }
      );    
    });
  }


const storageAccessGranted = await requestStorageAccess();
console.log(storageAccessGranted) // prints 'true'
await login();

Aún así, las cookies recibidas en la respuesta de API / login no se envían en llamadas posteriores a la API :(

Tom Teman
fuente
Asegúrese de que esto solo se active en la interacción explícita con el iframe, como onclick.
tomschmidt
1
Sí, así es como lo hice. Echa un vistazo a la cuestión de bugzilla webkit con la que me vinculé, supongo que este es un error real al final de Safari: /
Tom Teman
El problema no es que no se envíen las cookies. Si solicita acceso al almacenamiento, las cookies existentes se envían al servidor. El problema es que las cookies nuevas no se almacenan en absoluto, por lo que no están allí para enviarse.
Matt Cosentino
@MattCosentino, sí, eso es lo que quise decir: "las cookies recibidas en la respuesta de API / login" son cookies nuevas que se envían de vuelta en la respuesta del encabezado Set-Cookie al dominio de iframe, pero la próxima llamada del dominio de iframe no incluye esas cookies en la solicitud Entonces, sí, es más correcto decir que la raíz del problema es que no se almacenan cookies nuevas en el navegador en este escenario.
Tom Teman

Respuestas:

1

Creo que podría haber encontrado la solución: la API de acceso de almacenamiento de Apple: https://webkit.org/blog/8124/introducing-storage-access-api/

tomschmidt
fuente
Hola, gracias por la idea, pero me temo que no funcionó (mira mi edición de respuestas)
Tom Teman
1
También estoy teniendo el mismo problema con Safari 13. ¿Alguna solución?
Niroshana
0

Por lo tanto, la solución aún funciona, siempre y cuando la nueva ventana almacene la cookie que desea almacenar. El iframe aún no puede almacenar sus propias cookies. En mi caso, todo lo que necesitaba era la cookie de identificación de sesión. Entonces, abro una pequeña ventana emergente cuando el usuario concede acceso al almacenamiento. Obtiene y almacena la cookie de ID de sesión, cierra y vuelve a cargar el iframe. El iframe luego tiene acceso a la cookie de identificación de sesión y la envía en solicitudes posteriores. Sin embargo, creo que esto es solo temporal, parece que van a eliminar el acceso al almacenamiento de las ventanas emergentes en algún momento en el futuro. Tal vez arreglen el iframe para que no puedan almacenar cookies para entonces.

Matt Cosentino
fuente
Matt, he usado una solución similar con una ventana emergente, que funciona en el escritorio Safari 13.1, pero las pruebas en un iPad Safari 13.4 no funcionan. ¿Pudiste hacer que esto funcionara en un iPad? Thnx
teamdane