Subskrybuj, aby otrzymywać powiadomienia na temat nowych wpisów:

Integracja Turnstile z zaporą Cloudflare WAF w celu weryfikowania żądań fetch

18.12.2023

8 min czytania
Integrating Turnstile with the Cloudflare WAF to challenge fetch requests

Dwa miesiące temu rozwiązanie Cloudflare Turnstile stało się ogólnodostępne, dzięki czemu właściciele witryn internetowych z całego świata zyskali prosty sposób na odpieranie ataków botów bez konieczności stosowania techniki CAPTCHA. Dzięki Turnstile każdy właściciel witryny internetowej może przy użyciu prostego fragmentu kodu bezproblemowo osadzić w niej weryfikator Cloudflare, który pomaga zadbać o to, aby witrynę mogli przeglądać wyłącznie internauci. Oprócz ochrony frontendu witryny Turnstile umożliwia również administratorom stron internetowych wzmocnienie zabezpieczeń wywołań interfejsu API inicjowanych przez przeglądarkę (AJAX), lecz działających w tle. Te interfejsy API są powszechnie używane przez dynamiczne aplikacje internetowe typu single-page, takie jak te tworzone przy użyciu rozwiązań React, Angular czy Vue.js.

Dzisiaj mamy przyjemność ogłosić, że zintegrowaliśmy Turnstile z zaporą Cloudflare WAF (Web Application Firewall). Oznacza to, że administratorzy stron internetowych mogą dodać fragment kodu Turnstile do swoich witryn, a następnie skonfigurować zaporę Cloudflare WAF do zarządzania takimi żądaniami. Można to w pełni dostosować za pomocą reguł WAF — na przykład zezwolić użytkownikowi uwierzytelnionemu przez Turnstile na interakcję ze wszystkimi punktami końcowymi interfejsu API aplikacji bez napotykania dalszych mechanizmów weryfikacji bądź skonfigurować niektóre kluczowe punkty końcowe (takie jak dotyczące logowania) w taki sposób, aby zawsze zlecały weryfikację.

Weryfikowanie żądań fetch w zaporze Cloudflare WAF

Miliony witryn internetowych chronionych przez zaporę Cloudflare WAF korzystają z naszych mechanizmów weryfikacji (weryfikacja JS, zarządzana i interaktywna), aby powstrzymywać boty, umożliwiając jednocześnie dostęp internautom. W przypadku każdej z tych weryfikacji Cloudflare przechwytuje pasujące żądanie i reaguje poprzez wyświetlenie strony HTML renderowanej przez przeglądarkę, na której użytkownik wykonuje proste zadanie w celu udowodnienia, że jest człowiekiem. Po pomyślnym przejściu weryfikacji użytkownik otrzymuje plik cookie cf_clearance, który informuje Cloudflare o tym fakcie, jak również o typie weryfikacji i terminie jej ukończenia. Plik cookie weryfikacji nie może być współdzielony między użytkownikami i jest ważny tylko przez czas ustawiony przez klienta Cloudflare na pulpicie nawigacyjnym „Security Settings” (Ustawienia zabezpieczeń).

Ten proces przebiega dobrze z wyjątkiem sytuacji, gdy przeglądarka otrzymuje polecenie przeprowadzenia weryfikacji dotyczącej żądania fetch, a wcześniej nie przeszła pomyślnie weryfikacji. W przypadku żądania fetch lub XHR (XML HTTP Request) przeglądarka spodziewa się otrzymać prosty tekst (w formatach JSON lub XML) i nie może wyrenderować kodu HTML niezbędnego do uruchomienia weryfikacji.

Wyobraźmy sobie na przykład właściciela pizzerii, który utworzył formularz zamówień online w bibliotece React ze stroną płatności przesyłającą dane do punktu końcowego interfejsu API przetwarzającego płatności. Gdy użytkownik wyświetla formularz internetowy w celu dodania danych swojej karty kredytowej, może przejść weryfikację zarządzaną, ale gdy przesyła te dane przy użyciu żądania fetch, przeglądarka nie wykona kodu niezbędnego do uruchomienia weryfikacji. Jedynym rozwiązaniem dla właściciela pizzerii, aby poradzić sobie z podejrzanymi (ale potencjalnie prawidłowymi) żądaniami, jest ich blokowanie, co wiąże się z ryzykiem uzyskania wyników fałszywie pozytywnych, które mogłyby spowodować spadek obrotów restauracji.

Właśnie w tym miejscu może okazać się pomocne rozwiązanie Turnstile. Umożliwia ono każdemu w Internecie osadzenie weryfikatora Cloudflare w dowolnym miejscu swojej witryny. Do tej pory wynikiem działania Turnstile był token jednorazowego użytku. Aby umożliwić klientom zlecanie weryfikacji dotyczących takich żądań fetch, Turnstile może teraz generować plik cookie weryfikacji dla domeny, w której jest osadzony taki mechanizm. Klienci mogą przeprowadzać weryfikację w ramach strony HTML przed żądaniem fetch, wstępnie weryfikując odwiedzającego pod kątem interakcji z interfejsem API płatności.

