Safari 13+ iframe bloque les cookies CORS

9

Safari à plat ne vous permet pas de définir des cookies dans des iframes de domaines différents du domaine parent, les en-têtes CORS côté serveur soient damnés.

Pour clarifier: l'utilisateur est sur domainA.com. Un iframe pour domainB.com est ouvert et tente d'authentifier l'utilisateur sur domainB.com à l'intérieur de l'iframe. L'en-tête Set-Cookie est renvoyé par le serveur à l'intérieur de l'iframe domainB.com, avec tous les en-têtes requis, mais Safari ne le renvoie pas lors des appels suivants.

Une ancienne solution de contournement consistait à envoyer un formulaire à partir de l'iframe et à définir le cookie dans la réponse. Je suppose qu'ils ont aimé le fait que l'utilisateur clique sur quelque chose pour soumettre le formulaire. Vous devriez interroger le cookie pour voir quand la réponse est revenue, car le formulaire ne contient aucun rappel, et dans le cas des cookies HttpOnly, vous ne pouviez pas, mais bon, cela a fonctionné! Jusqu'à ce que ce ne soit pas le cas.

Ensuite, une solution de contournement plus récente redirigeait l'utilisateur vers le domaine iframe dans une nouvelle fenêtre / un nouvel onglet, y installant un cookie aléatoire, et à partir de ce moment, ce sous-domaine était "approuvé" à l'intérieur de l'iframe. Encore une fois, il a fallu un clic pour ouvrir la nouvelle fenêtre / nouvel onglet, et il y avait même une indication visuelle de l'ouverture du nouvel onglet. Beaucoup de sécurité, de telles normes.

Et maintenant, à partir de Safari 13 - Plus de solution. Aucun paramètre de cookie iframe plus sécurisé 🤬

Tout autre schéma d'authentification n'est pas bon pour nous (par exemple l'en-tête Auth-X). Nous devons utiliser un cookie sécurisé HttpOnly, car nous ne voulons pas que ce jeton soit accessible de quelque manière que ce soit par le côté client javascript.

Pour être clair, tout fonctionne très bien sur n'importe quel autre navigateur.

WebKit Bugzilla pertinent

Est-ce que quelqu'un a des suggestions?

Éditer:

Merci pour le lien @tomschmidt, cela semble être la bonne direction. J'ai essayé d'utiliser l'API d'accès au stockage d'Apple, mais malheureusement, bien que je m'assure de demander l'accès avant d'initialiser ma logique de connexion avec l'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();

Pourtant, les cookies reçus sur la réponse / login API ne sont pas envoyés lors des appels suivants à l'API :(

Tom Teman
la source
Assurez-vous que cela n'est déclenché que lors d'une interaction explicite avec l'iframe, comme onclick.
tomschmidt
1
Ouais, c'est comme ça que je l'ai fait. Découvrez le problème de bugkilla du webkit auquel j'ai lié, je suppose que c'est un bug réel à la fin de Safari: /
Tom Teman
Le problème n'est pas que les cookies ne sont pas envoyés. Si vous demandez un accès au stockage, les cookies existants sont envoyés au serveur. Le problème est que les nouveaux cookies ne sont pas stockés du tout, ils ne sont donc pas là pour être envoyés.
Matt Cosentino
@MattCosentino oui, c'est ce que je voulais dire - "les cookies reçus sur la réponse / login API" sont de nouveaux cookies qui sont renvoyés dans la réponse d'en-tête Set-Cookie au domaine iframe, mais le prochain appel du domaine iframe ne comprend pas ceux cookies dans la demande. Alors oui, il est plus correct de dire que la racine du problème est qu'aucun nouveau cookie n'est stocké dans le navigateur dans ce scénario.
Tom Teman

Réponses:

1

Je pense que j'ai peut-être trouvé la solution: l'API d'accès au stockage d'Apple: https://webkit.org/blog/8124/introducing-storage-access-api/

tomschmidt
la source
Hé, merci pour l'idée, mais je crains que cela n'ait pas fait l'affaire (consultez ma réponse modifier)
Tom Teman
1
J'ai également le même problème avec Safari 13. Une solution de contournement?
Niroshana
0

Ainsi, la solution de contournement fonctionne toujours un peu, tant que la nouvelle fenêtre stocke le cookie que vous souhaitez stocker. L'iframe ne peut toujours pas stocker ses propres cookies. Dans mon cas, tout ce dont j'avais besoin était le cookie d'identification de session. Donc, j'ouvre une petite fenêtre contextuelle lorsque l'utilisateur accorde l'accès au stockage. Il obtient et stocke le cookie d'ID de session, ferme et recharge l'iframe. L'iframe a alors accès au cookie d'ID de session et l'envoie dans les requêtes suivantes. Je pense que ce n'est que temporaire, il semble qu'ils vont supprimer l'accès au stockage des fenêtres contextuelles à l'avenir. Peut-être qu'ils corrigeront l'iframe ne pouvant pas stocker les cookies d'ici là.

Matt Cosentino
la source
Matt, j'ai utilisé une solution similaire avec une fenêtre contextuelle, qui fonctionne sur le bureau Safari 13.1, mais en testant sur un iPad Safari 13.4, cela ne fonctionne pas. Avez-vous pu faire fonctionner cela sur un iPad? Thnx
teamdane