
Sanitizador de HTML y CSS para Ruby.
Sanitize es un saneador de HTML y CSS basado en listas de permitidos. Elimina todo el HTML y/o CSS de una cadena excepto los elementos, atributos y propiedades que elijas permitir.
Usando una sintaxis de configuración simple, puedes indicar a Sanitize que permita ciertos elementos HTML, ciertos atributos dentro de esos elementos e incluso ciertos protocolos de URL dentro de atributos que contienen URLs. También puedes permitir propiedades CSS específicas, reglas @ y protocolos de URL en elementos o atributos que contienen CSS. Cualquier HTML o CSS que no permitas explícitamente será eliminado.
Sanitize se basa en el analizador HTML5 de Nokogiri, que analiza HTML de la misma forma que los navegadores modernos, y en Crass, que analiza CSS de la misma forma que los navegadores modernos. Siempre que tu configuración de lista de permitidos solo permita marcado y CSS seguros, incluso la entrada más malformada o maliciosa se transformará en una salida segura.
[!WARNING]
Sanitize no puede sanear completamente el contenido de los elementos
<math>o<svg>. Los elementos MathML y SVG son elementos foráneos que no siguen las reglas normales de análisis de HTML.De forma predeterminada, Sanitize eliminará todos los elementos MathML y SVG. Si agregas elementos MathML o SVG a una lista de permitidos de elementos personalizada, puedes crear una vulnerabilidad de seguridad en tu aplicación.
gem install sanitize
require 'sanitize'
# Clean up an HTML fragment using Sanitize's permissive but safe Relaxed config.
# This also sanitizes any CSS in `<style>` elements or `style` attributes.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# Clean up an HTML document using the Relaxed config.
Sanitize.document(html, Sanitize::Config::RELAXED)
# Clean up a standalone CSS stylesheet using the Relaxed config.
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# Clean up some CSS properties using the Relaxed config.
Sanitize::CSS.properties(css, Sanitize::Config::RELAXED)
Sanitize puede sanitizar los siguientes tipos de entrada:
<style>style[!WARNING]
Sanitize no puede sanitizar completamente el contenido de los elementos
<math>o<svg>. Los elementos MathML y SVG son elementos externos que no siguen las reglas normales de análisis de HTML.De forma predeterminada, Sanitize eliminará todos los elementos MathML y SVG. Si añades elementos MathML o SVG a una lista de elementos permitidos personalizada, puedes crear una vulnerabilidad de seguridad en tu aplicación.
Un fragmento es un extracto de HTML que no contiene un elemento <html> de nivel raíz.
Si no especificas ninguna opción de configuración, Sanitize utilizará por defecto su configuración más estricta, lo que significa que eliminará todo el HTML y dejará únicamente texto seguro.
html = '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
Sanitize.fragment(html)
# => "foo"
Para conservar ciertos elementos, añádelos a la lista de elementos permitidos.
Sanitize.fragment(html, elements: ['b'])
# => "<b>foo</b>"
Al sanitizar un documento, el elemento <html> debe estar en la lista de permitidos. También puedes establecer :allow_doctype en true para permitir definiciones de tipo de documento bien formadas.
html = %[
<!DOCTYPE html>
<html>
<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">
</html>
]
Sanitize.document(html,
allow_doctype: true,
elements: ['html']
)
# => "<!DOCTYPE html><html>foo\n \n</html>"
Para sanear CSS en un fragmento o documento HTML, primero incluye en la lista de permitidos el elemento <style> y/o el atributo style. Luego incluye en la lista de permitidos las propiedades CSS, las reglas @ y los protocolos de URL que desees permitir. También puedes elegir si permitir comentarios CSS o hacks de compatibilidad con navegadores.
html = %[
<style>
div { color: green; width: 1024px; }
</style>
<div style="height: 100px; width: 100px;"></div>
<p>hello!</p>
]
Sanitize.fragment(html,
elements: ['div', 'style'],
attributes: {'div' => ['style']},
css: {
properties: ['width']
}
)
#=> %[
# <style>
# div { width: 1024px; }
# </style>
#
# <div style=" width: 100px;"></div>
# hello!
# ]
Sanitize limpiará sin problema una hoja de estilos CSS independiente o una cadena de propiedades sin necesidad de invocar el analizador HTML.
[!WARNING] Esto solo debe usarse para sanitizar CSS destinado a un archivo CSS independiente. Para sanitizar CSS de forma segura en un contexto HTML, como en un elemento
<style>o un atributostyle, debe usarSanitize.document()oSanitize.fragment()con una lista de permitidos adecuada, tal como se describe en las secciones anteriores. No hacerlo puede permitir ataques de inyección HTML.
css = %[
@import url(evil.css);
a { text-decoration: none; }
a:hover {
left: expression(alert('xss!'));
text-decoration: underline;
}
]
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# => %[
#
#
# a { text-decoration: none; }
#
# a:hover {
#
# text-decoration: underline;
# }
# ]
Sanitize::CSS.properties(%[
left: expression(alert('xss!'));
text-decoration: underline;
], Sanitize::Config::RELAXED)
# => %[
#
# text-decoration: underline;
# ]
Además de la configuración predeterminada ultra segura, Sanitize incluye otras tres configuraciones integradas que puede usar directamente o adaptar para satisfacer sus necesidades.
Permite únicamente marcado en línea muy simple. Sin enlaces, imágenes ni elementos de bloque.
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
# => "<b>foo</b>"
Permite una variedad de marcado, incluyendo elementos de formato, enlaces y listas.
No se permiten imágenes ni tablas, los enlaces están limitados a los protocolos FTP, HTTP, HTTPS y mailto, y se añade un atributo rel="nofollow" a todos los enlaces para mitigar el spam SEO.
Sanitize.fragment(html, Sanitize::Config::BASIC)
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
Permite una variedad aún más amplia de marcado, incluidas imágenes y tablas, así como CSS seguro. Los enlaces siguen limitados a los protocolos FTP, HTTP, HTTPS y mailto, mientras que las imágenes se limitan a HTTP y HTTPS. En este modo, rel="nofollow" no se añade a los enlaces.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# => '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'