2014-05-21 13 views
29

Implementuję aplikację Rails 4 z interfejsem API. Chcę móc wywoływać API z telefonów komórkowych i samej aplikacji internetowej. Natknąłem this note podczas badania protect_from_forgery:Railsy 4 pomijam protect_from_forgery dla akcji API

Ważne jest, aby pamiętać, że wnioski XML lub JSON mają także wpływ, a jeśli budujemy API trzeba coś takiego:

class ApplicationController < ActionController::Base 
    protect_from_forgery 
    skip_before_action :verify_authenticity_token, if: :json_request? 

    protected 

    def json_request? 
    request.format.json? 
    end 
end 

Myślałem o zrobieniu tego, ale mam pewne zastrzeżenia/pytania:

  1. To rozwiązanie wydaje się pozostawić otwór CSRF otwarty, ponieważ teraz atakujący mógłby stworzyć łącze z javascriptem onclick, który wysyła JSON?
  2. Czy sprawdzenie tokena API jest rozsądnym zamiennikiem? tj. co, jeśli zamiast pomijać sprawdzanie autentyczności, zezwalając mu na niepowodzenie sprawdzenia i odzyskać w handle_unverified_request, jeśli token APi jest obecny i poprawny dla bieżącego użytkownika?
  3. A może powinienem zrobić tylko aplikację internetową i urządzenia mobilne send the CSRF token in the HTTP headers? Czy to jest bezpieczne? W jaki sposób telefon komórkowy otrzymałby nawet token CSRF, biorąc pod uwagę, że nie renderuje on formularzy HTML?

Edycja dla wyjaśnienia:

jestem bardziej zaniepokojony kliknięcie spreparowany odnośnik CSRF użytkownika webapp. Użytkownicy mobilni są uwierzytelniani, autoryzowani i mają klucz API, więc nie martwię się o nie. Jednak włączenie ochrony CSRF dla użytkowników aplikacji webapp uniemożliwia korzystanie z chronionego interfejsu API użytkownikom mobilnym. Chcę poznać prawidłową strategię obsługi tego i nie wierzę, że dokumentacja Rails daje właściwą odpowiedź.

+1

Masz dwa różne scenariusze: aplikacje internetowe i aplikacje inne niż internetowe. CSRF działa tylko w aplikacjach internetowych, ponieważ atak zależy od wykorzystania istniejącej, prawidłowej sesji przeglądarki. Dlatego jeśli uwierzytelniasz się przy użyciu sesji przeglądarki, musisz użyć ochrony tokenu CSRF. Jeśli uwierzytelniasz za pomocą klucza API, nie możesz cierpieć z powodu CSRF, ponieważ nie istnieje żadna ważna sesja do sfałszowania. Jeśli używasz obu technik w tym samym interfejsie API, musisz użyć odpowiedniej metody dla każdego typu żądania. – toxaq

Odpowiedz

9

Osoba atakująca może CURL na swoich kontrolerach lubić, ale jeśli twoje API wymaga uwierzytelnienia, nie dostaną się nigdzie.

Uczynienie klienta API przesyłaniem CSRF nie jest tak naprawdę tym, co robi CSRF. Aby to zrobić, musisz zaimplementować mechanizm pukania, w którym klient najpierw trafi na punkt końcowy autoryzacji, aby uzyskać kod (znany również jako CSRF), a następnie przesłać go do POST. to jest dla klientów mobilnych, ponieważ używa ich przepustowości, mocy i jest opóźniony.

Co więcej, czy jest to faktycznie fałszerstwo (np. F w CSRF), jeśli jest to autoryzowany klient, który uderza w kontroler?

+2

Jestem bardziej zaniepokojony tym, że użytkownik aplikacji internetowej kliknął spreparowany link CSRF. Użytkownicy mobilni są uwierzytelniani, autoryzowani i mają klucz API, więc nie martwię się o nie. Jednak włączenie ochrony CSRF dla użytkowników aplikacji webapp uniemożliwia korzystanie z chronionego interfejsu API użytkownikom mobilnym. Chcę poznać prawidłową strategię obsługi tego i nie wierzę, że dokumentacja Rails daje właściwą odpowiedź. –

+0

@ ChrisCameron CORS powinien chronić Cię przed tworzonymi wywołaniami ajaxowymi z domen, którym nie ufasz. Chyba, że ​​zezwalacie na niezaufane domeny w swoich zasadach CORS. –

5

Wysyłanie tokenu CSRF w nagłówku HTTP jest rzeczywiście powszechnym podejściem. Gwarantuje to, że klient w jakiś sposób uzyskał ważny token. Na przykład utworzony link CSRF zostanie wysłany z plikami cookie uwierzytelnienia, ale nagłówek nie będzie zawierał tokena CSRF. Twój własny javascript na kliencie będzie miał dostęp do plików cookie domeny i będzie mógł skopiować token z pliku cookie do nagłówka we wszystkich żądaniach XHR.

AngularJS stosuje to podejście, as explained here.

Jak dla swoich dwóch pierwszych pytań:

  1. To rozwiązanie wydaje się zostawić otwór CSRF otwarty ...

Rzeczywiście, dlatego nie należy wyłączać tokenu CSRF również w swoim interfejsie API.

  1. Byłoby sprawdzanie tokenu API być rozsądny substytut? ...

Prawdopodobnie nie. Należy wziąć pod uwagę następujące elementy (od OWASP):

CSRF tokeny w żądań GET są potencjalnie przeciekał w kilku miejscach: historii przeglądarki, pliki dziennika HTTP, urządzeń sieciowych, które sprawiają, że punkt do zalogowania pierwszy wiersz żądania HTTP oraz nagłówki Referer, jeśli chroniona strona łączy się z witryną zewnętrzną.

Zalecenie ogólne: Nie próbuj wymyślać koła. OWASP ma stronę o nazwie REST Security Cheat Sheet oraz stronę, z którą wcześniej się łączyłem. Możesz podążać za podejściem Angular (kopiowanie tokena z pliku cookie do nagłówka na każde żądanie XHR) i dla zwykłych formularzy innych niż ajaxowe, pamiętaj, aby używać tylko POST i ukrytego pola, jak to zwykle robi się w zabezpieczeniach CSRF statycznych formularzy serwera .

+0

Opublikowałem również podobne [pytanie] (http://stackoverflow.com/q/40706394/305019), ale myślę, że [OWASP CSRF Cheatsheet] (https://www.owasp.org/index.php/Cross- Site_Request_Forgery_ (CSRF) _Prevention_Cheat_Sheet # Protecting_REST_Services: _Use_of_Custom_Request_Headers) faktycznie mówi, że żądania XHR są chronione przed CSRF, o ile nie zezwalasz na CORS na niezaufane początki. – gingerlime

Powiązane problemy