2009-03-28 13 views
78

Tengo una cadena que no es de confianza que quiero mostrar como texto en una página HTML. Necesito escapar de los caracteres '<' y '&' como entidades HTML. Cuanto menos alboroto, mejor.Cómo codificar/escapar HTML de una cadena? ¿Hay un built-in?

Estoy usando UTF8 y no necesito otras entidades para las letras acentuadas.

¿Hay una función incorporada en Ruby o Rails, o debería hacer mi propia?

+2

[De acuerdo con la OWASP] (https: //www.owasp. org/index.php/XSS_ (Cross_Site_Scripting) _Prevention_Cheat_Sheet # RULE_.231 _-_ HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content), se deben escapar los siguientes seis caracteres para una protección XSS adecuada en el contenido del elemento HTML: '& <>" '/' – sffc

Respuesta

77

El método h ayudante:

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

Bueno, también se escapa> , que es innecesario, pero va a hacer. – kch

+0

Puede usar paréntesis para imprimir algunos con hy algunos sin. <% = h (""%> –

+0

Ahora sería tonto. No me importa mucho si se puede escapar o no. Solo estoy notando que no es obligatorio según las especificaciones html. – kch

13

Puede utilizar cualquiera o h()html_escape(), pero la mayoría de la gente usa h() por convención. h() es la abreviatura de html_escape() en rieles.

En su controlador:

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

En su opinión:

<%=h @stuff %> 

Si ve el código HTML: verá la salida sin tener que escribir en negrita los datos. Es decir. está codificado como &lt;b&gt;Hello World!&lt;/b&gt;.

Aparecerá un visualizarse como <b>Hello World!</b>

121

Pedido la clase Rubí CGI. Existen métodos para codificar y decodificar HTML así como también URL.

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

Gracias, esto es genial, ya que se puede hacer desde los controladores. No es que yo haría eso, por supuesto. –

+2

Esto es útil en pruebas funcionales/de integración, para verificar la corrección del contenido insertado en una plantilla (cuando la c ontent se supone que es HTML-escapado). –

+0

Si el contenido se muestra en el sitio web de un cliente, distinto del suyo (donde no puede controlar la vista), ¿cuál es el problema con el escape del html antes de insertarlo en la base de datos? ¿Hay otro trabajo alrededor? – n00b

70

En Ruby on Rails 3 HTML se escapó por defecto.

Para cadenas no escapado usar:

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

funciona como un encanto. Gracias. –

+0

exactamente lo que estaba buscando, gracias. – GnrlBzik

0

h() también es útil para escapar comillas.

Por ejemplo, tengo una vista que genera un enlace usando un campo de texto result[r].thtitle. El texto podría incluir comillas simples. Si no escapé result[r].thtitle en el método de confirmación, el código JavaScript se rompería:

&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 declaración :html título se escapó mágicamente por los rieles.

13

Una adición a la respuesta de Christopher Bradford utilizar el código HTML escapar en cualquier lugar, ya que la mayoría personas no utilizan CGI hoy en día, también se puede utilizar Rack:

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

Funciona con gambas. Gracias. – zezim

+0

¿Hay alguna forma mejor de escanear cadenas de forma similar en los métodos de instancia del modelo? –

22

ERB::Util.html_escape se puede utilizar en cualquier lugar. Está disponible sin usar require en Rails.

+0

esto es en realidad usando 'CGI.escapeHTML' debajo de – akostadinov

+0

@akostadinov - el resultado es diferente sin embargo. Por ejemplo, ERB :: Util.html_escape convertirá los apóstrofes en ' mientras que CGI :: escapeHTML no lo hará –

+0

@LouisSayers, no puedo ver cómo puede suceder eso: '' ' [43] pry (main)> show- ERB fuente :: Util.html_escape Desde: /usr/share/ruby/erb.rb línea @ 945: propietario: # Visibilidad: pública Número de líneas: 3 def html_escape (s) CGI.escapeHTML (s.to_s) final '' ' – akostadinov

2

Comparaison de los diferentes métodos:

> 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;" 

me escribió mi propia para ser compatible con los carriles ActiveMailer escapar:

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