Alerta de seguridad de dompdf: se descubre una vulnerabilidad de ejecución remota de código en una popular biblioteca de PDF para PHP
DeveloperSteve Coochin
18 de marzo de 2022
0 minutos de lecturaRecientemente, investigadores de Positive Security publicaron sus hallazgos e identificaron una importante vulnerabilidad de ejecución remota de código (RCE) en dompdf, una popular biblioteca para generar PDF. En su informe, describieron una forma de cargar código en una aplicación y ejecutarlo de forma remota mientras se genera un PDF.
Dompdf se usa ampliamente en el ecosistema PHP y está presente en más de 59.000 plataformas y proyectos de código abierto. La página de dompdf en PHP Composer por sí sola registra casi 50 millones de instalaciones desde su lanzamiento inicial en el gestor de paquetes de PHP en 2014.
Al momento de escribir esto, todavía no hay una solución para esta vulnerabilidad. Una posible alternativa es prohibir la carga de estilos de fuentes personalizados durante el proceso de generación de PDF o incluso restringir el acceso de escritura a la carpeta de caché de fuentes. También se puede restringir el acceso a la ubicación de instalación de Composer, según las bibliotecas que se usen y las funciones que necesite la aplicación.
En las versiones de dompdf >= 0.8.6, se puede deshabilitar la configuración $isRemoteEnabled para evitar que se carguen fuentes personalizadas mediante reglas CSS font-face. Sin embargo, ten en cuenta que esto podría causar problemas de compatibilidad. Además, en las versiones <0.8.5 no se usa esta configuración, por lo que no es posible corregir esta vulnerabilidad mediante $isRemoteEnabled.
En esta publicación del blog, veremos cómo funciona la vulnerabilidad. Para comprender a fondo el código y las vulnerabilidades, incluso en sus detalles más específicos, me resulta útil poner manos a la obra. Por eso, exploraremos esta vulnerabilidad con una demostración funcional usando la aplicación php-goof en un repositorio de Snyk en GitHub.
Bibliotecas de PDF
Generar PDF dentro de las aplicaciones es una de las tareas que menos me gustan como desarrollador. Es un proceso bastante largo y repetitivo: cambiar el código, generar el PDF, volver a cambiar el código, volver a generarlo, etc., hasta lograr el formato y el diseño adecuados.
Pero poder convertir HTML a PDF es increíblemente útil, sobre todo si pensamos en la frecuencia con que las aplicaciones necesitan generar PDF. Los usamos casi todos los días en sitios de comercio electrónico o en sitios que manejan datos transaccionales de usuarios y deben generar un recibo para que puedan guardarlo o imprimirlo.
Por eso, para la mayoría de nosotros, usar una biblioteca para realizar este tipo de tareas durante el desarrollo de aplicaciones ayuda a acelerar el proceso. Bibliotecas como dompdf nos permiten, como desarrolladores, implementar funciones rutinarias y pasar a tareas más complejas.
Cómo explorar la vulnerabilidad de dompdf
Al revisar los hallazgos de seguridad originales, puedes entender mejor qué ocurre dentro de la biblioteca y cómo fue posible explotarla.
En esencia, la biblioteca dompdf toma HTML normal en su formato habitual y lo convierte en un PDF con formato.
Ofrece una funcionalidad sencilla y fácil de usar, que evita una tarea muy rutinaria para una función de uso común. Lo mejor es que da formato al PDF de salida mediante etiquetas HTML estándar.
El HTML también puede incluir estilos. Estos pueden estar en línea con la etiqueta <html> o en una hoja de estilos. Con una hoja de estilos, puedes cargar una font-family e incluir un enlace a un archivo de fuente.
Aquí es donde las cosas empiezan a ponerse interesantes.
La biblioteca dompdf no solo carga una hoja de estilos externa mediante HTML, sino que también guarda el archivo de fuente en una caché local, lo agrega a un directorio de fuentes en el servidor y hace referencia a font-family y a su ubicación desde el framework de dompdf.
El siguiente paso del exploit consiste en introducir código PHP en un archivo de fuente que supere la validación de dompdf y se almacene en el servidor, pero que aun así permita ejecutar ese código PHP desde el archivo. Puede parecer complicado, pero los investigadores originales descubrieron que la validación de la biblioteca solo comprueba el tipo de archivo, no su contenido.
En la aplicación de demostración php-goof, puedes ver cómo funciona si revisas el archivo de fuente personalizado llamado gotcha-normal.otf. En su mayor parte, es un archivo de fuente normal con tipos de letra completamente habituales. Sin embargo, en los metadatos del archivo hay código PHP que se ejecutará en el servidor de la aplicación objetivo: <php? phpinfo(); ?>, dentro del campo de metadatos de derechos de autor. Sí, ¡así de fácil!

Luego, abre el archivo de fuente en un editor de código y copia su contenido en un archivo .php o simplemente cámbiale el nombre. Esto es importante porque dompdf validará los encabezados de fuente del archivo y lo guardará en la caché como un archivo .php, lo que permitirá que sea ejecutable.
A continuación, haz referencia al archivo de fuente falso que acabas de crear en el estilo CSS como font-family. En php-goof, lo hacemos directamente desde el repositorio de php-goof.
Nota: Es importante usar aquí el mismo nombre del archivo de fuente para font-family; de lo contrario, no funcionará en dompdf.
Ahora solo falta inyectar la hoja de estilos en el HTML que se usa para generar el PDF. Esto hará que dompdf almacene esa fuente en el servidor y permitirá ejecutarla de forma remota. Esta parte puede ser un poco complicada, porque el nombre del archivo tiene un hash y el directorio de fuentes puede estar en otra ubicación.
En php-goof, esta parte resulta un poco más sencilla porque se usa el framework de dompdf para identificar la ubicación y el nombre del archivo de fuente. Se utiliza $dompdf->getFontMetrics()->getFont(“gotcha”, “normal”) para averiguar cuándo se detecta en la caché de fuentes de dompdf.
Cuando el archivo de fuente gotcha está disponible en el framework, este devuelve la ruta como un enlace dentro del PDF generado. Aquí tienes algunas capturas de pantalla de la vulnerabilidad en la aplicación goof:



Mantente protegido
Un reconocimiento al equipo de Positive Security, no solo por compartir abiertamente sus hallazgos, sino también por las medidas que tomó para comunicarlos a los responsables del mantenimiento de dompdf.
Recuerda siempre analizar el código base de tu aplicación para identificar situaciones como esta, que pueden surgir sin que te des cuenta. Snyk Code puede ayudarte a detectar vulnerabilidades en frameworks y funciones para que hagas las verificaciones necesarias y protejas a los usuarios finales y sus datos.
Protege tus dependencias de código abierto
Las herramientas de Snyk, diseñadas para desarrolladores, generan pull requests de corrección con un clic para dependencias vulnerables de código abierto y sus dependencias transitivas.



