2012-04-03 16 views
57

Jestem programistą PHP uczącym się Ruby on Rails czytając Michael Hartl's tutorial. Oto cytat z książki, odnosząc się do csrf_meta_tag:Szyny: Jak działa csrf_meta_tag?

... Rails metoda csrf_meta_tag [uniemożliwia] cross-site wniosek fałszowanie (CSRF), rodzaj złośliwego ataku internetowej. Nie przejmuj się szczegółami (ja nie); tylko wiedz, że Rails ciężko pracuje, aby Twoja aplikacja była bezpieczna.

Chodzi o to, że jestem naprawdę ciekawy. W jaki sposób wstawianie metatagów csrf-param i csrf-token zapobiega CSRF? Próbowałem Googling, ale nie mogłem nic znaleźć.

+2

Pozwól mi google, że dla ciebie http://stackoverflow.com/questions/941594/understand-rails-authenticity-token –

+6

@MikhailNikalyukin Dzięki (I myśleć). To wyjaśnia CSRF, który znałem już na podstawach, ale nie wyjaśnia, w jaki sposób * meta tagi * (w przeciwieństwie do ukrytych pól formularzy) mogą temu zapobiec. Czy znasz odpowiedź na to pytanie? – Nick

Odpowiedz

68

csrf_meta_tag w zasadzie spełnia to samo, co ukryte pola formularzy, ale jest po to, aby składać wnioski javascript, które nie są powiązane z formularzem w łatwy sposób na uzyskanie tokena.

Jeśli używasz biblioteki jquery-ujs, zawartość tego metatagu jest automatycznie dodawana (jako nagłówek żądania) do wszystkich wysłanych zapytań ajaxowych.

+0

Krótkie i słodkie. Odpowiedziałeś na moje pytanie. Dzięki! – Nick

+0

Tylko do wykonania: [ten artykuł] (http://robots.thoughtbot.com/a-tour-of-rails-jquery-ujs) wspomina, że ​​ujs może również użyć ich do aktualizacji przestarzałych pamięci podręcznych fragmentów. [Właściwa linia źródłowa uJS] (https://github.com/rails/jquery-ujs/blob/57f4848652584f33018e46414605a873194a97d7/src/rails.js#L57). I na wszelki wypadek zastanawiają się nowi jak ja: 'form_tag' i inni pomocnicy również dodają token CSRF do formularza, więc pracują bez JS. –

52

Wstawia na stronę to, co jest w zasadzie cyfrową sygnaturą, stanowiąc weryfikację, że żądania przychodzące na serwer aplikacji są w rzeczywistości właściwie zalogowanymi użytkownikami. Pomaga to zapobiec skryptom cross-site (skrypt na zupełnie niezwiązanej stronie zwalniania żądań, aby powiedzieć, GMail, gdy jesteś zalogowany do Gmaila w innej karcie).

Domyślam się, że sama csrf_meta_tag nie uniemożliwia niepowiązanej stronie odpalania żądań do Gmaila (lub jakiejkolwiek innej usługi, która jest celem ataku), ale "podpis cyfrowy" w csrf_meta_tag jest używany do weryfikacji ważności wspomnianych żądań. Nieprawidłowe żądania (np. Próby cross-site scripting) nie powinny zostać zatwierdzone i dlatego są odrzucane.

powiedzieć to w inny sposób, z punktu widzenia atakującego widzenia:

Przed csrf_meta_tags istniał (nie są one wyłącznie w Rails za pomocą wszelkich środków), udane cross-site scripting dozwolone szkodliwą witrynę do przekazywania danych do aplikacji internetowej w sposób, który sprawia, że ​​żądanie wygląda tak, jakby było robione w imieniu użytkownika. Załóżmy, że jesteś administratorem usługi internetowej i na jednej karcie przeglądarki jesteś zalogowany w panelu administracyjnym dla tej usługi. Jeśli złośliwa witryna została otwarta na innej karcie, która atakowała twoją usługę w celu ataku, złośliwa strona może być w stanie uruchomić skrypty, które wysyłają żądania administracyjne, takie jak wysypywanie listy użytkowników z bazy danych, kradzież innych poufnych danych lub potencjalnie szkodzenie, uszkadzanie, lub niszczenie danych zawartych w usłudze, wszystkie podczas wyświetlania (z punktu widzenia serwera), aby były prawidłowymi żądaniami od samego administratora. csrf_meta_tag to sposób na podpisywanie żądań i pomaganie udaremnić takie próby.

Istnieje dużo bardziej szczegółowe wyjaśnienie: available here.

Byłoby również pouczające, aby zrobić "źródło widoku" na jednej ze stron generowanych przez Railsy, ​​a zobaczysz, jak wygląda znacznik CSRF.

+1

Dzięki za szczegółową odpowiedź! Chociaż było to pomocne i mogłem się z niego uczyć, nie wyjaśniało, w jaki sposób * meta tagi * pomagają w zapobieganiu CSRF (w przeciwieństwie do, powiedzmy, ukrytych pól formularza). Ale naprawdę doceniam twój czas. Dzięki jeszcze raz! – Nick

13

W Rails to będzie działać jak ten sposób

def csrf_meta_tags 
    if protect_against_forgery? 
     [ 
     tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token), 
     tag('meta', :name => 'csrf-token', :content => form_authenticity_token) 
     ].join("\n").html_safe 
    end 
    end 

