Pytanie:
Po co odświeżać token CSRF na żądanie formularza?
Philipp Gayret
2012-10-20 16:15:45 UTC
view on stackexchange narkive permalink

W wielu samouczkach i przewodnikach widzę, że token CSRF powinien być odświeżany na żądanie. Moje pytanie brzmi: dlaczego mam to robić? Czy pojedynczy token CSRF na sesję nie jest dużo łatwiejszy niż generowanie jednego na żądanie i śledzenie żądanych?

Wydaje się, że generowanie tokena na żądanie nie poprawia bezpieczeństwa poza tym, co token na sesję już by zrobił. Jedynym argumentem wydaje się być ochrona XSS, ale nie ma to zastosowania, ponieważ jeśli masz lukę w zabezpieczeniach XSS, skrypt i tak może odczytać nowe tokeny.

Jakie są korzyści z generowania nowych tokenów na żądanie?

Osiem odpowiedzi:
bobince
2012-10-22 01:31:40 UTC
view on stackexchange narkive permalink

Z powodów już omówionych nie jest konieczne generowanie nowego tokena na żądanie. Zapewnia prawie zerową przewagę w zakresie bezpieczeństwa i kosztuje użytkownika pod względem użyteczności: mając tylko jeden ważny token naraz, użytkownik nie będzie mógł normalnie poruszać się po aplikacji internetowej. Na przykład, jeśli klikną przycisk „wstecz” i prześlą formularz z nowymi wartościami, przesyłanie zakończy się niepowodzeniem i prawdopodobnie powitają ich wrogim komunikatem o błędzie. Jeśli spróbują otworzyć zasób na drugiej karcie, stwierdzą, że sesja jest losowo przerywana w jednej lub obu kartach. Zwykle nie warto okaleczać użyteczności aplikacji, aby spełnić to bezsensowne wymaganie.

Jest jednak miejsce, w którym warto wydać nowy token CSRF: po zmianie podmiotu w środku Sesja. To znaczy przede wszystkim przy logowaniu. Ma to na celu zapobieżenie atakowi polegającemu na utrwaleniu sesji, prowadzącemu do możliwości ataku CSRF.

Na przykład: atakujący uzyskuje dostęp do witryny i generuje nową sesję. Pobierają identyfikator sesji i wstrzykują go do przeglądarki ofiary (np. Zapisując plik cookie z podatnej na atak domeny sąsiedniej lub wykorzystując inną lukę, taką jak adresy URL jsessionid), a także wstrzykują token CSRF do formularza w przeglądarce ofiary. Czekają, aż ofiara zaloguje się za pomocą tego formularza, a następnie używają innego postu formularza, aby skłonić ofiarę do wykonania akcji z wciąż aktywnym tokenem CSRF.

Aby temu zapobiec, unieważnij token CSRF i wydaj nowy w miejscach (takich jak logowanie), w których już robisz to samo z identyfikatorem sesji, aby zapobiec atakom utrwalania sesji.

Czy ta rada jest nadal aktualna teraz, gdy ataki typu BREACH są czymś?
Ataki BREACH mają być rozwiązywane na innej warstwie (wyłączając kompresję danych aplikacji ORAZ kompresję TLS), więc odpowiedź brzmi: nie powinieneś martwić się atakiem BREACH, chyba że konfigurujesz TLS lub serwer HTTP
D.W.
2012-10-21 04:55:57 UTC
view on stackexchange narkive permalink

Omówienie. Standardową radą jest użycie unikalnego tokena CSRF, który jest unikalny dla każdego żądania. Czemu? Ponieważ token na żądanie jest nieco bardziej odporny na niektóre rodzaje błędów implementacji niż token na sesję. To sprawia, że ​​tokeny na żądanie są prawdopodobnie najlepszym wyborem do tworzenia nowych aplikacji internetowych. Żaden audytor bezpieczeństwa nie będzie też kłopotać się z używaniem tokena CSRF na żądanie.

