cd ~/blog

~/vulns/xxe-injection.md

XML External Entity (XXE) Injection

webautor: Jordy Pérez Osorio aviso legal
webXXEsystem

~3 min de lectura


1. Descripción técnica

XML External Entity (XXE) Injection ocurre cuando una aplicación procesa XML no confiable con un parser que permite resolver entidades hacia recursos fuera del límite previsto. El atacante controla el identificador de la entidad; el parser lo consume con los permisos y la conectividad del proceso.

Por ejemplo:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE results [
  <!ENTITY pwned SYSTEM "file:///etc/passwd">
]>
<details>
  <email>
    &pwned;
  </email>
  <password>
    asdf
  </password>
</details>
  • La línea <!DOCTYPE results [...]> declara un DTD (Document Type Definition).

  • Dentro del DTD defines una entidad externa:

<!ENTITY pwned SYSTEM "file:///etc/passwd">

Aquí el atacante dice: “Crea una entidad llamada pwned cuyo contenido provenga del archivo /etc/passwd”.

  • Más abajo, en <email>&pwned;</email>, el parser reemplaza &pwned; por el contenido del archivo real del sistema.

Resultado: el servidor devuelve el contenido del archivo /etc/passwd dentro de la respuesta HTTP.

2. Impacto de la vulnerabilidad

Dependiendo de cómo esté configurado el parser XML y los privilegios del proceso del servidor:

  • Lectura de archivos locales:
    Cualquier archivo legible por el proceso y admitido por el resolver. El efecto puede parecerse a una LFI, pero el mecanismo es diferente: aquí el parser XML recupera el recurso de una entidad externa.

  • SSRF (Server-Side Request Forgery):
    En lugar de file:///etc/passwd, un atacante puede declarar algo como:

<!ENTITY xxe SYSTEM "http://127.0.0.1:8080/admin">

Con esto el parser hace peticiones HTTP desde el servidor mismo, permitiendo escanear la red interna o interactuar con servicios que no son accesibles desde fuera.

  • Denegación de servicio (DoS):
    Mediante entidades anidadas (ataque llamado “Billion Laughs”), se puede forzar al parser a consumir memoria y CPU hasta tumbar el servicio.

  • Ejecución remota en configuraciones excepcionales:
    Requiere un handler adicional que ejecute comandos, como una extensión expect:// habilitada. php:// por sí solo no demuestra RCE.

3. Contexto

  • 1990s – orígenes de XML: XML se diseñó como un formato flexible con capacidad de definir entidades externas para reutilización de contenido. Esto se pensó para conveniencia, no seguridad.

  • 2002-2003: se empezaron a publicar investigaciones de seguridad mostrando que los parsers de XML eran susceptibles a ataques con DTDs maliciosos.

  • 2013: OWASP incluyó XXE dentro de su lista de vulnerabilidades críticas.

  • 2017: con la publicación de OWASP Top 10 2017, XXE aparece formalmente como categoría A4:XXE, dado que en esa época explotarla era muy común en aplicaciones Java, PHP, .NET y Python que usaban librerías por defecto inseguras.

  • Actualidad: Aunque con menos presencia en frameworks modernos (porque muchos desactivan DTDs por defecto), sigue siendo un vector de ataque importante, sobre todo en aplicaciones legacy o en integraciones SOAP/XML.

4. Condiciones necesarias

  1. El servidor recibe XML desde el cliente (Content-Type: text/plain o application/xml).

  2. El parser no está configurado en modo seguro y permite:

    • Definir entidades externas.
    • Resolver recursos externos vía file://, http://, ftp://, etc.
  3. El desarrollador no valida ni sanitiza la entrada XML antes de procesarla.

5. Validación y detección

  • Manualmente:
    Intentando inyectar una entidad externa como <!ENTITY test SYSTEM "file:///etc/hostname"> y revisando la respuesta.

  • Automáticamente:
    Herramientas como BurpSuite (Scanner), OWASP ZAP o XXEInjector pueden detectar la vulnerabilidad.

6. Mitigación

  1. Rechazar DTD cuando no sea necesaria y desactivar la resolución de entidades externas y DTD externos según la biblioteca concreta.

  2. Usar librerías modernas que procesen XML de forma segura por defecto.

  3. Si no es posible desactivar completamente, aplicar whitelists de DTD permitidos.

  4. Validar la estructura de la entrada, sin tratar la sanitización genérica como sustituto de una configuración segura del parser.

  5. Monitorear y auditar accesos a archivos sensibles.

7. Explotación documentada en 061-system

En System, magic.php procesaba el cuerpo XML y reflejaba el campo email. La entidad SYSTEM apuntó primero a file:///etc/passwd; el contenido apareció dentro de la respuesta, confirmando lectura local mediante el parser. El writeup reutilizó la misma primitiva para buscar archivos, pero no atribuye RCE ni SSRF sin evidencia adicional.

8. Clasificación

9. Referencias y conexiones

// relacionados