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

Zapobiegaj wyciekom informacji z innych domen oraz żądań CSRF i XSSI.

Dlaczego warto izolować zasoby internetowe?

Wiele aplikacji internetowych jest podatnych na ataki między domenami, takie jak fałszowanie żądań z innych witryn (CSRF), uwzględnianie skryptów między witrynami (XSSI), wycieki informacji z innych domen i ataki spekulacyjne realizowane poza kanałem (Spectre).

Nagłówki żądań Pobierz metadane umożliwiają wdrożenie silnego mechanizmu obrony – zasady izolacji zasobów – w celu ochrony aplikacji przed tymi popularnymi atakami z innych domen.

Często zasoby udostępniane przez daną aplikację internetową są ładowane 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 z innych witryn.

Zgodność z przeglądarką

Nagłówki żądania pobierania metadanych są obsługiwane przez wszystkie nowoczesne wyszukiwarki przeglądarek.

Obsługa przeglądarek

  • 76
  • 79
  • 90
  • 16.4

Źródło

Wprowadzenie

Możliwych jest wiele ataków między witrynami, ponieważ sieć jest domyślnie otwarta, a serwer aplikacji nie jest w stanie w łatwy sposób ochronić się przed komunikacją pochodzącą z aplikacji zewnętrznych. Typowym atakem z innej domeny jest sfałszowanie żądania z innej witryny (CSRF), w którym atakujący wciąga użytkownika na kontrolowane przez siebie witryny, a potem przesyła formularz na serwer, na którym jest zalogowany. Serwer nie jest w stanie określić, czy żądanie pochodzi z innej domeny (z innej witryny), a przeglądarka automatycznie dołącza pliki cookie do żądań z innych stron, dlatego serwer wykona działanie wymagane przez atakującego w imieniu użytkownika.

