Próbuję zrozumieć cały problem z CSRF i odpowiednie sposoby, aby temu zapobiec. (Zasoby, które przeczytałem, zrozumiałem i zgadzam się z: Arkuszem zapobiegania OWASP CSRF , Pytania dotyczące CSRF .)
Jak rozumiem, luka wokół CSRF wynika z założenia, że (z punktu widzenia serwera) prawidłowy plik cookie sesji w przychodzącym żądaniu HTTP odzwierciedla życzenia uwierzytelnionego użytkownika. Ale wszystkie pliki cookie dla domeny pochodzenia są magicznie dołączone do żądania przez przeglądarkę, więc tak naprawdę cały serwer może wnioskować z obecności prawidłowego pliku cookie sesji w żądaniu, że żądanie pochodzi z przeglądarki, która ma uwierzytelnioną sesję; nie może dalej zakładać niczego o kodziedziałający w tej przeglądarce lub czy rzeczywiście odzwierciedla życzenia użytkowników. Aby temu zapobiec, należy dołączyć do żądania dodatkowe informacje uwierzytelniające („token CSRF”), przenoszone w inny sposób niż automatyczna obsługa plików cookie w przeglądarce. Mówiąc luźniej, plik cookie sesji uwierzytelnia użytkownika / przeglądarkę, a token CSRF uwierzytelnia kod działający w przeglądarce.
Krótko mówiąc, jeśli używasz sesyjnego pliku cookie do uwierzytelniania użytkowników swojej aplikacji internetowej, powinieneś również dodać token CSRF do każdej odpowiedzi i wymagać pasującego tokenu CSRF w każdym (mutującym) żądaniu. Token CSRF wykonuje następnie objazd z serwera do przeglądarki z powrotem na serwer, udowadniając serwerowi, że strona wysyłająca żądanie jest zatwierdzona (wygenerowana przez, nawet) ten serwer.
Na moje pytanie, które dotyczy konkretnej metody transportu użytej dla tego tokenu CSRF w tej rundzie.
Wydaje się powszechne (np. W AngularJS , Django , Rails ) wysyłanie tokena CSRF z serwera do klienta jako pliku cookie (tj. W nagłówku Set-Cookie), a następnie JavaScript w kliencie zeskrobuje go z pliku cookie i dołącza jako osobny nagłówek XSRF-TOKEN, aby wysłać go z powrotem na serwer.
(Alternatywną metodą jest metoda zalecana np. Przez Express , gdzie token CSRF wygenerowany przez serwer jest zawarty w treści odpowiedzi poprzez rozwinięcie szablonu po stronie serwera, dołączony bezpośrednio do kodu / znaczników, które dostarczą go z powrotem do serwera, np. jako ukryte dane wejściowe. Ten przykład jest bardziej internetowym sposobem robienia rzeczy, ale uogólniałby się na klienta bardziej obciążonego JS).
Dlaczego tak często używa się Set-Cookie jako dalszego transportu tokena CSRF / dlaczego 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 jest zasadniczo ograniczeniem projektowym 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: nagłówek w dół dla serwera, aby poinformować przeglądarkę o tokenie CSRF, a Cookie: nagłówek w górę, aby przeglądarka zwróciła go na serwer), ponownie wprowadziłbyś lukę próbują to naprawić.
Zdaję sobie sprawę z tego, że powyższe ramy nie używają plików cookie przez całą podróż do tokena CSRF; wykorzystują Set-Cookie w dół, a następnie coś innego (np. nagłówek Token X-CSRF) w górę, a to eliminuje lukę. Ale nawet stosowanie 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 autentyczne złośliwe żądania XSRF; co najwyżej sprawia, że żądanie jest większe, niż powinno być, a w najgorszym przypadku jakiś sensowny, ale źle wprowadzony fragment kodu serwera może faktycznie spróbować go użyć, co byłoby naprawdę złe. Ponadto, ponieważ faktycznym zamierzonym odbiorcą tokenu CSRF jest JavaScript po stronie klienta, oznacza to, że ten plik cookie nie może być chroniony tylko za pomocą protokołu HTTP.