Tryb weryfikacji wstępnej w ramach Turnstile

Wróćmy do naszego przykładu z pizzerią. Trzy główne zalety używania trybu weryfikacji wstępnej do przeprowadzenia integracji Turnstile z zaporą Cloudflare WAF to:

  1. Poprawa doświadczenia użytkownika: osadzona weryfikacja Turnstile może działać w tle, podczas gdy odwiedzający wprowadza swoje dane płatnicze.
  2. Blokowanie większej liczby żądań w infrastrukturze brzegowej: Turnstile generuje teraz plik cookie weryfikacji dla domeny, w której ten mechanizm jest osadzony, dlatego nasz właściciel pizzerii może użyć reguły niestandardowej w celu zlecenia weryfikacji zarządzanej dla każdego żądania skierowanego do interfejsu API płatności. Dzięki temu automatyczne ataki skierowane bezpośrednio do interfejsu API płatności są powstrzymywane przez Cloudflare, zanim dotrą do tego interfejsu.
  3. Zabezpieczenie działań i użytkownika (opcjonalnie): do skorzystania z opcji weryfikacji wstępnej nie są potrzebne żadne zmiany w kodzie środowiska zaplecza. Dalsza integracja Turnstile zwiększy jednak bezpieczeństwo zintegrowanego interfejsu API. Właściciel pizzerii może dostosować swój formularz płatności w taki sposób, aby sprawdzać ważność otrzymanego tokena Turnstile. Dzięki temu każda próba płatności będzie indywidualnie sprawdzana przez Turnstile w celu ochrony punktu końcowego płatności przed przejęciem sesji.

Widżet Turnstile z włączoną opcją weryfikacji wstępnej nadal będzie generował tokeny Turnstile, co zapewnia klientom elastyczność przy podejmowaniu decyzji o tym, czy dany punkt końcowy jest na tyle krytyczny, że wymaga sprawdzenia bezpieczeństwa przy każdym docierającym do niego żądaniu, czy tylko raz na sesję. Pliki cookie weryfikacji generowane przez widżet Turnstile są automatycznie wykorzystywane w strefie Cloudflare, w której osadzony jest ten widżet, bez konieczności konfiguracji. Czas weryfikacji, przez który ważny jest token, nadal zależy od czasu trwania zweryfikowanej sesji określonej dla danej strefy.

Wdrażanie Turnstile z opcją weryfikacji wstępnej

Aby to zobrazować, prześledźmy podstawowe wdrożenie. Przed rozpoczęciem przygotowaliśmy prostą aplikację demonstracyjną, w której emulujemy infrastrukturę frontendu komunikującą się z infrastrukturą zaplecza w punkcie końcowym /your-api.

Aby to osiągnąć, dysponujemy następującym kodem:

<!DOCTYPE html>
<html lang="en">
<head>
   <title>Turnstile Pre-Clearance Demo </title>
</head>
<body>
  <main class="pre-clearance-demo">
    <h2>Pre-clearance Demo</h2>
    <button id="fetchBtn">Fetch Data</button>
    <div id="response"></div>
</main>


<script>
  const button = document.getElementById('fetchBtn');
  const responseDiv = document.getElementById('response');
  button.addEventListener('click', async () => {
  try {
    let result = await fetch('/your-api');
    if (result.ok) {
      let data = await result.json();
      responseDiv.textContent = JSON.stringify(data);
    } else {
      responseDiv.textContent = 'Error fetching data';
    }
  } catch (error) {
    responseDiv.textContent = 'Network error';
  }
});
</script>

Utworzyliśmy przycisk, po kliknięciu którego Cloudflare tworzy żądanie fetch() do punktu końcowego /your-api, wyświetlając wynik w kontenerze odpowiedzi.

Załóżmy teraz, że mamy skonfigurowaną regułę zapory Cloudflare WAF, która chroni punkt końcowy /your-api z wykorzystaniem mechanizmu weryfikacji zarządzanej.

Ze względu na tę regułę działanie aplikacji, którą właśnie napisaliśmy, zakończy się niepowodzeniem z wcześniej opisanego powodu (przeglądarka oczekuje odpowiedzi w formacie JSON, lecz zamiast tego otrzymuje stronę z mechanizmem zabezpieczającym w formacie HTML).

Jeśli sprawdzimy kartę „Network” (Sieć), zauważymy, że żądanie do interfejsu /your-api otrzymało odpowiedź 403.

Po dokładniejszym sprawdzeniu nagłówka Cf-Mitigated widać, że odpowiedź została zweryfikowana przez zaporę Cloudflare, ponieważ odwiedzający nie rozwiązał wcześniej zadania weryfikacyjnego.

Aby rozwiązać ten problem w naszej aplikacji, ustawiamy widżet Turnstile w tryb weryfikacji wstępnej dla klucza witryny Turnstile, którego chcemy użyć.

W naszej aplikacji zastępujemy funkcję fetch() w celu wywołania Turnstile, gdy tylko zostanie otrzymana odpowiedź Cf-Mitigated.