Jeśli jesteś programistą aplikacji internetowych, to wszystko, co musisz wiedzieć i możesz przestać czytać tutaj. Ale jeśli jesteś ekspertem ds. Bezpieczeństwa i zastanawiasz się nad szczegółowym uzasadnieniem tej porady lub zastanawiasz się, jak duże jest ryzyko, jeśli używasz tokena na sesję, czytaj dalej ....


Zagłębianie się nieco głębiej. Prawda jest taka, że ​​jeśli nie masz żadnych innych luk w swojej witrynie internetowej, pojedynczy token CSRF na sesję jest w porządku. Nie ma powodu, dla którego musisz mieć generować nowy token CSRF na żądanie.

Dowodzi tego fakt, że znajdziesz również renomowanych ekspertów ds. Bezpieczeństwa, którzy twierdzą, że inny rozsądny Sposobem obrony przed CSRF jest użycie podwójnego przesyłania plików cookie: innymi słowy, używasz kodu JavaScript po stronie klienta, który oblicza hash pliku cookie sesji i dodaje go do każdego żądania POST, traktując hash jako token CSRF. Możesz zobaczyć, że zasadniczo generuje to w locie token CSRF, który jest taki sam dla całej sesji.

Oczywiście znam argument, dlaczego niektórzy ludzie mogą zalecać generowanie nowego tokena CSRF dla każdego żądania. Myślą, że jeśli masz również lukę XSS w swojej witrynie, to jeśli użyjesz jednego tokena CSRF na sesję, łatwo będzie użyć XSS do odzyskania tokena CSRF, podczas gdy jeśli wygenerujesz nowy token CSRF na żądanie, zajmie więcej pracy, aby odzyskać token CSRF. Osobiście nie uważam tego za zbyt przekonujący argument. Jeśli masz lukę w zabezpieczeniach XSS w swojej witrynie, nadal można odzyskać tokeny CSRF, nawet jeśli wygenerujesz nowy token CSRF dla każdego żądania, wystarczy kilka dodatkowych wierszy złośliwego kodu JavaScript. Tak czy inaczej, jeśli masz lukę w zabezpieczeniach XSS w swojej witrynie i napotykasz poważnego, znającego się na rzeczy napastnika, trudno jest zagwarantować bezpieczeństwo, niezależnie od sposobu generowania tokenów CSRF.

Ogólnie rzecz biorąc, nie zaszkodzi aby wygenerować nowy token CSRF dla każdego żądania. I może lepiej zrobić to w ten sposób, żeby odciągnąć audytorów bezpieczeństwa. Ale jeśli masz już starszą aplikację, która używa jednego tokena CSRF przez całą sesję, wydanie pieniędzy na konwersję go w celu wygenerowania nowego tokena CSRF dla każdego żądania prawdopodobnie nie byłoby super wysoko na mojej liście priorytetów: Założę się, że mógłby znaleźć inne zastosowania dla tych pieniędzy i energii deweloperów, które jeszcze bardziej poprawiłyby bezpieczeństwo.

