Chroń swoje zasoby przed atakami internetowymi za pomocą funkcji Fetch Metadata

Zapobieganie wyciekom informacji CSRF i XSSI oraz wyciekom informacji z innych domen.

Dlaczego warto odizolować swoje zasoby internetowe?

Wiele aplikacji internetowych jest podatnych na ataki z innych domen, takie jak fałszowanie żądań z innych witryn (CSRF), uwzględnianie skryptów między witrynami (XSSI), ataki czasowe, wycieki informacji z innych domen lub ataki spekulacyjne związane z uruchamianiem po stronie 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.

Często zasoby udostępniane przez daną aplikację internetową są ładowane tylko przez nią, a nie przez inne witryny. W takich przypadkach wdrożenie zasady izolacji zasobów opartej na nagłówkach żądań Pobierz metadane nie wymaga większego wysiłku, a jednocześnie chroni aplikację przed atakami z wielu witryn.

Zgodność z przeglądarką

Nagłówki żądań pobierania metadanych są obsługiwane we wszystkich nowoczesnych przeglądarkach.

Obsługa przeglądarek

  • Chrome: 76.
  • Krawędź: 79.
  • Firefox: 90.
  • Safari: 16.4

Źródło

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ącym 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, którego zażądała intruz.

Inne ataki typu cross-site scripting (XSSI) lub wyciek informacji z innych domen są podobne do CSRF i polegają na wczytywaniu zasobów z aplikacji ofiary w dokumencie kontrolowanym przez atakującego oraz wycieku informacji o aplikacjach ofiary. Aplikacje nie są w stanie łatwo odróżniać żądań zaufanych od niezaufanych, dlatego nie mogą odrzucać złośliwego ruchu z różnych witryn.

Przedstawiamy narzędzie Fetch Metadata

Nagłówki żądań pobierania metadanych to nowa funkcja zabezpieczeń platformy internetowej zaprojektowana po to, by ułatwić serwerom ochronę przed atakami z różnych domen. 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. Pozwala to deweloperom decydować o akceptowaniu lub odrzucaniu żądań na podstawie sposobu, w jaki zostało przesłane i kontekstu, w jakim zostanie ono użyte. Pozwala to odpowiadać tylko na uzasadnione żądania przesłane z ich aplikacji.

Takie samo pochodzenie
Żądania pochodzące z witryn obsługiwanych przez Twój serwer (z tej samej domeny) będą nadal działać. Żądanie pobrania z https://site.example dla zasobu https://site.example/foo.json w JavaScripcie powoduje, że przeglądarka wysyła nagłówek żądania HTTP „Sec Fetch-Site: same-origin”.
W różnych witrynach
Serwer może odrzucać szkodliwe żądania między witrynami z powodu dodatkowego kontekstu w żądaniu HTTP zawartym w nagłówkach Sec-Fetch-*. Obraz w witrynie https://evil.example, w którym atrybut src elementu img ma wartość „https://site.example/foo.json” powoduje, że przeglądarka wysyła nagłówek żądania HTTP „Sec-Fetch-Site: cross-site”.

Sec-Fetch-Site

Obsługa przeglądarek

  • Chrome: 76.
  • Krawędź: 79.
  • Firefox: 90.
  • Safari: 16.4

Źródło

Sec-Fetch-Site informuje serwer, która witryna wysłała żądanie. Przeglądarka ustawia tę wartość na jedną z tych wartości:

  • same-origin, jeśli prośba została wysłana przez Twoją własną 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 żądanie zostało wysłane przez inną witrynę (np. evil.example)

Sec-Fetch-Mode

Obsługa przeglądarek

  • Chrome: 76.
  • Krawędź: 79.
  • Firefox: 90.
  • Safari: 16.4

Źródło

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 miejsce docelowe navigate oznacza żądanie nawigacji najwyższego poziomu, a no-cors wskazuje żądania zasobów takie jak wczytanie obrazu.

Sec-Fetch-Dest

Obsługa przeglądarek

  • Chrome: 80.
  • Edge: 80.
  • Firefox: 90.
  • Safari: 16.4

Źródło

