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

Zapobieganie wyciekom informacji z wykorzystaniem CSRF, XSS i cross-origin.

Wiele aplikacji internetowych jest podatnych na ataki z innych źródeł, takie jak fałszowanie żądań z innych witryn (CSRF), wstawianie skryptów z innych witryn (XSSI), ataki oparte na czasie, wyciek informacji z innych źródeł lub ataki typu spekulacyjne (Spectre).

Nagłówki żądań Pobierz metadane umożliwiają wdrażanie silnego mechanizmu obrony w głębi (zasady izolacji zasobów), aby chronić aplikację przed tymi typowymi atakami między domenami.

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 silnikach przeglądarek.

Obsługa przeglądarek

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Źródło

Tło

Wiele ataków na wiele witryn jest możliwych, ponieważ internet jest domyślnie otwarty, a serwer aplikacji nie może łatwo chronić się przed komunikacją pochodzącą z zewnętrznych aplikacji. Typowym atakiem między domenami jest fałszowanie żądań między domenami (CSRF), w którym atakujący zwodzi użytkownika, aby ten odwiedził witrynę kontrolowaną przez atakującego, a następnie przesyła formularz na serwer, na którym użytkownik jest zalogowany. Ponieważ 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, serwer wykona działanie zażądane przez atakującego w imieniu użytkownika.

Inne ataki między witrynami, takie jak wstawianie skryptu między witrynami (XSSI) czy wycieki informacji między domenami, mają charakter podobny 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. Aplikacje nie mogą łatwo odróżnić żądań zaufanych od nieznanych, więc nie mogą odrzucać złośliwego ruchu w różnych witrynach.

Przedstawiamy Fetch Metadata

Nagłówki żądania pobierania metadanych to nowa funkcja zabezpieczeń platformy internetowej, która pomaga serwerom bronić się przed atakami między domenami. Podając informacje o kontekście żądania HTTP w zestawie nagłówków Sec-Fetch-*, pozwalają serwerowi odpowiadającemu na żądanie zastosować zasady bezpieczeństwa przed przetworzeniem żądania. Dzięki temu deweloperzy mogą decydować, czy zaakceptować czy odrzucić prośbę na podstawie sposobu jej przesłania i kontekstu, w jakim ma być wykorzystana. Umożliwia to odpowiadanie tylko na uzasadnione prośby wysłane przez własną aplikację.

Same-Origin
Żądania pochodzące z witryn obsługiwanych przez Twój własny serwer (z tego samego źródła) będą nadal działać. Żądanie pobierania z https://site.example zasobu https://site.example/foo.json w JavaScript powoduje wysłanie przez przeglądarkę nagłówka żądania HTTP „Sec Fetch-Site: same-origin”.
W wielu witrynach
Serwer może odrzucać złośliwe żądania z wielu witryn z powodu dodatkowego kontekstu w żądaniu HTTP udostępnianego przez nagłówki Sec-Fetch-*. Obraz na stronie https://evil.example, w którego elemencie img atrybut src 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.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Źródło

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 prośba została wysłana 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

Obsługa przeglądarek

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Źródło

Sec-Fetch-Mode wskazuje tryb żądania. Odpowiada ono w przybliżeniu rodzajowi żądania i pozwala odróżnić wczytywanie zasobów od żądań nawigacyjnych. Na przykład wartość navigate wskazuje żądanie nawigacji najwyższego poziomu, a no-cors – żądanie zasobu, np. wczytywania obrazu.

Sec-Fetch-Dest

Obsługa przeglądarek

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

Źródło

Sec-Fetch-Dest podaje miejsce docelowe żądania (np. czy żądanie zostało przesłane przez przeglądarkę z powodu tagu script lub img).

Jak używać funkcji pobierania metadanych, aby chronić się przed atakami między domenami

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 internetowych, 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 z tej samej witryny i inicjowane przez przeglądarkę

Dozwolone będą wszystkie żądania, które nie pochodzą z kontekstu z innej domeny (np. evil.example). Dotyczy to w szczególności żądań, które:

  • pochodzić z Twojej aplikacji (np. żądanie z tego samego pochodzenia, w którym żądania site.example będą zawsze dozwolone);site.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ą 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. 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 mają być ładowane 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 żądania, które są żądaniami między witrynami, a nie żądaniami nawigacyjnymi

Inne żądania między witrynami zostaną odrzucone przez tę zasadę izolacji zasobów, co ochroni Twoją aplikację przed typowymi atakami między witrynami.

Przykład: poniższy kod pokazuje pełną implementację solidnej zasady izolacji zasobów na serwerze lub jako oprogramowania pośredniczącego, aby odrzucać potencjalnie złośliwe żądania zasobów w wielu witrynach, a jednocześnie zezwalać 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ł, np. fragment kodu podany powyżej, aby rejestrować i monitorować działanie witryny oraz upewnić się, że ograniczenia nie wpływają na prawidłowy ruch.
  2. Usuń potencjalne naruszenia, wykluczając z nich legalne punkty końcowe w ramach wielu źródeł.
  3. egzekwowanie 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 w ruchu produkcyjnym.

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