
bluemonday: un saneador de HTML en golang rápido (inspirado en el OWASP Java HTML Sanitizer) para limpiar contenido generado por el usuario de XSS.
bluemonday es un sanitizador HTML implementado en Go. Es rápido y altamente configurable.
bluemonday toma contenido generado por usuarios no confiable como entrada, y devolverá HTML saneado contra una lista blanca de elementos y atributos HTML aprobados para que puedas incluir el contenido de forma segura en tu página web.
Si aceptas contenido generado por usuarios, y tu servidor usa Go, necesitas bluemonday.
La política predeterminada para contenido generado por usuarios (bluemonday.UGCPolicy().Sanitize()) convierte esto:
Hello <STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>World
En un inofensivo:
Hello World
Y esto:
<a href="javascript:alert('XSS1')" onmouseover="alert('XSS2')">XSS<a>
En esto:
XSS
Mientras que aún permite esto:
<a href="http://www.google.com/">
<img src="https://ssl.gstatic.com/accounts/ui/logo_2x.png"/>
</a>
Para que pase casi sin alteraciones (gana un rel="nofollow", algo bueno para el contenido generado por usuarios):
<a href="http://www.google.com/" rel="nofollow">
<img src="https://ssl.gstatic.com/accounts/ui/logo_2x.png"/>
</a>
Protege a los sitios de ataques XSS. Existen muchos vectores para un ataque XSS y la mejor manera de mitigar el riesgo es sanear la entrada del usuario contra una lista conocida y segura de elementos y atributos HTML.
Siempre debes ejecutar bluemonday después de cualquier otro procesamiento.
Si usas blackfriday o Pandoc, bluemonday debe ejecutarse después de estos pasos. Esto garantiza que no se introduzca HTML inseguro más adelante en tu proceso.
bluemonday está fuertemente inspirado tanto en el OWASP Java HTML Sanitizer como en el HTML Purifier.
Basado en lista blanca: necesitas construir una política que describa los elementos y atributos HTML a permitir (y los patrones regexp de los atributos), o usar una de las políticas incluidas que representan buenos valores predeterminados.
La política que contiene la lista blanca se aplica mediante un analizador rápido, no validante, de solo avance y basado en tokens, implementado en la librería Go net/html por el equipo principal de Go.
Esperamos recibir HTML bien formateado (elementos de cierre para cada elemento abierto aplicable, con el anidamiento correcto), por lo que no nos centramos en reparar HTML mal anidado o incompleto. Nos centramos simplemente en garantizar que los elementos que existan estén descritos en la lista blanca de la política y que los atributos y enlaces sean seguros para usar en tu página web.
GIGO aplica aquí: si le das HTML malo, bluemonday no tiene la tarea de descubrir cómo volver a hacerlo bueno.
Sí
Estamos usando bluemonday en producción, tras migrar desde el OWASP Java HTML Sanitizer, ampliamente utilizado y probado en campo.
Estamos superando nuestra amplia suite de pruebas (incluidas las pruebas de AntiSamy y pruebas para cualquier problema reportado). Revisa los problemas no resueltos para ver si algo podría ser un bloqueo para ti.
Invitamos a enviar pull requests e issues para ayudarnos a garantizar que ofrecemos una protección integral contra diversos ataques mediante contenido generado por usuarios.
Instala usando go get github.com/microcosm-cc/bluemonday
Luego llámalo:
package main
import (
"fmt"
"github.com/microcosm-cc/bluemonday"
)
func main() {
// Do this once for each unique policy, and use the policy for the life of the program
// Policy creation/editing is not safe to use in multiple goroutines
p := bluemonday.UGCPolicy()
// The policy can then be used to sanitize lots of input and it is safe to use the policy in multiple goroutines
html := p.Sanitize(
`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`,
)
// Output:
// <a href="http://www.google.com" rel="nofollow">Google</a>
fmt.Println(html)
}
Ofrecemos tres maneras de llamar a Sanitize:
p.Sanitize(string) string
p.SanitizeBytes([]byte) []byte
p.SanitizeReader(io.Reader) bytes.Buffer
Si te obsesiona el rendimiento, p.SanitizeReader(r).Bytes() devolverá un []byte sin realizar ninguna conversión innecesaria de las entradas o salidas. Aunque la diferencia es tan insignificante que nunca deberías necesitar preocuparte por ello.
Puedes construir tus propias políticas:
package main
import (
"fmt"
"github.com/microcosm-cc/bluemonday"
)
func main() {
p := bluemonday.NewPolicy()
// Require URLs to be parseable by net/url.Parse and either:
// mailto: http:// or https://
p.AllowStandardURLs()
// We only allow <p> and <a href="">
p.AllowAttrs("href").OnElements("a")
p.AllowElements("p")
html := p.Sanitize(
`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`,
)
// Output:
// <a href="http://www.google.com">Google</a>
fmt.Println(html)
}
Incluimos dos políticas predeterminadas:
bluemonday.StrictPolicy(), que puede considerarse equivalente a eliminar todos los elementos HTML y sus atributos, ya que no tiene nada en su lista blanca. Un ejemplo de escenario de uso serían los títulos de publicaciones de blog, donde no se esperan etiquetas HTML en absoluto y, si las hay, tanto los elementos como el contenido de los elementos deben eliminarse. Esta es una política muy estricta.bluemonday.UGCPolicy(), que permite una amplia selección de elementos y atributos HTML seguros para contenido generado por usuarios. Ten en cuenta que esta política no permite iframes, object, embed, estilos, script, etc. Un ejemplo de escenario de uso serían los cuerpos de publicaciones de blog, donde se espera una variedad de formatos junto con la posibilidad de tablas e imágenes.La esencia de construir una política es determinar qué elementos y atributos HTML se consideran seguros para tu escenario. OWASP proporciona una chuleta de prevención de XSS para ayudar a explicar los riesgos, pero esencialmente:
script, style, iframe, object, embed, base, que permiten que el cliente ejecute código o que se incluya contenido de terceros que pueda ejecutar códigoBásicamente, deberías poder describir qué HTML es aceptable para tu escenario. Si no tienes confianza en que puedes describir tu política, considera usar una de las políticas incluidas, como bluemonday.UGCPolicy().
Para crear una nueva política:
p := bluemonday.NewPolicy()
Para añadir elementos a una política, añade solo los elementos:
p.AllowElements("b", "strong")
O usando una regex:
Nota: si un elemento se añade por nombre como se muestra arriba, cualquier regex que coincida será ignorada
También se recomienda asegurarse de que varios patrones no se superpongan, ya que el orden de ejecución no está garantizado y puede provocar que algunas reglas no se apliquen.
p.AllowElementsMatching(regex.MustCompile(`^my-element-`))