Come codificare / eseguire l'escape di una stringa in HTML? C'è un built-in?


98

Ho una stringa non attendibile che desidero mostrare come testo in una pagina HTML. Devo eseguire l'escape dei caratteri " <" e " &" come entità HTML. Meno confusione, meglio è.

Sto usando UTF8 e non ho bisogno di altre entità per le lettere accentate.

C'è una funzione incorporata in Ruby o Rails, o dovrei lanciarne una mia?


2
Secondo OWASP , i seguenti sei caratteri dovrebbero essere sottoposti a escape per una corretta protezione XSS nel contenuto degli elementi HTML:&<>"'/
sffc

Risposte:


94

Il hmetodo helper:

<%=h "<p> will be preserved" %>

Bene, sfugge anche a>, il che non è necessario, ma lo farà.
kch

È possibile utilizzare le parentesi per stamparne alcune con he altre senza. <% = h ("<p") + ">"%>
Trevor Bramble,

Ora sarebbe sciocco. Non mi interessa molto se viene scappato o meno. Sto solo notando che non è richiesto dalle specifiche html.
kch

12
E ' a volte necessario in XHTML causa dell'insistenza piuttosto fastidioso della specifica XML che ']]>' essere tenuto fuori testo (vedere la produzione 'CharData'). Questo rende generalmente più facile (e innocuo) sfuggirgli sempre.
bobince

19
per chi fosse interessato hc'è un alias perhtml_escape
lightswitch05

141

Dai un'occhiata alla classe Ruby CGI . Esistono metodi per codificare e decodificare HTML e URL.

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"

12
Grazie, è fantastico poiché può essere eseguito dai controller. Non che lo farei, ovviamente.
Dan Rosenstark

2
Questo è utile nei test funzionali / di integrazione, per verificare la correttezza del contenuto inserito in un modello (quando si suppone che il contenuto sia in formato HTML).
Alex D

Se il contenuto viene visualizzato in un sito Web di un cliente, diverso dal tuo (dove non puoi controllare la visualizzazione), qual è il problema con l'escape dell'html prima dell'inserimento nel database? C'è un altro lavoro in giro?
n00b

Giusto: l'escape prima di entrare nel database è fantastico. Vuoi solo assicurarti di non avere nessun vecchio hack senza escape prima di aggiungerlo ...
Kevin

5
Mi piace di più il suo sinonimo: CGI.escape_html
Trantor Liu

77

In Ruby on Rails 3 HTML verrà eseguito l'escape per impostazione predefinita.

Per le stringhe senza escape utilizzare:

<%= raw "<p>hello world!</p>" %>

25

ERB :: Util.html_escape può essere utilizzato ovunque. È disponibile senza l'utilizzo requirein Rails.


questo sta effettivamente usando CGI.escapeHTMLsotto
akostadinov

@akostadinov - il risultato è diverso tuttavia. Ad esempio, ERB :: Util.html_escape trasformerà gli apostrofi in & # x27; mentre CGI :: escapeHTML non lo farà
Louis Sayers il

@LouisSayers, non vedo come possa accadere: `` [43] pry (main)> show-source ERB :: Util.html_escape From: /usr/share/ruby/erb.rb @ line 945: Owner : # <Classe: ERB :: Util> Visibilità: pubblica Numero di righe: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end `` `
akostadinov

@akostadinov - hmm ... Sono appena corso di nuovo e sì, hanno prodotto lo stesso output. Giuro che questo ha prodotto risultati diversi quando l'ho eseguito al lavoro (forse un diverso comportamento della versione erb / cgi?). Domani dovrò vedere perché ho ottenuto un risultato diverso al lavoro.
Louis Sayers

17

Un'aggiunta alla risposta di Christopher Bradford per utilizzare l'HTML che esegue l'escape ovunque, dal momento che la maggior parte delle persone non usa CGIoggigiorno, puoi anche usare Rack:

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')

Esiste un modo migliore per eseguire l'escape delle stringhe in modo simile nei metodi di istanza del modello?
Codifica attiva il

15

Puoi usare h()o html_escape(), ma la maggior parte delle persone usa h()per convenzione. h()è l'abbreviazione di html_escape()in rails.

Nel tuo controller:

@stuff = "<b>Hello World!</b>"

Secondo te:

<%=h @stuff %>

Se visualizzi il sorgente HTML: vedrai l'output senza effettivamente mettere in grassetto i dati. Cioè è codificato come &lt;b&gt;Hello World!&lt;/b&gt;.

Apparirà visualizzato come <b>Hello World!</b>


9

Confronto dei diversi metodi:

> CGI::escapeHTML("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

> Rack::Utils.escape_html("quote ' double quotes \"")
=> "quote &#x27; double quotes &quot;"

> ERB::Util.html_escape("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

Ho scritto il mio per essere compatibile con l'escaping di Rails ActiveMailer:

def escape_html(str)
  CGI.escapeHTML(str).gsub("&#39;", "'")
end

0

h() è utile anche per sfuggire alle virgolette.

Ad esempio, ho una vista che genera un collegamento utilizzando un campo di testo result[r].thtitle. Il testo potrebbe includere virgolette singole. Se non scappassi result[r].thtitlenel metodo di conferma, il Javascript si interromperà:

&lt;%= link_to_remote "#{result[r].thtitle}", :url=>{ :controller=>:resource,
:action         =>:delete_resourced,
:id     => result[r].id,
:th     => thread,                                                                                                      
:html       =>{:title=> "<= Remove"},                                                       
:confirm    => h("#{result[r].thtitle} will be removed"),                                                   
:method     => :delete %>

&lt;a href="#" onclick="if (confirm('docs: add column &amp;apos;dummy&amp;apos; will be removed')) { new Ajax.Request('/resource/delete_resourced/837?owner=386&amp;th=511', {asynchronous:true, evalScripts:true, method:'delete', parameters:'authenticity_token=' + encodeURIComponent('ou812')}); }; return false;" title="&lt;= Remove">docs: add column 'dummy'</a>

Nota: la :htmldichiarazione del titolo è magicamente sfuggita da Rails.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.