Dlaczego często umieszcza się tokeny zapobiegające CSRF w plikach cookie?

Staram się zrozumieć cały problem z CSRF i odpowiednie sposoby, aby temu zapobiec. (Resources I ' ve read, understand, and agree with: OWASP CSRF Prevention CHeat Sheet, pytania dotyczące CSRF .)

Jak rozumiem, Luka wokół CSRF jest wprowadzana przez założenie, że (z punktu widzenia serwera www) poprawny plik cookie sesji w przychodzącym żądaniu HTTP odzwierciedla życzenia uwierzytelnionego użytkownika. Ale wszystkie pliki cookie dla domeny origin są magicznie dołączony do żądania przez przeglądarkę, więc naprawdę wszystko, co serwer może wywnioskować z obecności ważnego pliku cookie sesji w żądaniu, jest to, że żądanie pochodzi z przeglądarki, która ma uwierzytelnioną sesję; nie może dalej zakładać nic o kodzie działającym w tej przeglądarce, lub czy naprawdę odzwierciedla życzenia użytkownika. Sposób, aby temu zapobiec, polega na dodaniu dodatkowych informacji uwierzytelniających ("token CSRF") do żądania, przenoszonych za pomocą innych środków niż automatyczna obsługa plików cookie przeglądarki. Mówiąc luźno, plik cookie sesji uwierzytelnia użytkownika / przeglądarkę, a token CSRF uwierzytelnia kod uruchomiony w przeglądarce.

W skrócie, jeśli używasz pliku cookie sesji do uwierzytelniania użytkowników aplikacji internetowej, powinieneś również dodać token CSRF do każdej odpowiedzi i wymagać pasującego tokenu CSRF w każdym (mutującym) żądaniu. Następnie token CSRF wykonuje roundtrip z serwera do przeglądarki z powrotem na serwer, udowadniając serwerowi że strona składająca żądanie jest zatwierdzona przez (generowany przez, nawet) ten serwer.

Do mojego pytania, które dotyczy konkretnej metody transportu używanej dla tego tokenu CSRF w tej podróży.

Wydaje się pospolite (np. w AngularJS, Django, Rails ), Aby wysłać token CSRF z serwera do klienta jako plik cookie (tj. w nagłówku Set-Cookie), a następnie mieć Javascript w kliencie zeskrobać go z pliku cookie i dołączyć go jako oddzielny nagłówek XSRF-TOKEN aby odesłać na serwer.

(alternatywną metodą jest metoda zalecana przez np. Express, gdzie token CSRF wygenerowany przez serwer jest dołączany do ciała odpowiedzi poprzez rozszerzenie szablonu po stronie serwera, dołączane bezpośrednio do kodu / znaczników, które dostarczą go z powrotem do serwera, np. jako ukryte wejście formularza. Ten przykład jest bardziej web 1.0-owski sposób robienia rzeczy, ale uogólniłby fine do bardziej obciążonego js klienta.)

Dlaczego tak często używa się Set-Cookie jako transport downstream dla tokena CSRF / dlaczego jest to dobry pomysł ? Wyobrażam sobie, że autorzy wszystkich tych frameworków uważnie rozważali swoje opcje i nie zrozumieli tego źle. Ale na pierwszy rzut oka używanie Plików cookie do obejścia tego, co zasadniczo ogranicza projektowanie plików cookie, wydaje się głupie. W rzeczywistości, jeśli użyłeś plików cookie jako transportu w obie strony (Set-Cookie: header downstream dla serwera, aby powiedzieć przeglądarce token CSRF, i Cookie: header upstream dla przeglądarki, aby zwrócić go do serwera) ponownie wprowadziłbyś lukę, którą próbujesz naprawić.

Zdaję sobie sprawę, że powyższe frameworki nie używają ciasteczek dla całej rundy dla tokenu CSRF; używają Set-Cookie downstream, a następnie czegoś innego (np. nagłówka X-CSRF-Token), a to zamyka lukę. Ale nawet używanie Set-Cookie jako dalszego transportu jest potencjalnie mylące i niebezpieczne; przeglądarka będzie teraz dołączać token CSRF do każdego żądania, w tym prawdziwego złośliwego XSRF żądania; w najlepszym wypadku to sprawia, że żądanie jest większe niż musi być, a w najgorszym - jakiś dobrze znaczący, ale błędny fragment kodu serwera może próbować go użyć, co byłoby naprawdę złe. Co więcej, ponieważ rzeczywistym odbiorcą tokenu CSRF jest Javascript po stronie klienta, oznacza to, że ten plik cookie nie może być chroniony tylko przez http. Więc wysyłanie tokena CSRF poniżej w nagłówku Set-Cookie wydaje mi się dość nieoptymalne.

Author: Community, 2013-12-11

3 answers

Dobrym powodem, którego tak jakby dotknąłeś, jest to, że po otrzymaniu pliku cookie CSRF, jest on dostępny do użytku w całej aplikacji w skrypcie klienta do użytku zarówno w zwykłych formularzach, jak i postach AJAX. Będzie to miało sens w ciężkiej aplikacji JavaScript, takiej jak ta używana przez AngularJS (użycie AngularJS nie wymaga, aby aplikacja była aplikacją jednostronicową, więc byłoby przydatne, gdy stan musi przepływać między różnymi żądaniami stron, gdzie wartość CSRF nie można normalnie utrzymywać w przeglądarce).

Weź pod uwagę następujące scenariusze i procesy w typowej aplikacji dla niektórych zalet i wad każdego podejścia, które opisujesz. Są one oparte na wzorze tokenu synchronizatora .

Request Body Approach

  1. Użytkownik zalogował się pomyślnie.
  2. Serwer wystawia plik cookie auth.
  3. użytkownik kliknie, aby przejść do formularza.
  4. jeśli nie wygenerowano jeszcze dla tej sesji, serwer generuje token CSRF, przechowuje go przeciwko sesji użytkownika i wysyła ją do ukrytego pola.
  5. użytkownik przesyła formularz.
  6. serwer sprawdza ukryte pole dopasowuje przechowywany token sesji.

Zalety:

  • prosty w implementacji.
  • Działa z Ajaxem.
  • pracuje z formami.
  • Cookie może być w rzeczywistości tylko HTTP .

Wady:

  • Wszystkie formularze muszą wypisać ukryte pole w HTML.
  • Any AJAX POSTs musi również zawierać wartość.
  • strona musi wiedzieć z góry, że wymaga tokena CSRF, aby mogła umieścić go w treści strony, więc wszystkie strony muszą gdzieś zawierać wartość tokenu, co może sprawić, że implementacja w dużej witrynie będzie czasochłonna.

Niestandardowy nagłówek HTTP (downstream)

  1. Użytkownik zalogował się pomyślnie.
  2. Serwer wystawia plik cookie auth.
  3. użytkownik kliknie, aby przejść do formularza.
  4. strona ładuje się w przeglądarce, następnie AJAX Prośba o odzyskanie tokenu CSRF.
  5. serwer generuje token CSRF (jeśli nie został jeszcze wygenerowany dla sesji), przechowuje go przed sesją użytkownika i wysyła do nagłówek.
  6. użytkownik przesyła formularz (token jest wysyłany przez ukryte pole).
  7. serwer sprawdza ukryte pole dopasowuje przechowywany token sesji.

Zalety:

Wady:

  • nie działa bez żądania AJAX, aby uzyskać wartość nagłówka.
  • Wszystkie formularze muszą mieć wartość dodaną do kodu HTML dynamicznie.
  • wszelkie posty AJAX muszą również zawierać wartość.
  • strona musi najpierw złożyć żądanie AJAX, aby uzyskać token CSRF, więc będzie to oznaczać dodatkową podróż w obie strony za każdym razem.
  • równie dobrze można było po prostu wysłać token na stronę, która zapisałaby dodatkowe Prośba.

Niestandardowy nagłówek HTTP (upstream)

  1. Użytkownik zalogował się pomyślnie.
  2. Serwer wystawia plik cookie auth.
  3. użytkownik kliknie, aby przejść do formularza.
  4. jeśli nie jest jeszcze wygenerowany dla tej sesji, serwer generuje token CSRF, przechowuje go przeciwko sesji użytkownika i wysyła go gdzieś w zawartości strony.
  5. użytkownik przesyła formularz przez AJAX (token jest wysyłany przez nagłówek).
  6. serwer sprawdza niestandardowe dopasowanie nagłówka przechowywanej sesji token.

Zalety:

Wady:

  • nie działa z formularzami.
  • Wszystkie posty AJAX muszą zawierać nagłówek.

Niestandardowy nagłówek HTTP (upstream & downstream)

  1. Użytkownik zalogował się pomyślnie.
  2. Serwer wystawia plik cookie auth.
  3. użytkownik kliknie, aby przejść do formularza.
  4. strona ładuje się w przeglądarce, następnie żądane jest AJAX, aby odzyskać token CSRF.
  5. serwer generuje token CSRF (jeśli nie został jeszcze wygenerowany dla sesji), przechowuje go przed sesją użytkownika i wysyła do nagłówek.
  6. użytkownik przesyła formularz przez AJAX (token jest wysyłany przez nagłówek) .
  7. serwer sprawdza niestandardowe dopasowanie nagłówka sesji przechowywany token.

Zalety:

Wady:

  • nie działa z formularzami.
  • wszystkie posty AJAX muszą również zawierać wartość.
  • strona musi najpierw złożyć żądanie AJAX, aby uzyskać token CRSF, więc będzie to oznaczać dodatkową podróż w obie strony za każdym razem.

Set-Cookie

  1. Użytkownik zalogował się pomyślnie.
  2. Serwer wystawia plik cookie auth.
  3. użytkownik kliknie, aby przejść do formularza.
  4. serwer generuje token CSRF, przechowuje go na sesji użytkownika i wysyła go do pliku cookie.
  5. użytkownik przesyła formularz przez AJAX lub przez formularz HTML.
  6. serwer sprawdza niestandardowy nagłówek (lub ukryte pole formularza) dopasowuje token przechowywany w sesji.
  7. plik Cookie jest dostępny w przeglądarce do wykorzystania w dodatkowych żądaniach AJAX i formularzy bez dodatkowych żądań do serwera w celu pobrania tokenu CSRF.

Zalety:

  • prosty w implementacji.
  • Działa z Ajaxem.
  • Działa z formularze.
  • niekoniecznie wymaga żądania AJAX, aby uzyskać wartość pliku cookie. Każde żądanie HTTP może je odzyskać i może być dołączone do wszystkich żądań forms / AJAX za pomocą JavaScript.
  • Po pobraniu tokenu CSRF, ponieważ jest on przechowywany w pliku cookie, wartość może być ponownie wykorzystana bez dodatkowych żądań.

Wady:

  • Wszystkie formularze muszą mieć wartość dodaną do kodu HTML dynamicznie.
  • wszelkie posty AJAX muszą również zawierać wartość.
  • plik cookie będzie przesyłany dla każdego żądania (tj. wszystkich Getów dla obrazów, CSS, JS itp., które nie są zaangażowane w proces CSRF) zwiększającego rozmiar żądania.
  • Plik Cookie nie może być tylko HTTP .

Tak więc podejście cookie jest dość dynamiczne, oferując łatwy sposób na pobranie wartości pliku cookie (dowolne żądanie HTTP) i użycie go (JS może automatycznie dodać wartość do dowolnego formularza i może być stosowany w żądaniach AJAX jako nagłówek lub jako nagłówek wartość formularza). Gdy token CSRF zostanie odebrany do sesji, nie ma potrzeby go regenerować, ponieważ atakujący wykorzystujący exploit CSRF nie ma metody odzyskiwania tego tokena. Jeśli złośliwy użytkownik spróbuje odczytać token CSRF użytkownika w którejkolwiek z powyższych metod, zostanie to uniemożliwione przez ta sama polityka pochodzenia . Jeśli złośliwy użytkownik spróbuje odzyskać token CSRF po stronie serwera (np. poprzez curl), token ten nie będzie powiązany z tym samym kontem użytkownika, co konto ofiary w żądaniu nie będzie pliku cookie sesji auth (będzie to plik atakującego-dlatego nie będzie on powiązany po stronie serwera z sesją ofiary).

Oprócz wzorca tokenu synchronizatora Istnieje również metoda zapobiegania plikom cookie Double Submit CSRF, która oczywiście wykorzystuje pliki cookie do przechowywania typu tokenu CSRF. Jest to łatwiejsze do zaimplementowania, ponieważ nie wymaga żadnego stanu po stronie serwera dla tokena CSRF. Token CSRF w rzeczywistości może być standardem uwierzytelnianie cookie podczas korzystania z tej metody, a ta wartość jest przesyłana za pomocą Plików cookie, jak zwykle w żądaniu, ale wartość jest również powtarzana w ukrytym polu lub nagłówku, którego atakujący nie może replikować, ponieważ nie może odczytać wartości w pierwszej kolejności. Zaleca się jednak wybranie innego pliku cookie, innego niż plik cookie uwierzytelniania, aby plik cookie uwierzytelniania mógł być zabezpieczony przez oznaczenie HttpOnly. Więc jest to kolejny częsty powód, dla którego można znaleźć CSRF zapobieganie za pomocą metody opartej na plikach cookie.

 180
Author: SilverlightFox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 10:15:05

Użycie pliku cookie do przekazania tokenu CSRF Klientowi nie pozwala na udany atak, ponieważ atakujący nie może odczytać wartości pliku cookie i dlatego nie może umieścić go w miejscu, którego wymaga Walidacja CSRF po stronie serwera.

Atakujący będzie mógł wysłać żądanie do serwera zarówno za pomocą pliku cookie auth token, jak i pliku cookie CSRF w nagłówkach żądania. Ale serwer nie szuka tokena CSRF jako pliku cookie w nagłówkach żądań, szuka w ładunek wniosku. Nawet jeśli atakujący wie, gdzie umieścić token CSRF w ładunku, musiałby odczytać jego wartość, aby go tam umieścić. Jednak polityka cross-origin przeglądarki uniemożliwia odczyt wartości plików cookie z docelowej strony internetowej.

Ta sama logika nie dotyczy pliku cookie auth, ponieważ serwer oczekuje go w nagłówkach żądań, a atakujący nie musi robić nic specjalnego, aby go tam umieścić.

 26
Author: Tongfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-15 03:14:02

Moje najlepsze przypuszczenie co do odpowiedzi: rozważ te 3 opcje, jak przenieść token CSRF z serwera do przeglądarki.

  1. w treści żądania (nie nagłówka HTTP).
  2. w niestandardowym nagłówku HTTP, a nie Set-Cookie.
  3. jako plik cookie, w nagłówku Set-Cookie.

Myślę, że pierwszy z nich, request body (choć pokazany przez ekspresowy tutorial, który podlinkowałem w pytaniu ), nie jest tak przenośny do wielu różnych sytuacji; nie każdy jest generowanie każdej odpowiedzi HTTP dynamicznie; miejsce, w którym musisz umieścić token w Wygenerowanej odpowiedzi, może się znacznie różnić (w ukrytej formie wejściowej; w fragmencie kodu JS lub zmiennej dostępnej przez inny kod JS; może nawet w adresie URL, chociaż wydaje się to generalnie złym miejscem na umieszczenie tokenów CSRF). Tak więc, chociaż można to zrobić z pewnymi dostosowaniami, #1 to trudne miejsce, aby zrobić uniwersalne podejście.

Drugi, niestandardowy nagłówek, jest atrakcyjny, ale nie działa, ponieważ podczas gdy JS może pobrać nagłówki dla wywołanego XHR, nie może pobrać nagłówków dla strony załadowanej z.

To pozostawia trzeci, plik cookie przenoszony przez nagłówek Set-Cookie, jako podejście, które jest łatwe w użyciu w każdej sytuacji (każdy serwer będzie mógł ustawić nagłówki plików cookie na żądanie i nie ma znaczenia, jakiego rodzaju dane znajdują się w treści żądania). Tak więc pomimo swoich wad, była to najprostsza metoda dla frameworków do szerokiego wdrożenia.

 6
Author: metamatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:21