Ochrona CSRF i zapobieganie manipulacji formularzami

Poznaj ataki CSRF i dowiedz się, jak tokeny formularzy chronią je przed przejęciem. Sprawdź, dlaczego każdy formularz potrzebuje ochrony CSRF.

Wersja robocza

Wyobraź sobie, że ktoś nakłania odwiedzającego do kliknięcia linku, gdy ten jest zalogowany na swoim koncie bankowym. Link prowadzi do ukrytego formularza, który bez wiedzy odwiedzającego wysyła do banku polecenie przelewu. Bank widzi prawidłowe żądanie od uwierzytelnionego użytkownika i je realizuje. Atakujący przesunął pieniądze z konta ofiary, nigdy nie poznając jej hasła.

Na tym polega CSRF (Cross-Site Request Forgery): atak, w którym napastnik nakłania ofiarę do nieświadomego wysłania formularza lub żądania do innej strony, na której ofiara jest już zalogowana.

Czego się dowiesz: czym są ataki CSRF i jak działają, dlaczego są tak groźne nawet przy innych zabezpieczeniach, jak tokeny CSRF im zapobiegają i jak wdrożyć ochronę w swoich formularzach.

Czym jest CSRF?

CSRF (wymawiane „si-serf”) to skrót od Cross-Site Request Forgery. To atak, który wykorzystuje fakt, że gdy jesteś zalogowany na stronie, Twoja przeglądarka automatycznie ufa Twojej sesji i dołącza ją do każdego żądania wysyłanego do tej strony, nawet jeśli żądanie pochodzi z innej witryny.

Atak polega na nakłonieniu zalogowanego odwiedzającego do nieświadomego wysłania formularza do strony, na której ma konto. Atakujący nie widzi hasła ofiary. Nie musi. Wystarczy, że ofiara jest już zalogowana, a następnie zostanie nakłoniona do wysłania żądania (na przykład ukrytego formularza), które robi to, czego chce napastnik.

CSRF różni się od innych ataków tym, że nie wymaga kradzieży danych logowania ani łamania szyfrowania. Wykorzystuje zaufanie ofiary do strony. Ofiara jest już uwierzytelniona, więc strona ufa żądaniom, które wyglądają, jakby pochodziły od niej.

Jak działają ataki CSRF

Atak CSRF przebiega w trzech krokach.

Krok 1: Ofiara jest zalogowana na Twojej stronie

Ktoś odwiedza Twoją stronę i loguje się na swoje konto. Jego przeglądarka ma teraz aktywne ciasteczko sesji, które potwierdza uwierzytelnienie. Sesja pozostaje aktywna, dopóki ta osoba korzysta ze strony.

Krok 2: Atakujący nakłania ją do odwiedzenia złośliwej strony

Będąc nadal zalogowana na Twojej stronie, ofiara odwiedza stronę kontrolowaną przez atakującego (może to być link z mediów społecznościowych, myląca reklama albo witryna, która wygląda wiarygodnie). Na tej stronie jest ukryty kod, który wysyła formularz z powrotem do Twojej strony.

Krok 3: Formularz wysyła się automatycznie z sesją ofiary

Ukryty formularz wysyła dane do Twojej strony. Ponieważ ofiara jest już zalogowana, jej przeglądarka automatycznie dołącza ciasteczko sesji do żądania. Z perspektywy Twojego formularza to prawidłowe żądanie uwierzytelnionego użytkownika. Formularz przetwarza je tak, jakby ofiara wysłała je celowo.

Atakujący zrobił teraz coś na Twojej stronie z użyciem konta ofiary, bez jej wiedzy. Mógł zmienić hasło, przelać pieniądze, zaktualizować profil albo wysłać dane.

Dlaczego atak działa mimo innych zabezpieczeń

Ataki CSRF omijają kilka popularnych zabezpieczeń:

HTTPS nie zatrzymuje CSRF. Dane są szyfrowane w trakcie przesyłania, ale atakujący nie musi ich przechwytywać. Po prostu wysyła żądanie z przeglądarki ofiary, której ta przeglądarka już ufa.

Ochrona hasłem nie zatrzymuje CSRF. Atakujący nigdy nie potrzebuje hasła ofiary. Wykorzystuje tylko to, że ofiara jest już zalogowana.

Silny system logowania nie zatrzymuje CSRF. Nawet jeśli uwierzytelnianie jest doskonałe, atak działa, gdy ofiara jest zalogowana.

Dlatego ochrona CSRF to osobna warstwa. Inne zabezpieczenia jej nie zastępują. Formularze trzeba zaprojektować tak, by odpierały ataki CSRF.

Tokeny CSRF: jak zatrzymują atak

