Cómo procesar código HTML desde aplicaciones PHP, para eliminar posibles ataques XSS y restringir las etiquetas utilizadas, con la librería HTML Purifier, que se utiliza para filtrar validar y depurar código HTML.
HTML Purifier es gratuito y de código libre. Se trata además de un sistema altamente personalizable que puede abarcar varios tipos de usos dentro de un sitio web. Se utiliza generalmente para validar los campos que se reciben desde editores WYSIWYG o simplemente para validar el código que se muestra en una página web.
Toda la documentación, archivos de descarga y ejemplos los puedes encontrar en http://htmlpurifier.org . El sitio web de la librería está bastante completo y tiene varios textos con documentación y demos que sirven para hacerse una idea de las posibilidades y sobre cómo programar el script PHP para configurar la librería de filtrado de HTML.
Existen otras librerías similares para filtrar, validar y depurar HTML, con distintas funcionalidades y complejidades. Alguna de ellas ya las habíamos comentado en DesarrolloWeb.com, como la librería Kses, que es bastante más sencilla en sus posibilidades, pero también un poco más fácil de utilizar. HTML Purifier es quizás el filtro de HTML más completo y para comprobarlo podemos acceder a una comparativa de distintos filtros que aparece en la propia página del HTML Purifier. Claro que es una comparativa un poco subjetiva, que intenta ensalzar las posibilidades de su propia librería, pero aun así merece la pena echarle un vistazo para y conocer el verdadero alcance de HTML Purifier.
Instalación de HTML Purifier
Primero convendría saber que la última versión de HTML Purifier sólo es compatible con PHP 5. Es el único requisito importante de conocer antes de decantarnos por esta solición.Hay dos versiones para descargar esta librería desde http://htmlpurifier.org/download. La única diferencia entre la versión completa y la "Lite" es que se ha eliminado la documentación, los archivos de prueba, perfiles y archivos de mantenimiento, es decir, sólo contiene la carpeta con la librería.
Una vez descargado, descomprimimos el archivo y lo guardamos en el servidor. Después hay que darle permisos de escritura a la carpeta HTMLPurifier/DefinitionCache/Serializer. Suponiendo que hemos descomprimido el archivo en la carpeta raíz del servidor, hay que incluir unas líneas de código en el archivo donde vamos a utilizar esta librería:
- Si tu sitio web trabaja con UTF-8 y XHTML Transitional utiliza el siguiente código:
<?php
require_once '/htmlpurifier/library/HTMLPurifier.auto.php';
$purifier = new HTMLPurifier();
$clean_html = $purifier->purify($dirty_html);
?> - Si utilizas un juego de caracteres distinto o quieres validar el código HTML conforme a otro document type, por ejemplo HTML Transitional, utiliza este otro código:
<?php
require_once '/htmlpurifier/library/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('Core', 'Encoding', 'ISO-8859-1'); // Cambiar por tu juego de caracteres
$config->set('HTML', 'Doctype', 'HTML 4.01 Transitional'); // cambiar por tu doctype
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);
?>
Ejemplo de HTML Purifier
Vamos a mostrar un ejemplo utilizando algunas de las funciones de filtrado de HTML, que proporciona la librería y que permiten verificar un código HTML.En el ejemplo partiremos de un código HTML inicial en el que contendrá una serie de etiquetas HTML, de las cuales, las que nosotros no indiquemos como válidas, las eliminará de nuestro código.
En el siguiente código tenemos una cadena de caracteres con una serie de etiquetas HTML. Lo utilizaremos para configurar HTML Purifier de modo que elimine las etiquetas no permitidas.
$miHTML='<strong>Prueba de HTML Purifier de <a target="_blank" href="www.desarrolloweb.com">www.desarrolloweb.com</a></strong>';
Primero configuramos incluimos la librería y la configuramos con la codificación que necesitemos.
$config = HTMLPurifier_Config::createDefault();
$config->set('Core.Encoding', 'ISO-8859-1');
Indicaremos, de manera opcional, que automáticamente ponga saltos de linea al código que queremos verificar. Esto hace que los saltos de línea dobles se cambien por etiquetas P. Los saltos de línea los deja tal cual. Y por supuesto, para que funcione tenemos que incluir a la etiqueta P entre las permitidas. Luego veremos cómo hacerlo.
$config->set('AutoFormat.AutoParagraph', true);
Después indicaremos las etiquetas y atributos permitidos para nuestro código HTML. En nuestro ejemplo, vamos a permitir las etiquetas b, p, div y a, de las cuales de la etiqueta p sólo admitirá el atributo align y de la etiqueta a admitirá los atributos target y href. El resto de las etiquetas permitidas admiten todos sus atributos correspondientes.
$config->set('HTML.Allowed', 'b,p[align],div,a[target|href]');
Si queremos que en una etiqueta en concreto sólo se pueda admitir un cierto valor de un atributo, incluiremos el siguiente código indicando el archivo desde donde se está ejecutando este código. Hay que crear una nueva directiva de HTMLDefinicion con un identificador único de la definición.
$config->set('HTML.DefinitionID', '1');
Y hay que crear también un identificador exclusivo para la definición anterior, que sirve para manejar la caché de manera inteligente y a la vez vaciarla.
$config->set('HTML.DefinitionRev', 1);
$def = $config->getHTMLDefinition(true);
Aquí hemos indicado que para la etiqueta a sólo admita el atributo target con el valor _blank. Dentro del array se pueden indicar todos los valores que queramos que pueda tomar el atributo de la etiqueta en concreto.
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
array('_blank')
));
Y ya sólo queda purificar nuestro código HTML.
$purifier = new HTMLPurifier($config);
$html_purificado = $purifier->purify($miHTML);
Puedes ver mas funcionalidades de esta librería en la documentación de HTML purifier http://htmlpurifier.org/docs
Para terminar vamos a mostrar el código del ejemplo completo.
$miHTML='<strong>Prueba de HTML Purifier de <a target="_blank" href="https://desarrolloweb.com">www.desarrolloweb.com</a></strong>';
$config = HTMLPurifier_Config::createDefault();
$config->set('Core.Encoding', 'ISO-8859-1');
$config->set('AutoFormat.AutoParagraph', true);
$config->set('HTML.Allowed', 'b,p[align],div,a[target|href]');
$config->set('HTML.DefinitionID', '1');
$config->set('HTML.DefinitionRev', '1');
$def = $config->getHTMLDefinition(true);
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
array('_blank')
));
$purifier = new HTMLPurifier($config);
$html_purificado = $purifier->purify($miHTML);
Gema Maria Molina Prados
Equipo DesarrolloWeb.com