Cómo encontrar y corregir vulnerabilidades de entidades XML
Michael Sherman
7 de septiembre de 2022
0 minutos de lecturaXML es un formato de texto legible por humanos que se usa para transportar y almacenar datos estructurados. Los usuarios definen etiquetas y estructuras de datos en documentos autoexplicativos que cualquier herramienta XML puede analizar, lo que ofrece a los desarrolladores un mecanismo altamente configurable para representar datos.
Para ampliar la sintaxis básica limitada de XML, un autor puede definir la estructura y el contenido aceptable de los datos de un documento mediante una definición de tipo de documento (DTD). La DTD permite a los usuarios definir los datos válidos de un documento y describirlos en un solo lugar para reutilizarlos en todo el documento. Una entidad general se declara en la DTD y luego se referencia en el cuerpo del documento agregando un ampersand (&) antes de su nombre y un punto y coma (;) después.
Puedes definir una entidad en el documento:
Sin embargo, también puedes declarar una entidad en una fuente externa haciendo referencia a una ruta de archivo o URL:
El archivo person.dtd contiene:
Esta capacidad, junto con la sintaxis sencilla de XML y la uniformidad de la mayoría de los analizadores, facilita relativamente que los atacantes realicen un ataque llamado inyección de entidades externas XML (XXE). En esta publicación, analizaremos en detalle la XXE y exploraremos formas de prevenirla.
Por qué la XXE representa un riesgo de seguridad
Los ataques de inyección XXE permiten a los atacantes aprovechar las declaraciones de entidades externas para acceder a archivos o a la infraestructura del servidor o la red objetivo. Esto puede incluir información personal confidencial, lógica de negocio y credenciales.
En casos graves, los atacantes pueden realizar una falsificación de solicitudes del lado del servidor, lo que les permite hacerse pasar por un servidor en la red objetivo y podría permitirles ejecutar código de forma remota. Así pueden escalar sus privilegios, recorrer la infraestructura objetivo y atacar otros componentes sin protección, o propagar ataques que parecen originarse en el objetivo hacia otras redes conectadas.
Recuperación de datos
La vulnerabilidad de inyección XXE más común permite que los atacantes hagan que un servidor revele datos o archivos confidenciales en una respuesta HTTP. Por sí sola, esta vulnerabilidad le da al atacante acceso de solo lectura a los datos, pero puede revelar información útil para escalar a un ataque más dañino.
Por ejemplo, un atacante puede enviar una carga útil a un servidor objetivo para hacer que muestre un archivo de contraseñas local:
Implementar un protocolo sólido de cifrado de datos es eficaz para evitar la recuperación de datos, ya que hace que los datos almacenados sean ilegibles e inutilizables, incluso si un atacante logra infiltrarse en el servidor objetivo. Si usas algoritmos simétricos, como el estándar de cifrado avanzado (AES), para almacenar y transferir información confidencial basada en XML, defines una clave de seguridad confidencial que se usará para cifrar y descifrar tus datos.
Además, deshabilitar la compatibilidad predeterminada del analizador XML con las entidades externas es una estrategia eficaz para mitigar este tipo de ataque.
Falsificación de solicitudes del lado del servidor
Un servidor vulnerable a la inyección XXE le da al atacante la oportunidad de hacerse pasar por él y realizar solicitudes a recursos internos que normalmente no son visibles fuera de la red.
En un ataque de falsificación de solicitudes del lado del servidor (SSRF), el atacante suele inyectar una URL o dirección que apunta a una instancia del sistema de archivos local del servidor vulnerable u otros recursos de acceso restringido, especialmente cuando el analizador XML no filtra correctamente las entradas de los usuarios. Luego, puede obtener credenciales y privilegios administrativos dentro de la red objetivo:
Si el atacante logra obtener privilegios administrativos, puede hacerse pasar por el servidor para explorar la red objetivo en busca de otras vulnerabilidades. Incluso podría ejecutar código de forma remota y propagar nuevos ataques.
Hay algunas medidas que mejoran considerablemente la resiliencia de tu aplicación frente a este tipo de ataque:
Bloquea todas las solicitudes entrantes no autorizadas de usuarios a recursos internos y direcciones confidenciales.
Considera implementar una lista de bloqueo integral con posibles direcciones y URL maliciosas que puedan representar una amenaza para tu infraestructura web.
Adopta herramientas inteligentes de análisis estático (como Snyk Code) que puedan probar tu código para detectar vulnerabilidades y brechas de seguridad.
Ejecución remota de código
Un atacante puede usar la inyección XXE para ejecutar código de forma remota (RCE) en un servidor objetivo.
Por ejemplo, puede atacar un sitio web o una aplicación basada en PHP que tenga habilitado el complemento Expect, declarando una entidad que contenga el contenedor expect para ejecutar comandos de forma remota:
En este ejemplo, el comando ifconfig devuelve la configuración de red del servidor cuando el analizador XML evalúa la entidad xxe.
Podemos prevenir la RCE deshabilitando selectivamente los contenedores de protocolo, como la extensión Expect de PHP, en nuestros sitios web o aplicaciones web.
Sin embargo, incluso cuando no hay forma de recibir una respuesta directa del servidor, un atacante puede recurrir a métodos de XXE ciega.
Ataques de XXE ciega
En algunos casos, los analizadores XML pueden impedir las declaraciones de entidades en el cuerpo de los documentos XML. Un atacante puede evadir esta restricción mediante entidades de parámetro, que solo se declaran en la DTD o como valor de otra entidad. Una entidad de parámetro se declara anteponiendo a su nombre un signo de porcentaje y un carácter de espacio en blanco (%), y luego se referencia agregando un signo de porcentaje (%) antes de su nombre y un punto y coma (;) después.
En este código, el servidor objetivo intentará enviar la solicitud HTTP a la URL del servidor del atacante. Como resultado, el atacante puede realizar una consulta DNS del servidor objetivo mediante este ataque de XXE ciega.
Divulgación de información basada en errores
Nuestro servidor es vulnerable a métodos de inyección XXE ciega si un atacante puede recuperar datos valiosos examinando los mensajes de error que emite.
Por ejemplo, esta carga útil fuerza a nuestro servidor a revelar el archivo /etc/pâsswd en su mensaje de error:
Esta carga útil define tres entidades de parámetro: badfile, cuyo valor es el contenido del archivo /etc/pâsswd; wrapper, que contiene la declaración dinámica de una nueva entidad de parámetro llamada induce; y la entidad induce, que provoca una consulta a una ruta que genera un mensaje de error.
Para declarar la entidad wrapper, el atacante declara dinámicamente la entidad induce, que contiene una ruta válida pero inexistente con el valor del parámetro badfile. Luego, cuando se hace referencia a la entidad wrapper, se inicia la declaración dinámica de la entidad induce.
Por último, cuando el analizador encuentra la entidad induce, devuelve un mensaje de error que informa al usuario que el archivo cuyo nombre coincide con el valor de badfile no existe en la ruta nosuchfileexists. Y como badfile contiene el contenido de etc/pâsswd, el atacante puede ver esa información.
Un protocolo sólido de manejo de errores puede reducir la vulnerabilidad de nuestra aplicación a la divulgación de información basada en errores. Este protocolo puede incluir límites para la longitud y el alcance de los mensajes de error que el servidor envía al cliente. Si usamos un cuerpo de mensaje personalizado y un código de estado HTTP, podemos evitar los mensajes de error extensos generados automáticamente, ya que, en esencia, les ofrecen reconocimiento gratuito a los atacantes.
Debemos definir claramente los mensajes de error para situaciones previstas, como las relacionadas con la excepción FileNotFound de nuestro servidor de ejemplo. Además, debemos asegurarnos de especificar mensajes de error adecuados para los casos extremos, lo que suele requerir que probemos nuestro código.
Exfiltración fuera de banda
Un ataque fuera de banda se usa para exfiltrar datos por un canal distinto del que se usó para enviar el ataque. Este tipo de ataque suele consistir en dirigir al servidor objetivo para que realice una solicitud a una dirección donde el atacante aloja una DTD externa maliciosa.
Primero, deberá enviar una carga útil comprometida con el contenido de una DTD maliciosa, como:
El archivo corrupted.dtd en el servidor del atacante contiene:
Cuando se ejecuta la entidad revealinfo, se envía una solicitud HTTP al servidor del atacante con el valor de badfile incluido en la cadena de solicitud.
Cuando se hace referencia a la entidad deval, se inicia la declaración dinámica de la entidad revealinfo.
Otros vectores
Otros vectores comunes de ataques XXE incluyen:
Carga de archivos, como archivos
.configCampos de entrada de texto, especialmente los campos HTML
textytextarea, que pueden tener reglas limitadas de validación de entradaTecnologías basadas en XML, como las fuentes RSS y las API
Archivos basados en XML, en particular formatos comunes como las imágenes SVG
Por ejemplo, un atacante puede cargar un SVG que contenga un enlace a un documento malicioso para ejecutar un ataque de bomba XML:
La carga útil podría verse así:
El analizador detecta varias declaraciones de entidades en la DTD, pero no las evalúa de inmediato. Luego lee el documento y encuentra el elemento bin, al que accede expandiendo la entidad a4. Sin embargo, para hacerlo debe expandir las diez instancias incluidas de la entidad a3, lo que requiere expandir las entidades a2 incluidas, hasta llegar a a0.
El tamaño final expandido del elemento bin incluye la expansión recursiva de todos los elementos de la entidad a4. En una carga útil con diez o más niveles de entidades anidadas, el archivo resultante puede ocupar cientos de gigabytes, lo que suele provocar un error de falta de memoria en el servidor que intenta analizar el archivo SVG y una denegación de servicio para nuestros usuarios.
Establecer límites automáticos de memoria u otros recursos para el procesamiento de solicitudes basta para prevenir muchos tipos de ataques DOS, ya que suelen depender de sobrecargar la capacidad de un servidor.
Prácticas de seguridad de aplicación universal
Deshabilita la compatibilidad con entidades externas
Prohibir las entidades externas y las DTD definidas por los usuarios suele bastar para mitigar muchos tipos de ataques de inyección XXE, y la mayoría de las herramientas ofrecen comandos de una sola línea para hacerlo.
Usa un firewall de aplicaciones web (WAF)
Los firewalls de aplicaciones web (WAF) son herramientas excelentes para combatir los ataques XXE en general, ya que inspeccionan el tráfico HTTP en busca de contenido potencialmente malicioso y aplican reglas de filtrado para proteger nuestras aplicaciones web.
Implementa seguridad de confianza cero
La relación de confianza entre tus aplicaciones web y otros servicios externos o de terceros (como los agentes de mensajería y las plataformas de autenticación de usuarios) puede explotarse para lanzar un ataque SSRF contra la infraestructura de tu servidor. Además, los servicios de tu red solo deben tener acceso a los recursos que necesitan para funcionar correctamente.
Debemos asegurarnos de aislar correctamente los registros y los datos confidenciales, e implementar procesos sólidos para auditar periódicamente los privilegios de acceso de todos los usuarios, tanto humanos como programáticos. Esto también facilita la gestión del mantenimiento de la seguridad a largo plazo.
Ejecuta siempre análisis automatizados y pruebas para detectar vulnerabilidades XXE
Los análisis de vulnerabilidades automatizados para detectar XXE pueden ayudar a identificar y corregir vulnerabilidades en tu infraestructura antes de que un atacante las explote. Un sistema de detección integral e inteligente también debería ofrecer recomendaciones para proteger aún más el sistema.
Mantén actualizados tus parches de seguridad
Es importante que nuestros sistemas tengan parches actualizados de proveedores de seguridad confiables. Estos pueden incluir actualizaciones de controladores de seguridad y parches de protección contra ataques DOS. Para conocer las últimas vulnerabilidades de código abierto, recomendamos usar Snyk Open Source, que funciona con la completa, precisa y oportuna Snyk Vulnerability Database.
Reduce los riesgos con las capacidades de protección de Snyk
En ocasiones, las bibliotecas de terceros presentan vulnerabilidades que pueden ser explotadas y dejar tu aplicación expuesta a los atacantes. Para reforzar aún más las defensas de tu aplicación, te recomendamos usar Snyk OSS para analizar cada biblioteca de terceros integrada en ella.
También puedes aprovechar las capacidades de Snyk Code para identificar y detectar posibles vulnerabilidades de seguridad antes de que sean explotadas.
Reflexiones finales sobre la seguridad de XML
XML es una herramienta versátil y potente para transportar datos, y lo es aún más porque permite usar dinámicamente recursos externos vinculados. Sin embargo, estas características lo convierten en una herramienta popular entre los actores maliciosos. Para prevenir y mitigar adecuadamente los riesgos asociados, es fundamental comprender las posibles vulnerabilidades que puede introducir.
Las entradas de usuario que no se sanitizan correctamente, el manejo de errores demasiado detallado y los privilegios de acceso configurados de forma deficiente permiten que los atacantes usen ataques de inyección de entidades externas (XXE) para comprometer nuestros sistemas. Una forma eficaz de corregir estas vulnerabilidades es validar y filtrar las entradas y las cargas de archivos de los usuarios y, en la mayoría de los casos, simplemente eliminar funciones como el procesamiento de DTD externas o los envoltorios de protocolo PHP.
Los mensajes de error son más adecuados cuando comunican la mínima información posible al usuario. Por ejemplo, si un usuario no logra iniciar sesión, no es necesario decirle si el problema fue su contraseña o su nombre de usuario.
También podemos implementar WAF y protecciones contra ataques DoS, o usar un proveedor de servicios que ofrezca estas funciones. Y si un atacante logra vulnerar la seguridad, solo debería encontrar datos cifrados y una red de servicios de confianza cero.
Comienza con Capture the Flag
Aprende a resolver desafíos de Capture the Flag con nuestro taller virtual 101 a pedido.



