2009-03-30 11 views
24

¿Cuál es la forma recomendada de escaparse de HTML para evitar vulnerabilidades XSS en las aplicaciones Rails?Escapar HTML en Rails

¿Debería permitir que el usuario coloque cualquier texto en la base de datos pero que lo escape al mostrarlo? ¿Debería agregar filtros before_save para escapar de la entrada?

Respuesta

22

Existen tres enfoques básicos para este problema.

  1. usa h() en tus visualizaciones. La desventaja aquí es que si lo olvidas, obtienes pwnd.
  2. Utilice un complemento que escapa contenido cuando se guarda. Mi complemento xss_terminate hace esto. Entonces no tiene que usar h() en sus vistas (principalmente). Hay otros que funcionan en el nivel de controlador. Las desventajas aquí son (a) si hay un error en el código de escape, puede obtener XSS en su base de datos; y (b) Hay casos de esquina donde aún querrá usar h().
  3. Utilice un complemento que escapa contenido cuando se muestra. CrossSiteSniper es probablemente el más conocido de estos. Esto alía sus atributos para que cuando llame a foo.name se escape del contenido. Hay una forma de evitarlo si necesitas el contenido sin guardar. Me gusta este complemento pero no me gusta dejar que XSS en mi base de datos en primer lugar ...

Luego hay algunos enfoques híbridos.

No hay ninguna razón por la que no pueda usar xss_terminate y CrossSiteSniper al mismo tiempo.

También hay una implementación de ERb llamada Erubis que se puede configurar para que se escape cualquier llamada como <%= foo.name %> - el equivalente a <%= h(foo.name) %>. Desafortunadamente, Erubis siempre parece estar detrás de Rails, por lo que usarlo puede ralentizarte.

Si quiere leer más, escribí una publicación de blog (a la que amablemente se ha vinculado Xavor) sobre using xss_terminate.

+0

Su plugin funciona muy bien. ¡Gracias! – djburdick

+0

¿Quiere actualizar esto para Rails 3? – slhck

+1

Yuck. Los datos escapados en su base de datos son una mala idea para la cordura. – Ashe

5

Utilice el método h en su plantilla de visualización. Digamos que tienes un objeto post con un comentario propiedad:

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

El h es un alias para html_escape, que es un método de utilidad para escapar de todos los caracteres de etiqueta 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; 

Si necesita más control, vaya con el método sanitize, que puede ser utilizado como una lista blanca de etiquetas y atributos para permitir:

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

que permitiría al usuario ingresa nada, almacenarla como está en la base de datos, y escapar al mostrar que . De esa forma no perderá ninguna información ingresada. Siempre puede modificar la lógica de escape más adelante ...

+0

Respaldo el movimiento de permitir que los usuarios ingresen cualquier cosa y escapen solo en las pantallas. xss_terminate es bueno pero puede ser lento y hace que la actualización a Rails 3 sea mucho más difícil. – simianarmy

0

Acabo de lanzar un complemento llamado ActsAsSanitiled usando la gema Sanitize que puede garantizar la buena formación y ser muy configurable para el tipo de HTML permitido, todo ello sin interferir con la entrada del usuario ni requerir que se recuerde nada en la plantilla nivel.

Cuestiones relacionadas