2010-11-01 8 views
9

Ci si sente come html_safe aggiunge un'astrazione alla classe String che richiede la comprensione di ciò che sta accadendo, ad esempio,Perché in Rails 3, <% = note.html_safe%> e <% = h note.html_safe%> danno lo stesso risultato?

<%= '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 

Per la linea 4, se stiamo dicendo, ok, abbiamo fiducia la stringa - è è sicuro, ma perché non possiamo evaderlo? Sembra che per sfuggire a esso da h, la stringa deve essere non sicura.

Quindi, sulla linea 1, se la stringa non viene sfuggita da h, verrà eseguita automaticamente l'escape. Sulla linea 5, h non può sfuggire alla stringa due volte, in altre parole, dopo che < è stato modificato in &lt;, non può sfuggire ancora una volta a &amp;lt;.

Quindi cosa sta succedendo? All'inizio pensavo che lo html_safe stia semplicemente taggando una bandiera sulla stringa, dicendo che è sicuro. Allora, perché non lo fa h? Sembra che h e html_escape effettivamente cooperano sull'uso della bandiera:

1) Se una stringa è html_safe, allora h non sfuggirà che

2) Se una stringa non è html_safe, allora quando la stringa viene aggiunto al buffer di output, verrà automaticamente salvato da h.

3) Se h già sfuggito una stringa, viene contrassegnato html_safe, e quindi, sfuggendo ancora una volta da h non avrà alcun effetto. (come su Line 5, e quel comportamento è lo stesso anche in Rails 2.3.10, ma su Rails 2.3.5 h può effettivamente scappare due volte ... quindi in Rails 2.3.5, h è un semplice metodo di escape, ma alcuni dove lungo la linea a 2.3.10, h non è diventato così semplice. ma 2.3.10 non si auto sfuggire una stringa, ma per qualche motivo, il metodo html_safe esiste già per 2.3.10 (a quale scopo?))

È così che funziona esattamente? Penso che al giorno d'oggi, a volte non otteniamo ciò che vogliamo nell'output e aggiungiamo immediatamente html_safe alla nostra variabile, che può essere piuttosto pericolosa, perché può introdurre l'attacco XSS in questo modo, quindi capire come funziona esattamente può essere abbastanza importante . Quanto sopra è solo un'ipotesi su come funziona esattamente. Potrebbe essere in realtà un meccanismo diverso e c'è qualche documento che lo supporta?

risposta

6

Come si può vedere, chiamando html_safe su una stringa si trasforma in una cassaforte SafeBuffer

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

Eventuali operazioni su un SafeBuffer che potrebbero influenzare la sicurezza stringa HTML sarà passato attraverso h()

h utilizza questo flag per evitare la doppia fuga

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

Il comportamento è cambiato e penso che tu sia per lo più corretto su come funziona. In generale non si dovrebbe chiamare html_safe se non si è sicuri che sia già sterilizzato.Come qualche cosa, bisogna fare attenzione durante l'utilizzo

+1

interessante ... utilizza una nuova classe SafeBuffer come "flag" ... quindi "" foobar ".html_safe' creerà e restituirà una nuova istanza di SafeBuffer con il contenuto della stringa originale ... –

Problemi correlati