Safari 13+ iframe blokuje pliki cookie CORS

9

Safari całkowicie nie pozwala ustawiać plików cookie w ramkach iframe domen innych niż domena nadrzędna, nagłówki CORS po stronie serwera niech będą przeklęte.

Aby wyjaśnić: użytkownik jest na domainA.com. Ramka iframe dla domainB.com jest otwarta i próbuje uwierzytelnić użytkownika na domainB.com w ramce iframe. Nagłówek Set-Cookie jest zwracany z serwera w ramce iframe domainB.com ze wszystkimi wymaganymi nagłówkami, ale Safari nie odsyła go w kolejnych wywołaniach.

Stare obejście polegało na przesłaniu formularza z ramki iframe i ustawieniu pliku cookie w odpowiedzi. Myślę, że spodobał im się fakt, że użytkownik klikał coś, aby przesłać formularz. Musiałbyś sondować plik cookie, aby zobaczyć, kiedy odpowiedź wróciła, ponieważ przesłane formularze nie mają wywołań zwrotnych, aw przypadku plików cookie HttpOnly nie można, ale hej, zadziałało! Aż nie.

Następnie nowszym obejściem było przekierowanie użytkownika do domeny iframe w nowym oknie / karcie, ustawienie tam losowego pliku cookie i od tego momentu ta subdomena była „zaufana” w ramce iframe. Ponownie wymagało to kliknięcia, aby otworzyć nowe okno / kartę, a nawet pojawiło się wizualne wskazanie otwarcia nowej karty. Dużo bezpieczeństwa, takie standardy.

A teraz, od Safari 13 - Koniec z obejściem. Nigdy więcej bezpiecznego ustawienia plików cookie iframe 🤬

Każdy inny schemat uwierzytelniania nie jest dla nas dobry (np. Nagłówek Auth-X). Musimy użyć bezpiecznego pliku cookie HttpOnly, ponieważ nie chcemy, aby ten token był w jakikolwiek sposób dostępny po stronie klienta javascript.

Żeby było jasne, wszystko działa świetnie w każdej innej przeglądarce.

Odpowiednia Bugzilla WebKit

Czy ktoś ma jakieś sugestie?

Edytować:

Dzięki za link @ tomschmidt, który wydaje się właściwym kierunkiem. Próbowałem użyć interfejsu API Storage Storage firmy Apple, ale niestety, mimo inicjowania logiki logowania za pomocą interfejsu API muszę się poprosić o dostęp:

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();

Jednak pliki cookie otrzymane w odpowiedzi na interfejs API / login nie są wysyłane w kolejnych wywołaniach interfejsu API :(

Tom Teman
źródło
Upewnij się, że uruchamia się to tylko w przypadku jawnej interakcji z ramką iframe, np. Onclick.
tomschmidt
1
Tak, właśnie tak to zrobiłem. Sprawdź problem z bugzillą webkita, z którym się łączyłem, myślę, że to prawdziwy błąd na końcu Safari: /
Tom Teman
Problemem nie jest to, że pliki cookie nie są wysyłane. Jeśli poprosisz o dostęp do pamięci, istniejące pliki cookie są wysyłane na serwer. Problem polega na tym, że żadne nowe pliki cookie nie są w ogóle przechowywane, więc nie można ich wysłać.
Matt Cosentino
@MattCosentino tak, o to mi chodziło - „pliki cookie otrzymane w odpowiedzi / login API” to nowe pliki cookie, które są odsyłane w odpowiedzi nagłówka Set-Cookie do domeny iframe, ale następne wywołanie z domeny iframe nie obejmuje tych pliki cookie w żądaniu. Tak, bardziej poprawne jest stwierdzenie, że przyczyną problemu jest brak zapisywania nowych plików cookie w przeglądarce w tym scenariuszu.
Tom Teman

Odpowiedzi:

0

To obejście nadal działa, dopóki nowe okno przechowuje ciasteczko, które chcesz przechowywać. Element iframe nadal nie może przechowywać własnych plików cookie. W moim przypadku wszystko, czego potrzebowałem, to plik cookie identyfikatora sesji. Otwieram więc małe okienko wyskakujące, gdy użytkownik udziela dostępu do pamięci. Pobiera i przechowuje plik cookie identyfikatora sesji, zamyka i ponownie ładuje ramkę iframe. Ramka iframe ma wówczas dostęp do pliku cookie identyfikatora sesji i wysyła go w kolejnych żądaniach. Myślę, że to tylko tymczasowe, wygląda na to, że w przyszłości usuną dostęp do pamięci z okien wyskakujących. Może naprawią, że iframe nie będzie w stanie przechowywać plików cookie.

Matt Cosentino
źródło
Matt, użyłem podobnego rozwiązania z wyskakującym okienkiem, które działa na komputerze stacjonarnym Safari 13.1, ale testowanie na iPadzie Safari 13.4 nie działa. Czy udało Ci się uzyskać to na iPadzie? Thnx
teamdane