See more details just click

Należy również sprawdzić Ruby On Rails Security Guide

tutaj jest ładny blog

ALE - ja prefere luki Narodowy Baza danych, oto dobre wyjaśnienie

CWE-352: Cross-Site Request Forgery (CSRF)

CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Check this document for CWE - Common Weakness Enumeration

+1

Świetne linki do bazy danych luk w zabezpieczeniach! – jefflunt

+2

Dzięki za szczegółową odpowiedź! Chociaż było to pomocne i mogłem się z niego uczyć, nie wyjaśniało, w jaki sposób * meta tagi * pomagają w zapobieganiu CSRF (w przeciwieństwie do, powiedzmy, ukrytych pól formularza). Jednak link do kodu źródłowego wyjaśnił trochę. W każdym razie, naprawdę doceniam twój czas. Dzięki jeszcze raz! – Nick

+0

Cześć Nick, mam kierunek pytania, wkrótce zmienię moją odpowiedź i zaktualizuję. Głównie w ten weekend. –

4

csrf_meta_tags są wskazania do ajax wniosków do korzystania z tych jako jeden z parametrów formularz, aby złożyć wniosek do serwera. Rails oczekuje, że csrf będzie częścią twojego formularza (params) do przetwarzania twoich żądań. Korzystając z tych metatagów, możesz skonstruować treść formularza lub nagłówek csrf w zależności od potrzeb. Mam nadzieję, że ta odpowiedź pomoże ci odpowiedzieć na twoje pytanie.

0

Wyjście pomocnika csrf_meta_tags:

<meta name="csrf-param" content="authenticity_token" /> 
<meta name="csrf-token" content="J/gw2ePXHS9Z1SUSSeUQgMmPhsPEFlFbMrLTLFHLfKjeWh7g4uyOnBlfKnlZlmCBiALDWdDWCSo1z0tybGVtfA==" /> 

Ten token może być zawarte w Ajax żądanie. Exapmle (jquery-ujs):

https://github.com/rails/jquery-ujs/blob/4b6e30f68ff1244fc0c790641d3408c2695a29bd/src/rails.js#L70

csrfToken: function() { 
    return $('meta[name=csrf-token]').attr('content'); 
    }, 

    // URL param that must contain the CSRF token 
    csrfParam: function() { 
    return $('meta[name=csrf-param]').attr('content'); 
    }, 

    // Make sure that every Ajax request sends the CSRF token 
    CSRFProtection: function(xhr) { 
     var token = rails.csrfToken(); 
     if (token) xhr.setRequestHeader('X-CSRF-Token', token); 
    },