2010-11-01 15 views
9

Czuje jak html_safe dodaje abstrakcji klasy String, która wymaga zrozumienia tego, co się dzieje, na przykład,Dlaczego w Railsach 3, <% = note.html_safe%> i <% = h note.html_safe%> daje ten sam wynik?

<%= '1 <b>2</b>' %>  # gives 1 &lt;b&gt;2&lt;/b&gt; in the HTML source code 

<%= h '1 <b>2</b>' %> # exactly the same as above 

<%= '1 <b>2</b>'.html_safe %>  # 1 <b>2</b> in HTML source code 

<%= h '1 <b>2</b>'.html_safe %> # exactly the same as above 

<%= h (h '1 <b>2</b>') %> # 1 &lt;b&gt;2&lt;/b&gt; wont' escape twice 

Na linii 4, jeżeli mówimy, ok, ufamy ciąg - to jest bezpieczny, ale dlaczego nie możemy tego uniknąć? Wydaje się, że aby uciec przed nim przez h, ciąg musi być niebezpieczny.

Tak więc w linii 1, jeśli ciąg nie zostanie zmieniony przez h, zostanie automatycznie zmieniony. W linii 5, h nie może uciec z ciągu znaków dwa razy - innymi słowy, po zmianie nazwy na < na &lt;, nie może przed tym uciec jeszcze raz przed &amp;lt;.

Co się dzieje? Na początku myślałem, że html_safe po prostu oznacza flagę do napisu, mówiąc, że jest bezpieczna. Dlaczego więc h nie może tego uniknąć? Wydaje się, że h i html_escape rzeczywiście współpracują przy użyciu flag

1) Jeżeli łańcuch jest html_safe, następnie h nie ujdzie mu

2) Jeśli ciąg nie jest html_safe, wtedy gdy łańcuch zostanie dodany do bufora wyjściowego, zostanie automatycznie zmieniony przez h.

3) Jeśli h już uciekł z ciągu znaków, jest oznaczony html_safe, a zatem, uniknięcie go jeszcze raz przez h nie przyniesie żadnego efektu. (jak na Linii 5, a zachowanie to jest takie samo, nawet w Railsach 2.3.10, ale w Railsach 2.3.5 h może faktycznie uciec z niego dwukrotnie ... więc w Railsach 2.3.5, h jest prostą metodą ucieczki, ale niektóre gdzie wzdłuż linii do 2.3.10, h nie stało się tak proste, ale 2.3.10 nie będzie automatycznie uciekać z ciągu, ale z jakiegoś powodu metoda html_safe już istnieje dla 2.3.10 (w jakim celu?))

Czy to działa dokładnie? Myślę, że obecnie, czasami nie dostajemy tego, czego chcemy na wyjściu i natychmiast dodajemy html_safe do naszej zmiennej, co może być dość niebezpieczne, ponieważ może w ten sposób wprowadzić atak XSS, więc zrozumienie, jak to działa dokładnie może być dość ważne . Powyższe jest tylko zgadywaniem, jak dokładnie działa. Czy to może być faktycznie inny mechanizm i czy jest jakiś dokument, który go obsługuje?

Odpowiedz

6

Jak widać, nazywając html_safe na sznurku zamienia ją w bezpiecznym SafeBuffer

http://github.com/rails/rails/blob/89978f10afbad3f856e2959a811bed1982715408/activesupport/lib/active_support/core_ext/string/output_safety.rb#L87

żadnych operacji na SafeBuffer, które mogłyby mieć wpływ na bezpieczeństwo ciąg html zostaną przekazane przez h()

h wykorzystuje tę flagę, aby uniknąć podwójnego ucieczce

http://github.com/rails/rails/blob/89978f10afbad3f856e2959a811bed1982715408/activesupport/lib/active_support/core_ext/string/output_safety.rb#L18

Zachowanie się zmieniło i myślę, że w większości zgadzasz się, jak to działa. Zasadniczo nie powinieneś dzwonić do html_safe, chyba że masz pewność, że jest już oczyszczony.Jak wszystko, trzeba być ostrożnym podczas korzystania z niego

+1

ciekawe ... używa nowej klasy SafeBuffer jako "flagi" ... więc '" foobar ".html_safe' faktycznie utworzy i zwróci nową instancję SafeBuffer z zawartością oryginalnego napisu ... –

Powiązane problemy