Mam wiele problemów związanych z tokenem autentyczności w Railsach, tak jak wiele razy.
Ale tak naprawdę nie chcę po prostu rozwiązać tego problemu i kontynuować. Naprawdę chciałbym zrozumieć token autentyczności. Cóż, moje pytanie brzmi: czy masz jakieś pełne źródło informacji na ten temat, czy poświęciłbyś czas na szczegółowe wyjaśnienie tutaj?
ruby-on-rails
ruby
authenticity-token
Ricardo Acras
źródło
źródło
Odpowiedzi:
Co się dzieje
Gdy użytkownik wyświetla formularz w celu utworzenia, aktualizacji lub zniszczenia zasobu, aplikacja Rails tworzy losowy
authenticity_token
, przechowuje ten token w sesji i umieszcza go w ukrytym polu w formularzu. Gdy użytkownik prześle formularz, Rails szuka goauthenticity_token
, porównuje z tym zapisanym w sesji i jeśli są zgodne, żądanie może być kontynuowane.Dlaczego tak się dzieje
Ponieważ token uwierzytelnienia jest przechowywany w sesji, klient nie może poznać jego wartości. Zapobiega to przesyłaniu formularzy do aplikacji Rails bez przeglądania formularza w samej aplikacji. Wyobraź sobie, że korzystasz z usługi A, zalogowałeś się do usługi i wszystko jest w porządku. Teraz wyobraź sobie, że poszedłeś skorzystać z usługi B i zobaczyłeś zdjęcie, które ci się podoba, i nacisnąłeś je, aby zobaczyć większy rozmiar. Teraz, jeśli w usłudze B był jakiś zły kod, może on wysłać żądanie do usługi A (do której jesteś zalogowany) i poprosić o usunięcie konta, wysyłając żądanie na adres
http://serviceA.com/close_account
. Jest to tak zwane CSRF (Cross Site Request Forgery) .Jeśli usługa A korzysta z tokenów autentyczności, ten wektor ataku nie ma już zastosowania, ponieważ żądanie z usługi B nie będzie zawierało prawidłowego tokenu autentyczności i nie będzie można kontynuować.
Dokumenty API opisują szczegóły dotyczące metatagu:
Notatki
Pamiętaj, że Railsy weryfikują tylko metody bez idempotentne (POST, PUT / PATCH i DELETE). Żądanie GET nie jest sprawdzane pod kątem tokenu autentyczności. Dlaczego? ponieważ specyfikacja HTTP stwierdza, że żądania GET są idempotentne i nie powinny tworzyć, zmieniać ani niszczyć zasobów na serwerze, a żądanie powinno być idempotentne (jeśli uruchomisz to samo polecenie wiele razy, za każdym razem powinieneś uzyskać ten sam wynik).
Również rzeczywista implementacja jest nieco bardziej skomplikowana, jak określono na początku, zapewniając lepsze bezpieczeństwo. Railsy nie wydają tego samego przechowywanego tokena w każdym formularzu. Nie generuje i nie zapisuje za każdym razem innego tokena. Generuje i przechowuje hash kryptograficzny w sesji i wydaje nowe tokeny kryptograficzne, które można dopasować do przechowywanego, za każdym razem, gdy strona jest renderowana. Zobacz request_forgery_protection.rb .
Lekcje
Służy
authenticity_token
do ochrony nie idempotentnych metod (POST, PUT / PATCH i DELETE). Upewnij się także, aby nie dopuścić do żadnych żądań GET, które mogłyby potencjalnie modyfikować zasoby na serwerze.EDYCJA: Sprawdź komentarz @erturne, że żądania GET są idempotentne. Wyjaśnia to lepiej niż ja tutaj.
źródło
Token autentyczności został zaprojektowany tak, abyś wiedział, że formularz jest przesyłany z Twojej witryny. Jest generowany z komputera, na którym działa, z unikalnym identyfikatorem, który zna tylko twoja maszyna, co pomaga zapobiegać atakom polegającym na fałszowaniu żądań w różnych witrynach.
Jeśli po prostu masz trudności z szynami odmawiającymi dostępu do skryptu AJAX, możesz użyć
aby wygenerować poprawny token podczas tworzenia formularza.
Możesz przeczytać więcej na ten temat w dokumentacji .
źródło
Co to jest CSRF?
Token autentyczności stanowi środek przeciwdziałający fałszowaniu żądań między witrynami (CSRF). Co to jest CSRF, pytasz?
Jest to sposób, w jaki osoba atakująca może potencjalnie przejąć sesje, nie znając nawet tokenów sesji.
Scenariusz :
Rozwiązanie CSRF :
źródło
Minimalny przykład ataku, któremu można by zapobiec: CSRF
Na mojej stronie
evil.com
przekonuję Cię do przesłania następującego formularza:Jeśli zalogujesz się do swojego banku za pomocą sesyjnych plików cookie, pliki cookie zostaną wysłane, a przelew zostanie wykonany bez Twojej wiedzy.
Oznacza to, że w grę wchodzi token CSRF:
Tak więc formularz w autentycznej przeglądarce wyglądałby następująco:
Tak więc mój atak nie powiódłby się, ponieważ nie wysłał
authenticity_token
parametru, i nie ma sposobu, bym mógł go odgadnąć, ponieważ jest to ogromna liczba losowa.Ta technika zapobiegania nosi nazwę wzorca tokenu synchronizatora .
Polityka tego samego pochodzenia
Ale co jeśli atakujący wysyła dwa żądania za pomocą JavaScript, jedno do odczytu tokena, a drugie do przeniesienia?
Sam wzorzec tokenu synchronizatora nie wystarczy, aby temu zapobiec!
W tym właśnie momencie na ratunek przychodzi Polityka tego samego pochodzenia, jak wyjaśniłem na stronie : /security/8264/why-is-the-same-origin-policy-so-important/72569# 72569
Jak Rails wysyła tokeny
Objęte: Railsy: Jak działa csrf_meta_tag?
Gruntownie:
Pomocnicy HTML tacy jak
form_tag
dodają ukryte pole do formularza, jeśli nie jest to formularz GETAJAX jest obsługiwany automatycznie przez jquery-ujs , który odczytuje token z
meta
elementów dodanych do nagłówka przezcsrf_meta_tags
(obecnych w szablonie domyślnym) i dodaje go do każdego złożonego żądania.uJS próbuje również zaktualizować token w formularzach w nieaktualnych buforowanych fragmentach.
Inne podejścia zapobiegawcze
X-Requested-With
:Origin
nagłówka: /security/91165/why-is-the-synchronizer-token-pattern-preferred-over-the-origin-header-check-toźródło
Token autentyczności służy do zapobiegania atakom typu Cross-Site Request Forgery (CSRF). Aby zrozumieć token autentyczności, musisz najpierw zrozumieć ataki CSRF.
CSRF
Załóżmy, że jesteś autorem
bank.com
. Na stronie znajduje się formularz służący do przesyłania pieniędzy na inne konto z prośbą GET:Haker może po prostu wysłać do serwera żądanie HTTP z pytaniem
GET /transfer?amount=$1000000&account-to=999999
, prawda?Źle. Atak hakerów nie zadziała. Serwer w zasadzie pomyśli?
Skąd serwer o tym wie? Ponieważ nie ma
session_id
pliku cookie uwierzytelniającego osobę żądającą.Po zalogowaniu się przy użyciu nazwy użytkownika i hasła serwer ustawia
session_id
plik cookie w przeglądarce. W ten sposób nie musisz uwierzytelniać każdego żądania za pomocą nazwy użytkownika i hasła. Gdy przeglądarka wysyłasession_id
ciasteczko, serwer wie:Haker może pomyśleć:
Przeglądarka użytkowników ma ustawiony plik cookie dla
bank.com
domeny. Za każdym razem, gdy użytkownikbank.com
wysyła żądanie do domeny, wszystkie pliki cookie są wysyłane. W tymsession_id
ciasteczko.Więc jeśli haker mógłby zmusić cię do złożenia żądania GET, które przeleje pieniądze na jego konto, odniesie sukces. Jak mógł cię oszukać? Z fałszowaniem żądań między witrynami.
Właściwie to po prostu proste. Haker może po prostu zachęcić cię do odwiedzenia jego strony internetowej. Na swojej stronie internetowej może mieć następujący tag graficzny:
Gdy przeglądarka użytkowników natrafi na ten znacznik obrazu, wysyła żądanie GET do tego adresu URL. A ponieważ żądanie pochodzi z jego przeglądarki, wyśle z nim wszystkie powiązane pliki cookie
bank.com
. Jeśli użytkownik ostatnio zalogował się wbank.com
...session_id
plik cookie zostanie ustawiony, a serwer pomyśli, że użytkownik zamierzał przelać 1 000 000 USD na konto 999999!To nie wystarczy Co jeśli ktoś opublikuje ten obraz na Facebooku i pojawi się on na twojej ścianie? Co się stanie, jeśli zostanie wstrzyknięty do witryny odwiedzanej przez atak XSS?
Nie prawda. Formularz, który wysyła żądanie POST, może być generowany dynamicznie. Oto przykład z Poradnika na temat bezpieczeństwa w Railsach :
Token autentyczności
Kiedy masz
ApplicationController
to:To:
Jest skompilowany w to:
W szczególności generowane są następujące elementy:
Aby zabezpieczyć się przed atakami CSRF, jeśli Railsy nie zobaczą tokena autentyczności wysłanego wraz z żądaniem, nie uzna wniosku za bezpieczne.
Jak atakujący powinien wiedzieć, co to jest ten token? Przy każdym generowaniu formularza losowo generowana jest inna wartość:
Atak Cross Site Scripting (XSS) - tak właśnie jest. Ale to inna wrażliwość na inny dzień.
źródło
Jest
Authenticity Token
to metoda „szynowa ”, aby zapobiec atakom typu „fałszowanie żądań w różnych witrynach (CSRF lub XSRF)” .Mówiąc najprościej, upewnia się, że żądania PUT / POST / DELETE (metody, które mogą modyfikować treść) do Twojej aplikacji internetowej są wysyłane z przeglądarki klienta, a nie od strony trzeciej (atakującego), która ma dostęp do utworzonego pliku cookie po stronie klienta.
źródło
ponieważ
Authenticity Token
jest to bardzo ważne, aw Railsach 3.0+ możesz używaćtworzyć
gdziekolwiek
źródło
XSS
na stronie logowania, nie w nikczemnych celach, ale w celu utworzenia nowej sesji z wstępnie wypełnioną nazwą użytkownika. Teraz wiem, że mogę po prostu użyćvalue="token_value"
.Uwaga: mechanizm tokenu autentyczności może powodować warunki wyścigu, jeśli masz wiele równoczesnych żądań od tego samego klienta. W tej sytuacji Twój serwer może wygenerować wiele tokenów autentyczności, gdy powinien być tylko jeden, a klient otrzymujący wcześniejszy token w formularzu zawiedzie przy następnym żądaniu, ponieważ token cookie sesji został nadpisany. Tutaj jest opis tego problemu i nie do końca trywialne rozwiązanie: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/
źródło
Metody Gdzie
authenticity_token
jest wymaganeDlaczego jest to wymagane
źródło
Co to jest token uwierzytelniania?
Jest to losowy ciąg używany przez aplikację railsową, aby upewnić się, że użytkownik żąda lub wykonuje akcję ze strony aplikacji, a nie z innej aplikacji lub witryny.
Dlaczego potrzebny jest token uwierzytelniający?
Aby chronić aplikację lub witrynę przed fałszowaniem żądań w różnych witrynach.
Jak dodać token uwierzytelnienia do formularza?
Jeśli generujesz formularz przy użyciu tagu form_for, automatycznie zostanie dodany token uwierzytelniający, którego możesz użyć
<%= csrf_meta_tag %>
.źródło