Rozwiązaniem jest token CSRF. To unikalny, nieprzewidywalny ciąg znaków, który Twój serwer generuje dla każdego formularza. Działa to tak:

Serwer tworzy unikalny token dla każdego odwiedzającego

Gdy ktoś ładuje stronę z formularzem, serwer generuje losowy token i wiąże go z sesją tego użytkownika. Token za każdym razem jest inny i jest unikalny dla danego użytkownika.

Token jest osadzony w formularzu

Token jest dołączony jako ukryte pole w formularzu HTML. Gdy odwiedzający wysyła formularz, token podróżuje razem z nim.

Serwer weryfikuje token przed przetworzeniem zgłoszenia

Po wysłaniu formularza serwer sprawdza, czy token w zgłoszeniu zgadza się z tokenem wygenerowanym dla sesji tego użytkownika. Jeśli tak, formularz zostaje przetworzony. Jeśli nie (albo gdy tokenu brak), formularz zostaje odrzucony.

Ukryty formularz atakującego nie może zawierać prawidłowego tokenu, bo tokeny są nieprzewidywalne i unikalne dla każdej sesji. Atakujący z innej domeny nie może zobaczyć ani odgadnąć tokenu. Jego atak się nie udaje. Ukryty formularz się wysyła, ale serwer go odrzuca, bo token się nie zgadza.

Jak token CSRF wygląda w praktyce

W HTML formularz chroniony przed CSRF wygląda tak:

<form method="POST" action="/submit-form"> <input type="hidden" name="csrf_token" value="a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"> <input type="email" name="email" placeholder="Your email"> <button type="submit">Submit</button> </form>

Pole `csrf_token` jest ukryte. Odwiedzający go nie widzi, ale wysyła się razem z danymi formularza. Serwer sprawdza je, zanim przetworzy adres e-mail lub inne dane.

Ochrona CSRF dla różnych rodzajów formularzy

Tradycyjne formularze HTML

Standardowe formularze HTML (te, które wysyłają dane metodą POST do serwera) wymagają tokenów CSRF. Dotyczy to formularzy kontaktowych, logowania, resetowania hasła i każdego formularza, który zmienia dane na serwerze.

Formularze AJAX i JavaScript

Formularze wysyłane przez JavaScript do punktu końcowego API też potrzebują ochrony CSRF. Token można osadzić w samym formularzu, zapisać w ciasteczku albo pobrać ze znacznika meta przed wysłaniem żądania.

Bezstanowe żądania API

Jeśli Twoje API używa uwierzytelniania opartego na tokenach (np. JWT), ochrona CSRF działa inaczej. Przeglądarka nie dołącza automatycznie tokenu JWT tak jak ciasteczka sesji, więc klasyczny CSRF jest mniejszym zagrożeniem. Mimo to dobra praktyka nadal zaleca dodatkowy token CSRF dla większego bezpieczeństwa.

Inne zabezpieczenia działające razem z tokenami CSRF

Tokeny CSRF to główna obrona, ale najlepiej działają razem z innymi praktykami bezpieczeństwa.

Ciasteczka SameSite

Ustawiając ciasteczko sesji, możesz dodać atrybut `SameSite`, który mówi przeglądarce, by nie dołączała ciasteczka do żądań pochodzących z innej domeny. Dzięki temu ukryty formularz atakującego w ogóle nie może użyć sesji ofiary.

Sprawdzanie nagłówka Referer

Serwer może sprawdzić nagłówek Referer, by zobaczyć, skąd przyszło żądanie. Jeśli wysłany formularz twierdzi, że pochodzi z Twojej domeny, ale Referer wskazuje inną, to prawdopodobnie atak. (Nagłówki Referer można jednak podrobić, więc to nie jest pełna obrona.)

Wzorzec podwójnego ciasteczka (double-submit)

W tym podejściu token CSRF jest zapisany zarówno w ciasteczku, jak i w polu formularza. Serwer sprawdza, czy się zgadzają, zanim przetworzy dane. To rzadsze rozwiązanie niż tradycyjne tokeny, ale dobrze sprawdza się w aplikacjach bezstanowych.

Jak wdrożyć ochronę CSRF

Szczegóły zależą od używanych technologii, ale wzorzec jest ten sam:

  1. Generuj unikalny token dla każdej sesji. Gdy użytkownik zaczyna sesję lub ładuje stronę z formularzem, Twój backend generuje nowy token.
  2. Przechowuj token po stronie serwera. Zapisz go w powiązaniu z sesją tego użytkownika.
  3. Dołącz token do formularza. Dodaj go jako ukryte pole w HTML albo jako znacznik meta, który odczyta JavaScript.
  4. Waliduj przy wysłaniu. Zanim przetworzysz jakiekolwiek dane formularza, sprawdź, czy wysłany token zgadza się z tokenem zapisanym dla tej sesji.
  5. Generuj token ponownie po wrażliwych działaniach. Gdy użytkownik zmienia hasło lub robi coś krytycznego, wygeneruj nowy token.

