Zapobieganie wyciekom informacji z wykorzystaniem CSRF, XSS i cross-origin.
Dlaczego warto izolować zasoby internetowe?
Wiele aplikacji internetowych jest podatnych na ataki z innych domen, takie jak fałszywe żądania między witrynami (CSRF), uwzględnianie skryptów między witrynami (XSSI), ataki czasowe, wycieki informacji z innych domen lub ataki spekulacyjne związane z wykonaniem w obrębie kanału (Spectre).
Nagłówki żądań Pobierz metadane umożliwiają wdrożenie silnego mechanizmu obrony (zasady izolacji zasobów), który chroni aplikację przed typowymi atakami z innych domen.
Zasoby udostępnione przez daną aplikację internetową są zwykle wczytywane tylko przez tę aplikację, a nie przez inne witryny. W takich przypadkach wdrożenie zasady izolacji zasobów na podstawie nagłówków żądań pobierania metadanych nie wymaga wiele wysiłku, a jednocześnie chroni aplikację przed atakami na wiele witryn.
Zgodność z przeglądarką
Nagłówki żądań pobierania metadanych są obsługiwane we wszystkich nowoczesnych przeglądarkach.
Tło
Istnieje wiele takich ataków, ponieważ domyślnie internet jest otwarty i serwer aplikacji nie jest w stanie łatwo zabezpieczyć się przed komunikacją pochodzącej z aplikacji zewnętrznych. Typowym atakiem z innych domen jest fałszowanie żądań z innych witryn (CSRF) polega na tym, że osoba przeprowadzająca atak przyciąga użytkownika na kontrolowanej przez siebie stronie, a potem przesyła formularz na serwer, na którym jest on zalogowany. Serwer nie może określić, czy żądanie pochodzi z innej domeny (z innej witryny), a przeglądarka automatycznie dołącza pliki cookie do żądań z innych witryn, więc serwer wykona w imieniu użytkownika działanie, o które prosiła osoba przeprowadzająca atak.
Inne ataki między witrynami, takie jak wstawianie skryptu między witrynami (XSSI) czy wycieki informacji między domenami, są podobne do ataku CSRF i polegają na wczytywaniu zasobów z aplikacji ofiary w dokument kontrolowany przez atakującego oraz na wycieku informacji o aplikacji ofiary. Ponieważ aplikacje nie są w stanie łatwo odróżnić zaufanych żądań od niezaufanych, nie mogą odrzucać złośliwego ruchu z innych witryn.
Przedstawiamy narzędzie Fetch Metadata
Nagłówki żądania pobierania metadanych to nowa funkcja zabezpieczeń platformy internetowej, która pomaga serwerom bronić się przed atakami między domenami. Udostępniając informacje o kontekście żądania HTTP w zestawie nagłówków Sec-Fetch-*
, pozwalają serwerowi odpowiadającemu na zastosowanie zasad bezpieczeństwa przed przetworzeniem żądania. Dzięki temu deweloperzy mogą decydować, czy zaakceptować czy odrzucić prośbę na podstawie sposobu jej wysłania i kontekstu, w jakim ma być wykorzystana. Umożliwia to odpowiadanie tylko na uzasadnione prośby wysłane przez własną aplikację.
Sec-Fetch-Site
Sec-Fetch-Site
informuje serwer, z którego witryny pochodzi żądanie. Przeglądarka ustawia tę wartość na jedną z tych wartości:
same-origin
, jeśli prośba została wysłana przez Twoją aplikację (np.site.example
)same-site
, jeśli żądanie zostało wysłane przez subdomenę Twojej witryny (np.bar.site.example
)none
, jeśli żądanie zostało wyraźnie wywołane przez interakcję użytkownika z klientem użytkownika (np. kliknięcie zakładki);cross-site
, jeśli prośba została wysłana z innej witryny (np.evil.example
)
Sec-Fetch-Mode
Sec-Fetch-Mode
wskazuje tryb żądania. Mniej więcej odpowiada to typowi żądania i umożliwia odróżnienie obciążeń zasobów od żądań nawigacji. Na przykład wartość navigate
wskazuje żądanie nawigacji na najwyższym poziomie, a no-cors
– żądanie zasobu, np. wczytywania obrazu.
Sec-Fetch-Dest
Funkcja Sec-Fetch-Dest
ujawnia miejsce docelowe żądania (np. jeśli tag script
lub img
spowodował żądanie zasobu przez przeglądarkę).
Jak używać funkcji pobierania metadanych, aby chronić się przed atakami z innych źródeł
Dodatkowe informacje zawarte w tych nagłówkach żądań są dość proste, ale dodatkowy kontekst umożliwia tworzenie za pomocą zaledwie kilku linii kodu zaawansowanej logiki zabezpieczeń po stronie serwera, zwanej też zasadą izolacji zasobów.
Wdrażanie zasady izolacji zasobów
Zasady izolacji zasobów uniemożliwiają zewnętrznym witrynom wysyłanie żądań do Twoich zasobów. Blokowanie takiego ruchu pozwala ograniczyć częste luki w zabezpieczeniach w witrynach, takie jak CSRF, XSSI, ataki na czas trwania operacji i wycieki informacji z wielu źródeł. Te zasady można włączyć dla wszystkich punktów końcowych aplikacji. Umożliwi to wszystkie żądania zasobów pochodzące z Twojej aplikacji, a także bezpośrednie przejścia (za pomocą żądania HTTP GET
). Punkty końcowe, które mają być wczytywane w kontekście wielu witryn (np. punkty końcowe wczytywane za pomocą CORS), mogą być wyłączone z działania tej logiki.
Krok 1. Zezwalaj na żądania z przeglądarek, które nie wysyłają żądania pobierania metadanych
Nie wszystkie przeglądarki obsługują pobieranie metadanych, więc musisz zezwolić na żądania, które nie ustawiają nagłówków Sec-Fetch-*
, sprawdzając obecność nagłówka sec-fetch-site
.
if not req['sec-fetch-site']:
return True # Allow this request
Krok 2. Zezwól na żądania zainicjowane w tej samej witrynie i w tej samej przeglądarce
Dozwolone będą wszystkie żądania, które nie pochodzą z kontekstu z innej domeny (np. evil.example
). Są to prośby, które:
- pochodzą z Twojej aplikacji (np. żądanie z tego samego źródła, w przypadku którego
site.example
żąda zawsze żądaniasite.example/foo.json
); - pochodzą z Twoich subdomen.
- są wyraźnie wywoływane przez użytkownika (np. przez bezpośrednie przejście do witryny lub kliknięcie zakładki);
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True # Allow this request
Krok 3. Zezwól na prostą nawigację na najwyższym poziomie i ramowanie
Aby umożliwić linkowanie do Twojej witryny z innych witryn, musisz zezwolić na prostą (HTTP GET
) nawigację najwyższego poziomu.
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
# <object> and <embed> send navigation requests, which we disallow.
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True # Allow this request
Krok 4. Wyłącz punkty końcowe, które mają obsługiwać ruch z wielu witryn (opcjonalnie)
W niektórych przypadkach aplikacja może udostępniać zasoby, które są przeznaczone do wczytywania w różnych witrynach. Te zasoby muszą być wyłączone na poziomie ścieżki lub punktu końcowego. Przykłady takich punktów końcowych:
- Punkty końcowe, do których można uzyskać dostęp w ramach różnych witryn: jeśli Twoja aplikacja obsługuje punkty końcowe z włączoną funkcją
CORS
, musisz je wyraźnie wyłączyć z izolacji zasobów, aby zapewnić możliwość wysyłania żądań do tych punktów końcowych z różnych witryn. - Zasoby publiczne (np. obrazy, style itp.): Wyjątek można też zastosować do wszystkich publicznych zasobów bez uwierzytelniania, które powinny być ładowalne z innych witryn.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
Krok 5. Odrzuć wszystkie inne prośby, które są pochodzące z różnych witryn i nie służą do nawigacji
Zgodnie z tymi zasadami izolacji zasobów wszystkie inne żądania z innych witryn będą odrzucane, co chroni Twoją aplikację przed typowymi atakami z różnych witryn.
Przykład: poniższy kod ilustruje pełną implementację niezawodnych zasad izolacji zasobów na serwerze lub jako oprogramowanie pośredniczące, które odrzuca potencjalnie szkodliwe żądania zasobów z różnych witryn, jednocześnie umożliwiając proste żądania nawigacji:
# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
# Allow requests from browsers which don't send Fetch Metadata
if not req['sec-fetch-site']:
return True
# Allow same-site and browser-initiated requests
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True
# Allow simple top-level navigations except <object> and <embed>
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True
# [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
# Reject all other requests that are cross-site and not navigational
return False
Wdrażanie zasady izolacji zasobów
- Zainstaluj moduł podobny do powyższego fragmentu kodu, aby rejestrować i monitorować zachowanie witryny oraz mieć pewność, że ograniczenia nie wpływają na prawidłowy ruch.
- Usuń potencjalne naruszenia, wykluczając z nich uzasadnione punkty końcowe w wielu domenach.
- egzekwować zasadę przez odrzucanie żądań niezgodnych z zasadami.
Wykrywanie i usuwanie naruszeń zasad
Zalecamy przetestowanie zasad w taki sposób, aby nie powodowały efektów ubocznych, przez ich włączenie w trybie raportowania w kodzie po stronie serwera. Możesz też zastosować tę logikę w oprogramowaniu pośredniczącym lub w usługach odwrotnego serwera proxy, które rejestrują wszelkie naruszenia zasad, które mogą wystąpić po zastosowaniu zasad do ruchu produkcyjnego.
Z naszych doświadczeń z wdrażania zasad izolacji zasobów w Google wynika, że większość aplikacji jest domyślnie zgodna z tymi zasadami i rzadko wymaga wyłączenia punktów końcowych, aby umożliwić ruch między witrynami.
Egzekwowanie zasady izolacji zasobów
Gdy upewnisz się, że Twoje zasady nie wpływają na legalny ruch produkcyjny, możesz wdrożyć ograniczenia, które zagwarantują, że inne witryny nie będą mogły żądać Twoich zasobów, a także ochronią użytkowników przed atakami na wiele witryn.
Więcej informacji
- Specyfikacja nagłówków żądania Fetch Metadata W3C
- Narzędzie do pobierania metadanych
- Prezentacja Google I/O: Zabezpieczanie aplikacji internetowych przy użyciu nowoczesnych funkcji platformy (Prezentacje)