Chrome wyłączy modyfikację document.domain, aby złagodzić zasadę dotyczącą tej samej domeny

Jeśli Twoja witryna korzysta z ustawienia document.domain, musisz podjąć odpowiednie działania.

Nowości

  • 30 maja 2023 r.: ogłosiliśmy, że wycofanie settera document.domain wejdzie w życie w Chrome 115.
  • 7 kwietnia 2023 r.: przed wdrożeniem tej zmiany w Chrome 112 wykryliśmy problem. Funkcja document.domain, która ma zostać usunięta domyślnie, jest obecnie zawieszona, a nowy etap dostawy nie został jeszcze określony. Wróć do tego posta na blogu lub zasubskrybuj kanał blink-devten wątek.
  • 20 stycznia 2023 r.: zaktualizowany harmonogram – setter document.domain zostanie domyślnie usunięty od wersji Chrome 112. Dodano też wzmiankę o zasadach przedsiębiorstwa, aby kontrolować działanie document.domain.
  • 25 lipca 2022 r.: zaktualizowano harmonogram – setter document.domain zostanie usunięty domyślnie od wersji Chrome 109.
  • 4 lutego 2022 r.: aktualizacja dotycząca nowego harmonogramu. Od wersji Chrome 100 będziemy wyświetlać ostrzeżenie w panelu Problemy, a od wersji 106 domyślnie usuniemy setter document.domain.

document.domain została zaprojektowana do pobierania lub ustawiania nazwy hosta źródła.

W Chrome strony nie będą mogły ustawiać document.domain. Aby komunikować się między domenami, musisz użyć alternatywnych metod, takich jak postMessage() lub interfejs Channel Messaging API. Chcemy wprowadzić tę zmianę w Chrome 112, ale zależy to od odpowiedzi na intencję wprowadzenia.

Jeśli Twoja witryna wymaga prawidłowego działania mechanizmu document.domain, aby móc korzystać z ustępstwa od zasady źródeł, musi wysyłać nagłówek Origin-Agent-Cluster: ?0, podobnie jak wszystkie inne dokumenty, które wymagają takiego zachowania (pamiętaj, że document.domain nie ma żadnego wpływu, jeśli ustawia go tylko jeden dokument).

Dlaczego warto uczynić element document.domain niezmiennym?

Wiele witryn ma ustawioną wartość document.domain, aby umożliwić komunikację między stronami w tej samej witrynie, ale w różnych domenach.

Oto jak go używać:

Załóżmy, że strona https://parent.example.com zawiera element iframe ze strony https://video.example.com. Te strony mają tę samą domenę eTLD + 1 (example.com) z różnymi subdomenami. Gdy document.domain obu stron jest ustawiony na 'example.com', przeglądarka traktuje obie te domeny tak, jakby pochodziły z tej samej domeny.

Ustaw wartość document.domain dla https://parent.example.com:

// Confirm the current origin of "parent.example.com"
console.log(document.domain);

// Set the document.domain
document.domain = 'example.com';
console.log(document.domain);

Ustaw wartość document.domain dla https://video.example.com:

// Confirm the current origin of "video.example.com"
console.log(document.domain);

// Set the document.domain
document.domain = 'example.com';
console.log(document.domain);

Możesz teraz utworzyć manipulację DOM w różnych domenach na stronie https://parent.example.com w przypadku https://video.example.com.

Witryny ustawiają document.domain, aby ułatwić komunikację między dokumentami w tej samej witrynie. Ta zmiana łagodzi zasady dotyczące tego samego źródła, dzięki czemu strona nadrzędna może uzyskać dostęp do dokumentu iframe i przechodzić po drzewie DOM, a także odwrotnie.

Jest to wygodna technika, ale wiąże się z ryzykiem dla bezpieczeństwa.

Problemy z bezpieczeństwem w document.domain

Problemy z bezpieczeństwem document.domain spowodowały zmianę specyfikacji, która ostrzega użytkowników przed używaniem tego typu urządzeń. Obecna dyskusja z innymi dostawcami przeglądarek zmierza w tym samym kierunku.

Jeśli na przykład 2 strony mają ustawioną wartość document.domain, mogą udawać, że mają ten sam element źródła. Jest to szczególnie ważne, gdy te strony korzystają z usługi współdzielonego hostingu z różnymi subdomenami. Ustawienie document.domain umożliwia dostęp do wszystkich innych witryn hostowanych przez tę samą usługę, co ułatwia atakującym dostęp do Twoich witryn. Jest to możliwe, ponieważ document.domain ignoruje część domeny zawierającą numer portu.