Inne ataki z innych witryn, takie jak uwzględnianie skryptów między witrynami (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 ujawnianiu informacji o aplikacjach będących ofiarami. Ponieważ aplikacje nie są w stanie łatwo odróżniać żądań zaufanych od niezaufanych, nie mogą odrzucać złośliwego ruchu między witrynami.

Przedstawiamy pobieranie metadanych

Nagłówki żądań pobierania metadanych to nowa funkcja zabezpieczeń platformy internetowej, która ma pomóc serwerom bronić się przed atakami z innych domen. Podając informacje o kontekście żądania HTTP w zestawie nagłówków Sec-Fetch-*, umożliwiają one serwerowi odpowiadającemu zastosowanie zasad zabezpieczeń przed przetworzeniem żądania. Dzięki temu deweloperzy mogą zdecydować, czy zaakceptować lub odrzucić prośbę na podstawie sposobu jej zgłoszenia i kontekstu, w którym zostaną wykorzystane. Dzięki temu będą mogli odpowiadać tylko na uzasadnione prośby zgłoszone przez ich aplikacje.

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 zasobu https://site.example/foo.json z witryny https://site.example w JavaScripcie powoduje, że przeglądarka wysyła nagłówek żądania HTTP „Sec Fetch-Site: same-origin”.
Między witrynami
Złośliwe żądania z innych witryn mogą być odrzucane przez serwer z powodu dodatkowego kontekstu żądania HTTP dostarczonego przez nagłówki Sec-Fetch-*. Obraz w witrynie https://evil.example, który ma ustawiony atrybut src elementu img na „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

  • 76
  • 79
  • 90
  • 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 żądanie zostało przesłane przez Twoją własną aplikację (np. site.example)
  • same-site, jeśli żądanie zostało przesłane przez subdomenę Twojej witryny (np.bar.site.example).
  • none, jeśli żądanie zostało bezpośrednio spowodowane interakcją użytkownika z klientem użytkownika (np. kliknięciem zakładki)
  • cross-site, jeśli prośba została wysłana przez inną witrynę (np. evil.example)

Sec-Fetch-Mode

Obsługa przeglądarek

  • 76
  • 79
  • 90
  • 16.4

Źródło

Sec-Fetch-Mode wskazuje tryb żądania. Odpowiada to typowi żądania i pozwala odróżnić obciążenia zasobów od żądań nawigacji. Na przykład miejsce docelowe navigate oznacza żądanie nawigacji najwyższego poziomu, a no-cors – żądania zasobów, takie jak wczytanie obrazu.

Sec-Fetch-Dest

Obsługa przeglądarek

  • 80
  • 80
  • 90
  • 16.4

Źródło

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

Korzystanie z funkcji Pobieranie metadanych do ochrony przed atakami z innych domen

Dodatkowe informacje podawane przez nagłówki żądań są dość proste, ale dodatkowy kontekst pozwala zbudować po stronie serwera zaawansowaną logikę zabezpieczeń (zwaną też zasadą izolacji zasobów).

Wdrażanie zasady izolacji zasobów

Zasada izolacji zasobów uniemożliwia dostęp do zasobów ze stron zewnętrznych. Blokowanie takiego ruchu eliminuje typowe luki w zabezpieczeniach witryny, takie jak CSRF, XSSI, ataki czasowe i wycieki informacji z innych witryn. Tę zasadę można włączyć dla wszystkich punktów końcowych aplikacji. Zezwala ona na wszystkie żądania dotyczące zasobów pochodzące z Twojej aplikacji oraz do bezpośrednich nawigacji (przy użyciu żądania HTTP GET). Punkty końcowe, które powinny być ładowane w kontekście wielu witryn (np. punkty końcowe ładowane za pomocą CORS), mogą być wyłączone z tej logiki.

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

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ść tagu sec-fetch-site.

if not req['sec-fetch-site']:
  return True  # Allow this request

Krok 2. Zezwól na żądania pochodzące z tej samej witryny i w przeglądarce

Dozwolone będą wszystkie żądania, które nie pochodzą z kontekstu z innych domen (np. evil.example). W szczególności są to żądania, które:

  • źródło z Twojej własnej aplikacji (np. z żądania z tej samej domeny, w przypadku którego site.example prosi o site.example/foo.json zawsze).
  • Pochodzą z Twoich subdomen.
  • są wyraźnie spowodowane interakcją użytkownika z klientem użytkownika (np. bezpośrednią nawigacją lub 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 tworzenie ramek iframe

Aby mieć pewność, że inne witryny nadal będą zawierać linki do Twojej witryny, musisz zezwolić na prostą nawigację najwyższego poziomu (HTTP GET).

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 w różnych witrynach (opcjonalnie)

W niektórych przypadkach aplikacja może udostępniać zasoby przeznaczone do ładowania w różnych witrynach. Te zasoby należy wykluczyć w odniesieniu do poszczególnych ścieżek lub punktów końcowych. Przykłady takich punktów końcowych:

  • Punkty końcowe, które mają być dostępne z innych domen: jeśli aplikacja obsługuje punkty końcowe z włączonym CORS, musisz wyraźnie wyłączyć izolację zasobów w ich przypadku, aby żądania z różnych witryn były nadal możliwe.
  • Zasoby publiczne (np. obrazy, style itp.): Wszystkie publiczne i nieuwierzytelnione zasoby, które powinny być ładowane, pochodzące z innych witryn, również mogą być zwolnione.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

Krok 5. Odrzuć wszystkie inne żądania, które pochodzą z innych witryn, a nie z nawigacji

Wszelkie inne żądania z innych witryn będą odrzucane przez tę zasadę izolacji zasobów, dzięki czemu będą chronić Twoją aplikację przed popularnymi atakami z innych witryn.

Przykład: poniższy kod przedstawia pełną implementację niezawodnej zasady izolacji zasobów na serwerze lub jako oprogramowanie pośredniczące do odrzucania potencjalnie szkodliwych żądań zasobów pochodzących z różnych witryn przy jednoczesnym zezwalaniu na proste żądania nawigacyjne:

# 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ł taki jak fragment kodu powyżej, aby rejestrować i monitorować zachowanie witryny oraz upewnić się, że ograniczenia nie wpływają na żaden prawidłowy ruch.
  2. Napraw potencjalne naruszenia, wykluczając prawidłowe punkty końcowe z innych domen.
  3. Egzekwuj zasady, odrzucając żądania niezgodne z zasadami.

Identyfikowanie i usuwanie naruszeń zasad

Zalecamy przetestowanie zasady bez żadnych konsekwencji, włączając ją najpierw w trybie raportowania w kodzie po stronie serwera. Możesz też zaimplementować tę logikę w oprogramowaniu pośredniczącym lub w odwrotnym serwerze proxy, który rejestruje wszelkie naruszenia zasad, które mogą wystąpić po zastosowaniu zasad do ruchu produkcyjnego.

Z naszych doświadczeń związanych z wdrażaniem w Google zasad izolacji zasobów metadanych wynika, że większość aplikacji jest z nią domyślnie zgodna i rzadko wymaga wykluczenia punktów końcowych w celu umożliwienia ruchu z innych witryn.

Wymuszanie zasady izolacji zasobów

Gdy upewnisz się, że zasada nie ma wpływu na prawidłowy ruch produkcyjny, możesz wprowadzić ograniczenia, gwarantując tym samym, że inne witryny nie będą mogły żądać Twoich zasobów i chronią użytkowników przed atakami w innych witrynach.

Więcej informacji