Większość nowoczesnych frameworków automatycznie generuje i waliduje tokeny CSRF. Jeśli używasz frameworka, ochrona CSRF jest zwykle domyślnie włączona. Uważaj tylko, by przypadkiem jej nie wyłączyć.

Częste błędy, które zostawiają formularze podatne na atak

Wyłączanie ochrony CSRF dla wygody. Niektórzy programiści wyłączają kontrole CSRF, by ułatwić testowanie API albo uprościć kod. Nie rób tego. To tworzy realną lukę.

Jeden statyczny token dla wszystkich użytkowników. Token musi być unikalny dla sesji każdego użytkownika. Token taki sam dla wszystkich (albo taki sam we wszystkie dni) nie chroni przed CSRF.

Brak odnawiania tokenów. Jeśli używasz tego samego tokenu przez tygodnie, atakujący ma więcej czasu na jego wykorzystanie. Odnawiaj tokeny regularnie i zawsze po wrażliwych operacjach.

Poleganie wyłącznie na ciasteczkach SameSite. SameSite pomaga, ale nie wystarcza. Używaj tokenów CSRF jako głównej obrony, a SameSite jako zabezpieczenia dodatkowego.

Brak tokenów w niektórych formularzach. Jeśli chronisz tokenami część formularzy, a inne nie, atakujący użyją tych niezabezpieczonych. Każdy formularz, który zmienia dane, potrzebuje ochrony.

Co WEMASY robi dla ochrony CSRF

Formularze WEMASY automatycznie zawierają ochronę tokenem CSRF w każdym utworzonym formularzu. Nie musisz niczego konfigurować ani o tym myśleć. Gdy odwiedzający wysyła formularz, WEMASY waliduje token, zanim zapisze zgłoszenie. Ta ochrona jest wbudowana i domyślnie włączona.

Więcej o opcjach bezpieczeństwa formularzy znajdziesz na stronie z cennikiem.

Najczęstsze pytania

Czy atakujący może odgadnąć token CSRF?
Teoretycznie nie. Tokeny CSRF są kryptograficznie losowe i często się zmieniają. Atakujący próbujący zgadnąć token musiałby sprawdzić miliardy możliwości. W praktyce tokeny CSRF są tak nieprzewidywalne, że zgadywanie nie jest realnym atakiem. Siła tokenu wynika z losowości i unikalności, a nie z utrzymywania go w tajemnicy.
Co się stanie, gdy odwiedzający wyśle formularz z nieprawidłowym tokenem?
Zgłoszenie zostaje odrzucone. Serwer nie przetwarza danych formularza i nie zapisuje zgłoszenia. Odwiedzający zwykle widzi komunikat o błędzie (np. „Sesja wygasła” lub „Nieprawidłowe żądanie”) i jest proszony o ponowną próbę. Z punktu widzenia atakującego ukryty formularz po prostu nie działa.
Czy potrzebuję ochrony CSRF, jeśli mój formularz nie wymaga logowania?
Tak. Ataki CSRF mogą działać na formularzach bez uwierzytelniania. Atakujący może użyć CSRF, by nakłonić odwiedzającego do wysłania niechcianych danych do dowolnego formularza, niezależnie od tego, czy jest zalogowany. Każdy formularz przetwarzający zgłoszenia potrzebuje ochrony CSRF.
Czym CSRF różni się od XSS?
Cross-Site Scripting (XSS) to sytuacja, w której atakujący wstrzykuje do Twojej strony złośliwy kod uruchamiany w przeglądarkach odwiedzających. CSRF to sytuacja, w której atakujący nakłania przeglądarkę odwiedzającego do wysłania formularza do innej strony. To różne ataki z różnymi sposobami obrony. Tokeny CSRF chronią przed CSRF, a walidacja i czyszczenie danych wejściowych chronią przed XSS.
A co z atakami na aplikacje mobilne? Czy tokeny CSRF tam działają?
Aplikacje mobilne są mniej podatne na klasyczne ataki CSRF, bo nie dołączają ciasteczek automatycznie tak jak przeglądarki. Mimo to aplikacje mobilne powinny nadal używać uwierzytelniania opartego na tokenach lub certyfikatach. Jeśli aplikacja mobilna używa ciasteczek lub tokenów wysyłanych automatycznie z żądaniami, powinna też walidować tokeny CSRF jako dodatkową warstwę ochrony.

Wykorzystaj to od razu
na własnej stronie.

Zacznij za darmo z WEMASY i zbuduj stronę w kilka minut.