2009-03-30 7 views
24

Jaki jest zalecany sposób na uniknięcie kodu HTML, aby zapobiec lukom XSS w aplikacjach Railsowych?Uciekający kod HTML w Railsach

Czy zezwolić użytkownikowi na umieszczenie dowolnego tekstu w bazie danych, ale uciec z niego przy wyświetlaniu? Czy należy dodać filtry before_save, aby uniknąć wprowadzania danych?

Odpowiedz

22

Istnieją trzy podstawowe podejścia do tego problemu.

  1. użyć h() w swoich widokach. Minusem jest to, że jeśli zapomnisz, dostaniesz pwnd.
  2. Użyj wtyczki, która ucieka z treści, gdy jest zapisana. Moja wtyczka xss_terminate to robi. Wtedy nie musisz używać h() w swoich widokach (głównie). Są inne, które działają na poziomie kontrolera. Wadami są tutaj: (a) jeśli wystąpi błąd w kodzie ucieczki, możesz uzyskać XSS w bazie danych; oraz (b) Są przypadki narożne, w których nadal będziesz chciał używać h().
  3. Użyj wtyczki, która wymyka się zawartości, gdy jest wyświetlana. CrossSiteSniper jest prawdopodobnie najbardziej znanym z nich. To zmienia twoje atrybuty, aby po wywołaniu foo.name uciekało z treści. Jest sposób obejścia tego, jeśli chcesz, aby zawartość nie uległa zmianie. Podoba mi się ta wtyczka, ale nie dziwi mnie wpuszczanie XSS do mojej bazy danych ...

Istnieje kilka podejść hybrydowych.

Nie ma powodu, dla którego nie można używać xss_terminate i CrossSiteSniper w tym samym czasie.

Istnieje również implementacja ERb o nazwie Erubis, którą można skonfigurować w taki sposób, aby każde wywołanie, takie jak <%= foo.name %>, zostało usunięte - odpowiednik <%= h(foo.name) %>. Niestety, Erubis zawsze pozostaje w tyle za Railsami, więc używanie go może spowolnić działanie.

Jeśli chcesz przeczytać więcej, napisałem post na blogu (do którego Xavor uprzejmie się połączył) o numerze using xss_terminate.

+0

Twoja wtyczka działa świetnie. dzięki! – djburdick

+0

Może chcieć zaktualizować to dla Rails 3? – slhck

+1

Yuck. Przechwycone dane w bazie danych to zły pomysł na zdrowie psychiczne. – Ashe

5

Użyj metody h w szablonie widoku. Załóżmy, że masz obiekt wiadomości z właściwością Komentarz:

<div class="comment"> 
    <%= h post.comment %> 
</div> 
13

h jest aliasem dla html_escape, który jest metoda narzędziowa do usuwania wszystkich znaków znaczników HTML:

html_escape('<script src=http://ha.ckers.org/xss.js></script>') 
# => &lt;script src=http://ha.ckers.org/xss.js&gt;&lt;/script&gt; 

Jeśli potrzebujesz większej kontroli, idź z metoda sanitize, który może być stosowany w postaci białej liście znaczników i atrybutów, aby umożliwić:

sanitize(@article.body, :tags => %w(table tr td), :attributes => %w(id class style)) 

Chciałbym umożliwić użytkownikowi do niczego wejściowego, przechowywać go jak jest w bazie danych, i uciec podczas wyświetlania go . W ten sposób nie tracisz żadnych wprowadzonych informacji. Zawsze możesz poprawić logikę ucieczki później ...

+0

Po drugie, pozwolę użytkownikom wprowadzać cokolwiek i uciekać tylko na wyświetlaczach. xss_terminate jest ładne, ale może być powolne i sprawia, że ​​uaktualnianie do Rails 3 jest o wiele trudniejsze. – simianarmy

0

Właśnie wydałem plugin o nazwie ActsAsSanitiled przy użyciu klejnotu Sanitize, który może zagwarantować dobrą formułę, a także bardzo konfigurowalny do tego, jaki rodzaj HTML jest dozwolony, a wszystko to bez ingerencji użytkownika lub wymagającego zapamiętania w szablonie poziom.