Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Już wkrótce Chrome uniemożliwi ustawianie document.domain
Już całkiem niedługo, bo w wersji Chrome 106 (okolice lipca 2022) Chrome uniemożliwi ustawienie własnej wartości document.domain
w celu osłabienia Same Origin Policy, co może w efekcie pozwolić na dodatkowe uszczelnienie modelu bezpieczeństwa w tej przeglądarce.
Zacznijmy może od wyjaśnienia czym w ogóle jest document.domain
w przeglądarkach i dlaczego jego ustawianie jest problemem bezpieczeństwa. Przede wszystkim document.domain
może być używane jako getter – wówczas po prostu zwraca nazwę domeny, na której zostało wykonane. Na Sekuraku zwróci więc sekurak.pl
. W tym elemencie nie ma problemów bezpieczeństwa.
Co ciekawe jednak, document.domain
ma też setter, który może już wpływać na bezpieczeństwo. Wiemy, że w przeglądarkach mamy mechanizm Same Origin Policy (szeroko opisany na Sekuraku w tekście dot. CORS), który – w największym skrócie – polega na tym, że dwa konteksty przeglądarkowe (czyli np. dwie ramki) mogą widzieć swoje dokumenty (tj. obiekt document
), jeśli mają ten sam origin, tj. protokół, domenę i port. Jeśli więc miałbym jedną ramkę w originie https://test1.sekurak.pl, a drugą w originie https://test2.sekurak.pl, to one nie będą miały bezpośredniego dostępu do dokumentu.
I tutaj „z pomocą” wchodzi setter z document.domain
, który pozwala na zmianę efektywnego originu ramki. A konkretniej – za jego pomocą można ustawić dowolną domenę nadrzędną z obecnej domeny. Jeśli więc oryginalnie document.domain
zwracałoby test1.test2.test3.sekurak.pl
, to możemy setterem ustawić następujące domeny:
test1.test2.test3.sekurak.pl
test2.test3.sekurak.pl
test3.sekurak.pl
sekurak.pl
Jeśli więc wrócimy do wcześniejszego przykładu z test1.sekurak.pl i test2.sekurak.pl, to jeśli obie strony wykonają poniższy kod:
document.domain = "sekurak.pl"
To wówczas obie zyskają dostęp do swoich dokumentów, pomimo tego, że formalnie znajdują się w różnych domenach.
Jak widać ten mechanizm jest de facto złamaniem same origin policy i z jednym powodów, dla których model bezpieczeństwa przeglądarek jest słabszy niż mógłby być. W szczególności mam tutaj na myśli Site Isolation, które zapewnia, że strony w różnych domenach są uruchamiane w różnych procesach. Ale właśnie – jeśli mamy dwie poddomeny jednej domeny, to one w ramach Site Isolation i tak są uruchamiane w jednym procesie. Jeśli więc ktoś znajdzie błąd bezpieczeństwa np. w test1.sekurak.pl, to może wówczas dostać się do danych test2.sekurak.pl, jeśli znajdzie również stosowny exploit na przeglądarkę.
Powodem, dla którego dwie poddomeny muszą być w tym samym procesie jest dosłownie fakt możliwości ustawienia document.domain
i synchronicznej komunikacji pomiędzy nimi. Jeśli więc zamkniemy taką możliwość, wówczas będzie można przechodzić w kierunku Origin Isolation, czyli uruchamiania każdego originu we własnym procesie, co jest bardziej zgodne z ogólnym modelem bezpieczeństwa przeglądarek.
Być może zastanawiacie się, czy ktokolwiek w prawdziwym świecie w ogóle używa tej możliwości ustawiania domeny przez document.domain
. Odpowiedź brzmi: tak. Proponuję spróbować wejść na www.facebook.com
, a potem na developers.facebook.com
i wpisać document.domain
w konsoli. W obu przypadkach dostaniemy po prostu facebook.com
(zamiast pełnej nazwy domeny), co dowodzi, że obie strony skorzystały z settera. Znalezienie XSS-a w jednej z domen pozwoli więc na łatwą eskalację do drugiej domeny.
— Michał Bentkowski
Lubię takie newsy, bo oprócz podania samego faktu: „już wkrótce Chrome uniemożliwi ustawianie document.domain”, to jeszcze opisujecie co to dokładniej jest, co robi i jakie niesie konsekwencje :)
Mam jednak jeszcze pytanie do ekspertów. Po co realnie się to stosuje, tzn. jakie są konkretne przypadki, gdzie stosowanie takiego mechanizmu przez developerów miało sens?
Co się teraz stanie z takimi stronami po wejściu zmiany w życie?
Ustawianie document.domain jest jednym z najstarszych sposobów komunikacji pomiędzy różnymi originami – wspierane jest od czasu Internet Explorera 4 (wydanego w 1997 roku). Zatem odpowiedź na pytanie „gdzie stosowanie takiego mechanizmu przez developerów miało sens?” brzmi: deweloperzy stosowali ten mechanizm, bo po prostu nie mieli alternatywy 😀
W ostatnich 10 latach zostały wprowadzone inne mechanizmy, takie jak postMessage czy CORS, więc setter z document.domain stracił już sens.
> Co się teraz stanie z takimi stronami po wejściu zmiany w życie?
Krótko mówiąc: przestaną działać. Będą musiały zastosować inne mechanizmy komunikacji. W praktyce powinno to dotknąć niewielkiej liczby stron, ale na pewno znajdą się takie, które ucierpią.
W linkowanym artykule źródłowym jest też mowa o możliwości ustawienia specjalnego nagłówka: „Origin-Agent-Cluster: ?0”, który umożliwi ustawianie document.domain, ale spodziewam się, że pewnie w niewiele dalszej przyszłości i ta możliwość zostanie wyłączona.
Autor zapomniał mocno podkreślić, że wprowadzona zmiana dotknie „tylko” stron będących po sslu, gdyż, jak możemy przeczytać np. tutaj: https://web.dev/origin-agent-cluster/
„Finally, note that the Origin-Agent-Cluster header will only work on secure contexts, i.e. on HTTPS pages or on http://localhost. Non-localhost HTTP pages do not support origin-keyed agent clusters.” Więc jeśli masz stronę albo aplikację web po http, to nie musisz się teoretycznie (jeszcze) tą zmianą przejmować.