Nie nazwałbym ich „renomowanymi ekspertami ds. Bezpieczeństwa”, gdyby zalecali przesyłanie podwójnych plików cookie ... XSS to nie jedyny problem, jaki mamy do rozwiązania. OWASP ma dobre podsumowanie na ten temat ...
Podwójne przesyłanie plików cookie @AviD, jest całkowicie w porządku. Nie widziałem jeszcze żadnego dowodu na to, że to podejście jest znacznie bardziej podatne na ataki niż jakiekolwiek inne. Każda technika ma swoje słabości. Ten nie jest inny.
@Gili problem z podwójnie przesyłanymi plikami cookie polega na tym, że zazwyczaj odnosi się to do normalnego, już istniejącego pliku cookie sesji - i nie powinien być dostępny dla JavaScript (np. Przy użyciu flagi `HttpOnly`). Użycie tej techniki może zapobiec atakowi CSRF, ale spowodowałoby otwarcie pliku cookie sesji na inne problemy, na przykład zwiększenie podatności na możliwe luki w zabezpieczeniach XSS. Istnieją techniki, które działają dobrze, nie powodując innych, oddzielnych luk w zabezpieczeniach.
@AviD,, jak wspomniano w http://security.stackexchange.com/q/61110/5002, OWASP instruuje programistów, aby używali oddzielnego pliku cookie dla tokena CSRF właśnie z tego powodu. Możesz zachować flagę `HttpOnly` w pliku cookie sesji.
@Gili tak, o to właśnie chodzi.
@AviD, przepraszam, nie rozumiem twojego punktu. Powiedziałeś, że podwójne przesyłanie plików cookie zmusza cię do usunięcia flagi `HttpOnly` z pliku cookie sesji, ale właśnie wyjaśniłem, że tak nie jest (możesz użyć oddzielnego pliku cookie dla tokena podwójnego przesyłania plików cookie). Czy to nie unieważnia Twojej pierwotnej skargi?
@Gili, ponownie przeczytał komentarze AviD. Nie zapomnij użyć słowa „typowo”. Przez przesłanie podwójnego pliku cookie zwykle rozumie się ponowne użycie pliku cookie sesji. Jeśli ktoś zaleca przesyłanie plików cookie z dwoma plikami cookie i nie ma przeciwnych wyraźnych zastrzeżeń, oznacza to, że zaleca ponowne użycie pliku cookie sesji. Myślę, że AviD opisał to w swoich komentarzach powyżej.
Słusznie. PS: W podobnej notatce http://security.stackexchange.com/a/43550/5002 kwestionuje wartość „HttpOnly” przeciwko atakom XSS.
@Gili, tak, wiem. :-) Właśnie opublikowałem odpowiedź na pytanie, do którego utworzyłeś link, a także link do tej samej dyskusji o `HttpOnly`. Dzięki za wskaźnik i dyskusję!
@Gili tak, dokładnie tak, jak D.W. powiedział, dokładnie taki był mój zamiar.
@AviD, Cieszę się, że obaj jesteśmy na tej samej stronie. Dziękuję za wyjaśnienie.
„nie zaszkodzi wygenerowanie nowego tokena CSRF dla każdego żądania”, szkodzi użyteczności (?)
Token CSRF dla każdego żądania można odświeżyć, ale trzeba zadbać o wywołania Ajax.W pewnym sensie jest to żmudny proces, ale wywołanie Ajax można aktualizować.
rook
2012-10-20 23:24:34 UTC
view on stackexchange narkive permalink

XSS może służyć do odczytywania tokena CSRF, nawet jeśli jest to pojedynczy token przesyłania, to dziecinnie proste. Jest prawdopodobne, że ta rekomendacja dotycząca pojedynczego tokena przesyłania pochodzi od kogoś, kto nie rozumie CSRF.

Jedynym powodem używania „pojedynczego tokena przesyłania” jest chęć zapobieżenia przypadkowemu kliknięciu przez użytkownika prześlij dwa razy. Dobrym zastosowaniem tego jest zapobieganie dwukrotnemu kliknięciu „kasy” przez użytkownika i przypadkowemu dwukrotnemu obciążeniu klienta.

CAPTCHA lub prośba o podanie aktualnego hasła użytkownika może służyć jako środek ochrony przed csrf być omijane przez XSS.

Polecam przeczytanie CSRF Prevention Cheat Sheet.