Więcej informacji o znaczeniu ustawień document.domain dla zabezpieczeń znajdziesz na stronie „Document.domain” w MDN.

W Chrome 112 zespół Chrome planuje ustawić document.domain jako niezmienną.

Skąd mam wiedzieć, czy moja witryna jest dotknięta?

Jeśli ta zmiana ma wpływ na Twoją witrynę, Chrome wyświetli ostrzeżenie w panelu Problemy w Narzędziach dla programistów. Zwróć uwagę na żółtą flagę w prawym górnym rogu.

Gdy zmienisz wartość document.domain, w panelu Problemy pojawi się ostrzeżenie.
Gdy zmienisz wartość document.domain, w panelu Problemy pojawi się ostrzeżenie.

Jeśli masz skonfigurowany punkt końcowy raportowania, otrzymasz też raporty o wycofaniu. Dowiedz się więcej o korzystaniu z interfejsu API do raportowania w połączeniu z dotychczasowymi usługami do zbierania raportów lub przez opracowanie własnego rozwiązania wewnętrznego.

Aby znaleźć wszystkie interfejsy API, które mają zostać usunięte z Chrome, możesz przeprowadzić audyt interfejsów API wycofanych z Lighthouse.

Alternatywna komunikacja między domenami

Obecnie masz 3 opcje wymiany document.domain w swojej witrynie.

Użyj interfejsu postMessage() lub Channel Messaging API

W większości przypadków interfejs postMessage() lub Channel Messaging API może zastąpić interfejs document.domain.

W tym przykładzie:

  1. https://parent.example.com wysyła https://video.example.com w ramach iframe, aby manipulować DOM, wysyłając wiadomość przez postMessage().
  2. https://video.example.com modyfikuje DOM, gdy tylko otrzyma wiadomość, i powiadamia element nadrzędny o powrocie do niego.
  3. https://parent.example.com potwierdza, że wszystko się udało.

https://parent.example.com:

// Send a message to https://video.example.com
iframe.postMessage('Request DOM manipulation', 'https://video.example.com');

// Receive messages
iframe.addEventListener('message', (event) => {
  // Reject all messages except ones from https://video.example.com
  if (event.origin !== 'https://video.example.com') return;

  // Filter success messages
  if (event.data === 'succeeded') {
    // DOM manipulation is succeeded
  }
});

https://video.example.com:

// Receive messages
window.addEventListener('message', (event) => {
  // Reject all messages except ones from https://parent.example.com
  if (event.origin !== 'https://parent.example.com') return;

  // Do a DOM manipulation on https://video.example.com.

  // Send a success message to https://parent.example.com
  event.source.postMessage('succeeded', event.origin);
});

Wypróbuj, jak to działa. Jeśli masz konkretne wymagania, które nie działają z postMessage() lub interfejsem Channel Messaging API, daj nam znać na Twitterze za pomocą konta @ChromiumDev lub zadaj pytanie na Stack Overflow z tagiem document.domain.

W ostateczności wyślij nagłówek Origin-Agent-Cluster: ?0

Jeśli masz ważne powody, aby nadal używać ustawienia document.domain, możesz wysłać nagłówek odpowiedzi Origin-Agent-Cluster: ?0 wraz z dokumentem docelowym.

Origin-Agent-Cluster: ?0

Nagłówek Origin-Agent-Cluster informuje przeglądarkę, czy dokument powinien być obsługiwany przez grupę agentów ze źródłem jako kluczem. Więcej informacji o Origin-Agent-Cluster znajdziesz w artykule Prośba o izolację skuteczności za pomocą nagłówka Origin-Agent-Cluster.

Gdy wysyłasz ten nagłówek, dokument może nadal ustawiać wartość document.domain, nawet gdy domyślnie jest ona niezmienna.

Konfigurowanie OriginAgentClusterDefaultEnabled do obsługi zasad korporacyjnych

Opcjonalnie administrator może skonfigurować zasadę OriginAgentClusterDefaultEnabled na false, aby umożliwić domyślne stosowanie document.domain w przypadku instancji Chrome w całej organizacji. Więcej informacji znajdziesz w artykule Lista zasad Chrome Enterprise i zarządzanie nimi | Dokumentacja.

Zgodność z przeglądarką

Zasoby

Podziękowania

Zdjęcie autorstwa Braydon AndersonUnsplash