Funkcja Sec-Fetch-Dest ujawnia miejsce docelowe żądania (np. jeśli tag script lub img spowodował żądanie zasobu przez przeglądarkę).

Jak korzystać z narzędzia Pobierz metadane do ochrony przed atakami z innych domen

Dodatkowe informacje dostarczane w nagłówkach żądań są dość proste, jednak dodatkowy kontekst pozwala stworzyć solidną logikę zabezpieczeń po stronie serwera, nazywaną też zasadami izolacji zasobów, za pomocą kilku linijek kodu.

Wdrażanie zasady izolacji zasobów

Zasada izolacji zasobów zapobiega wysyłaniu żądań zasobów przez witryny zewnętrzne. Zablokowanie takiego ruchu eliminuje typowe luki w zabezpieczeniach występujące w różnych witrynach, takie jak CSRF, XSSI, ataki czasowe i wyciek informacji z innych domen. Tę zasadę można włączyć dla wszystkich punktów końcowych aplikacji i zezwoli ona na wszystkie żądania zasobów pochodzące z Twojej aplikacji oraz bezpośrednie nawigację (przez żądanie HTTP GET). Punkty końcowe, które powinny być ładowane w kontekście wielu witryn (np. punkty końcowe wczytane przy użyciu CORS), można wyłączyć z tej logiki.

Krok 1. Zezwól na żądania z przeglądarek, które nie wysyłają metadanych pobierania

Ponieważ nie wszystkie przeglądarki obsługują pobieranie metadanych, musisz zezwolić na żądania, które nie ustawiają nagłówków Sec-Fetch-*, sprawdzając obecność elementu 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 przeglądarce

Dozwolone będą wszystkie żądania, które nie pochodzą z kontekstu z innych domen (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 żądania site.example/foo.json);
  • pochodzą z Twoich subdomen.
  • są jawnie spowodowane interakcją użytkownika z klientem użytkownika (np. bezpośrednim nawigacją, kliknięciem zakładki itp.);
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

Krok 3. Zezwól na prostą nawigację najwyższego poziomu i elementy iframe

Aby nadal można było łączyć się z Twoją witryną w innych witrynach, musisz zezwolić na prostą (HTTP GET) nawigację na najwyższym poziomie.

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. Zrezygnuj z punktów końcowych, które mają obsługiwać ruch z różnych 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ć wykluczone według ścieżki lub punktu końcowego. Przykłady takich punktów końcowych:

  • Punkty końcowe, które mają być dostępne z innych domen: jeśli Twoja aplikacja obsługuje punkty końcowe z włączoną obsługą CORS, musisz wyraźnie wyłączyć je z izolacji zasobów, aby umożliwić wysyłanie żądań z innych witryn do tych punktów końcowych.
  • Zasoby publiczne (np. obrazy, style itp.): Wyjątkiem mogą być też wszystkie publiczne i nieuwierzytelnione zasoby, które powinny być ładowane z innych witryn 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

  1. 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.
  2. Napraw potencjalne naruszenia, wykluczając prawidłowe punkty końcowe z innych domen.
  3. Wymuszaj stosowanie zasad, odrzucając żądania niezgodne z zasadami.

Identyfikowanie i naprawianie naruszeń zasad

Zalecamy, aby najpierw przetestować zasadę w sposób swobodny – w tym celu włącz ją w trybie raportowania w kodzie po stronie serwera. Możesz też wdrożyć tę logikę w oprogramowaniu pośredniczącym lub w odwrotnym serwerze proxy, który rejestruje wszelkie naruszenia zasad, które mogą zostać wprowadzone w przypadku ruchu produkcyjnego.

Z naszego doświadczenia związanego z wdrażaniem zasad izolacji zasobów metadanych pobierania w Google większość aplikacji jest domyślnie zgodna z tymi zasadami i rzadko wymaga wykluczenia punktów końcowych, aby umożliwić ruch między witrynami.

Egzekwowanie zasady izolacji zasobów

Gdy upewnisz się, że zasada nie wpływa na prawidłowy ruch produkcyjny, możesz zastosować ograniczenia, które gwarantują, że inne witryny nie będą mogły prosić o Twoje zasoby i będą chronić użytkowników przed atakami z wielu witryn.

Więcej informacji