Nie rozumiem, w jaki sposób CAPTCHA lub wprowadzenie hasła byłoby bezpieczne w obliczu XSS. Po prostu zmusza atakującego do przeskoczenia przez kilka dodatkowych obręczy.
@CodesInChaos atakujący musiałby znać hasło, a wtedy jest to kwestia sporna.
Jeśli użytkownik wprowadzi hasło w pewnym momencie po xss, osoba atakująca prawdopodobnie może je ukraść. Dlatego ponowne wprowadzenie hasła trochę pomaga, ale niewiele.
@CodesInChaos To działa dobrze na papierze, ale ten proponowany atak ma znacznie mniejsze szanse powodzenia w prawdziwym scenariuszu.
@CodesInChaos, masz rację, że CAPTCHA nie miałby do tego znaczenia. Z drugiej strony ponowne uwierzytelnianie (selektywne w przypadku wrażliwych akcji) jest jednym z najlepszych rozwiązań dla CSRF i powinno być częściej używane. Zobacz także dyskusję Schneiera na temat „uwierzytelniania transakcji”, która jest podobna, choć nie identyczna.
Tokeny jednorazowego użytku mają jeszcze więcej korzyści (przynajmniej w przypadku operacji o znaczeniu krytycznym): zwiększają ochronę przed [atakami powtórek] (http://en.wikipedia.org/wiki/Replay_attack).
@Domi To zależy przede wszystkim od tego, w jaki sposób otrzymali token. Gdyby to było z XSS lub przez niezabezpieczony kanał, token nie miałby znaczenia.
Nadal zapewniają ochronę przed atakami typu replay, biorąc pod uwagę, że nie ma XSS.
Polynomial
2012-10-20 18:37:03 UTC
view on stackexchange narkive permalink

Jeśli token jest taki sam w całej sesji, osoba atakująca może wyciec token z jednej strony i użyć go do innego działania.

Na przykład możesz użyć iframe, aby załadować stronę, a następnie wyodrębnij token, korzystając z luki XSS. Stamtąd możesz użyć tego tokena do przesłania formularza zmiany hasła

Używanie tokena na żądanie zamiast tokena obejmującego całą sesję utrudnia, ale nie zapobiega CSRF. Atakujący może po prostu wykorzystać XSS, aby odczytać token ze strony, a następnie go odpalić. Jeśli jednak token jest globalny, a nie ograniczony do tej konkretnej strony, osoba atakująca może zaatakować dowolną stronę, aby ukraść token. Używanie oddzielnych tokenów dla każdego żądania znacznie utrudnia to.

Nie ma możliwości, aby ktoś mógł wyodrębnić cokolwiek z iframe, złamałoby to [te same zasady pochodzenia] (http://en.wikipedia.org/wiki/Same_origin_policy)
@SkPhilipp Przepraszam, chciałem powiedzieć przez XSS.
Za pomocą XSS powinno być możliwe wyodrębnienie tokena, nawet jeśli jest on odświeżany przy każdym żądaniu. Czy mam rację?
Tak, przez XSS możesz następnie załadować iframe do formularza zmiany hasła i możesz wyodrębnić ten token, generowanie nowych tokenów nie zapewniłoby tego bezpieczeństwa, gdybyś miał lukę XSS.
-1 Przykro mi, ale nie chcę, aby ludzie myśleli, że jeśli używają pojedynczego tokena przesyłania, są magicznie chronieni przed XSS, ponieważ jest to najbardziej nieprawdziwe. Jeśli użytkownik może to zrobić w przeglądarce internetowej, to xss może to zrobić w przeglądarce internetowej.
@Rook Co? Nigdy nie powiedziałem, że używanie jednego tokena jest dobre ...
Jeśli masz lukę w zabezpieczeniach XSS, możesz użyć XHR do odczytania dowolnej strony i przesłania dowolnego żądania. Posiadanie innego tokena na każdej stronie nie pomaga.
@Rook Nie twierdzę, że całkowicie rozwiązuje problem, ale utrudnia to, jeśli używasz indywidualnych tokenów i blokujesz je do określonych żądań. Rozumiem jednak, dlaczego martwisz się, że odpowiedź może dać złe wrażenie.
SilverlightFox
2015-11-30 16:45:14 UTC
view on stackexchange narkive permalink

Oprócz innych odpowiedzi, rozsądne może być również odświeżenie tokena, jeśli Twój serwer jest podatny na atak BREACH.

Wymaga to spełnienia trzech warunków:

  • Być obsługiwane z serwera, który używa kompresji na poziomie HTTP
  • Odzwierciedlaj dane wejściowe użytkownika w treściach odpowiedzi HTTP
  • Odzwierciedlaj tajny (taki jako token CSRF ) w treściach odpowiedzi HTTP

Aby złagodzić BREACH, należałoby odświeżyć token CSRF w żądaniu GET ładującym formularz unieważnić wszystkie poprzednie tokeny. W ten sposób MITM (Man-In-The-Middle) tworzący dodatkowe żądania wykrycia tokena na stronie otrzyma za każdym razem inny token. Oznacza to, że prawdziwy użytkownik nie będzie mógł przesłać formularza w sytuacji MITM.

Oczywiście pozostałe dwa warunki również są spełnione. Prawdopodobnie byłoby łatwiej utrzymać token CSRF na sesję i wyłączyć kompresję na poziomie HTTP dla wszystkich stron obsługujących formularze.

user2428118
2015-07-17 15:45:15 UTC
view on stackexchange narkive permalink

Nie jest to zbyt znany fakt, ale zwykłe porównanie ciągów jest podatne na ataki czasowe ( takie jak ten. Krótko mówiąc, normalne operacje porównywania ciągów ( == lub === ) porówna dwa ciągi znak po znaku od lewej do prawej i zwróci fałsz, gdy napotkają dowolny znak, który nie jest równy w danej pozycji w obu łańcuchach. różnica w czasie, która została potwierdzona jako wykrywalna.

Korzystając z ataku czasowego w celu wypróbowania każdego możliwego znaku dla każdej pozycji, można ustalić, jaki jest rzeczywisty token. Tworząc nowy token za każdym razem, gdy przesyłane jest żądanie z tokenem, można zapobiec temu atakowi.

Oczywiście działa to tylko wtedy, gdy ponownie utworzysz token, jeśli nieprawidłowy token został przesłany, co może być niepożądane. Dlatego lepiej rozwiązać ten problem za pomocą niezależnej od czasu funkcji porównywania ciągów, takiej jak ta.

W porządku, ale muszę zauważyć w przykładach i artykule, który wymieniłeś, teoretycznie atakujący może bardzo dokładnie zmierzyć czas zegara procesora. Maszyna nie była obciążona żadnym innym obciążeniem, a wiele języków używa wstępnie obliczonych kodów skrótów do porównywania ciągów przed wykonaniem sprawdzenia znak po znaku.
Porównania ze stałym czasem mogą i powinny być używane do złagodzenia tego problemu (pętla po wszystkich znakach i x lub flaga różnicy).
edruid
2015-04-23 20:30:37 UTC
view on stackexchange narkive permalink

Jednym z powodów, dla których warto zmienić token CSRF na żądanie, jest ograniczenie wycieku tokenu przez kompresję. Rozumiem przez to, że jeśli atakująca Ewa może wstrzyknąć dane na stronę zawierającą token, na który strona jest wysyłana, skompresowana Ewa może następnie odgadnąć, czy pierwszy znak ciągu otrzymuje mniejszy zestaw danych dla strony, wiedząc, że zgadła od razu do następnego znaku.

Jest to podobne do ataku czasowego.

W tej chwili nie ma powodu (o którym wiem), aby zmieniać token, jeśli jest on wysyłany tylko w nagłówkach HTTP.

Inną metodą jest zmiana tokena, gdy tylko zostanie wykryte nieudane żądanie, ale może to spowodować problemy z tym, że użytkownik nie będzie mógł przesłać żadnego formularza.

Bhuvanesh
2015-07-17 12:37:51 UTC
view on stackexchange narkive permalink

Jeśli ten sam token jest używany przez całą sesję, istnieje prawdopodobieństwo, że atakujący może przejąć token za pomocą XSS i użyć sesji ofiary do wykonania złośliwych działań, takich jak zmiana hasła .

Mogą usuwać hasła, umieszczając ramkę iframe w witrynie, z której korzystasz.

Dlatego lepiej jest użyć jednego tokena na żądanie, aby uniemożliwić atakującemu uzyskanie dostęp do tego tokena.

Atakujący korzystający z XSS może uzyskać dostęp do nowych tokenów, o to całe pytanie. Zobacz także komentarze na http://security.stackexchange.com/a/22904/15195


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...