<script>
turnstileLoad = function () {
  // Save a reference to the original fetch function
  const originalFetch = window.fetch;

  // A simple modal to contain Cloudflare Turnstile
  const overlay = document.createElement('div');
  overlay.style.position = 'fixed';
  overlay.style.top = '0';
  overlay.style.left = '0';
  overlay.style.right = '0';
  overlay.style.bottom = '0';
  overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  overlay.style.border = '1px solid grey';
  overlay.style.zIndex = '10000';
  overlay.style.display = 'none';
  overlay.innerHTML =       '<p style="color: white; text-align: center; margin-top: 50vh;">One more step before you proceed...</p><div style=”display: flex; flex-wrap: nowrap; align-items: center; justify-content: center;” id="turnstile_widget"></div>';
  document.body.appendChild(overlay);

  // Override the native fetch function
  window.fetch = async function (...args) {
      let response = await originalFetch(...args);

      // If the original request was challenged...
      if (response.headers.has('cf-mitigated') && response.headers.get('cf-mitigated') === 'challenge') {
          // The request has been challenged...
          overlay.style.display = 'block';

          await new Promise((resolve, reject) => {
              turnstile.render('#turnstile_widget', {
                  'sitekey': ‘YOUR_TURNSTILE_SITEKEY',
                  'error-callback': function (e) {
                      overlay.style.display = 'none';
                      reject(e);
                  },
                  'callback': function (token, preClearanceObtained) {
                      if (preClearanceObtained) {
                          // The visitor successfully solved the challenge on the page. 
                          overlay.style.display = 'none';
                          resolve();
                      } else {
                          reject(new Error('Unable to obtain pre-clearance'));
                      }
                  },
              });
          });

          // Replay the original fetch request, this time it will have the cf_clearance Cookie
          response = await originalFetch(...args);
      }
      return response;
  };
};
</script>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=turnstileLoad" async defer></script>

W powyższym fragmencie kodu dzieje się bardzo wiele. Po pierwsze tworzymy ukryty element nakładki (overlay) i zastępujemy funkcję fetch() przeglądarki. Funkcja fetch() została zmieniona w taki sposób, aby analizować nagłówek Cf-Mitigated pod kątem wyrazu „challenge”. Jeśli weryfikacja zostanie zlecona, początkowy wynik będzie świadczyć o jej niepowodzeniu, natomiast w naszej aplikacji internetowej pojawi się nakładka Turnstile (z włączoną opcją weryfikacji wstępnej). Gdy weryfikacja Turnstile zostanie ukończona, ponowimy poprzednie żądanie (po uzyskaniu przez Turnstile pliku cookie cf_clearance), aby przedostać się przez zaporę Cloudflare WAF.

Nakładka znika po uporaniu się z widżetem Turnstile, a wymagany wynik API jest pomyślnie wyświetlany:

Opcja weryfikacji wstępnej jest dostępna dla wszystkich klientów Cloudflare

Każdy użytkownik Cloudflare z planem Free lub wyższym może bezpłatnie korzystać z rozwiązania Turnstile w trybie zarządzanym dla nieograniczonej liczby żądań. Jeśli jesteś użytkownikiem Cloudflare, który chce poprawić swoje bezpieczeństwo i doświadczenie użytkownika w odniesieniu do swoich kluczowych punktów końcowych interfejsu API, przejdź do naszego pulpitu nawigacyjnego i utwórz widżet Turnstile z opcją weryfikacji wstępnej już dzisiaj.

theNET
Chronimy całe sieci korporacyjne, pomagamy klientom sprawnie tworzyć aplikacje o skali internetowej, przyspieszamy działanie wszelkich witryn i aplikacji internetowych, zapobiegamy atakom DDoS, trzymamy hakerów z daleka oraz możemy pomóc Ci we wdrażaniu modelu Zero Trust.

Odwiedź stronę 1.1.1.1 na dowolnym urządzeniu i zacznij korzystać z naszej bezpłatnej aplikacji, dzięki której Twój Internet będzie szybszy i bezpieczniejszy.

Aby dowiedzieć się więcej o naszej misji budowania lepszego Internetu, przejdź tutaj . Jeśli interesuje Cię zmiana ścieżki kariery, sprawdź nasze wolne stanowiska.
Security (PL)CAPTCHA (PL)Bots (PL)Turnstile (PL)Product News (PL)Developers (PL)Micro-frontends (PL)Polski

Obserwuj nas w serwisie X

Adam Martinetti|@adamemcf
Benedikt Wolters|@worengawins
Miguel de Moura|@miguel_demoura
Cloudflare|@cloudflare

Powiązane wpisy

20 września 2022 13:30

Cloudflare Area 1 — najlepszy system bezpieczeństwa poczty e‑mail jest coraz lepszy

Od dziś na pulpicie nawigacyjnym Cloudflare możesz znaleźć sekcję poświęconą bezpieczeństwu poczty e-mail. To najłatwiejszy sposób, by zapoznać się z zabezpieczeniami poczty elektronicznej Cloudflare Area 1 i zacząć ich używać...