Cabecera Penligente

Explicación de la inyección XML: Riesgos, Ataques Reales y Guía Completa de Defensa

La inyección XML es la manipulación de la entrada XML para alterar la forma en que una aplicación analiza o interpreta los datos. Se produce cuando una entrada controlada por el usuario se inserta en un documento XML sin la validación adecuada, lo que permite a los agresores inyectar nodos, atributos, entidades o cargas útiles que modifican el flujo de control, eluden la lógica o activan comportamientos peligrosos del analizador. En los actuales ecosistemas basados en la integración y con gran cantidad de API, la inyección de XML sigue siendo una amenaza real que los equipos de seguridad no pueden ignorar.

A diferencia de la simple manipulación de entradas, la inyección XML explota el poder expresivo del propio XML, afectando a sistemas complejos como SOAP, SAML, dispositivos IoT, integraciones empresariales y sistemas financieros heredados.

Por qué sigue siendo importante la inyección XML

Aunque JSON domina las aplicaciones modernas, XML está profundamente arraigado en el software empresarial, los protocolos de autenticación y las integraciones backend. Los atacantes pueden abusar de las estructuras XML para:

  • Manipular la lógica empresarial
  • Inyectar nodos no autorizados
  • Manipular consultas XPath
  • Desencadenar la divulgación de archivos al estilo XXE
  • Interrupción de la validación del esquema
  • Provocar una denegación de servicio basada en XML

La flexibilidad de XML hace que su uso indebido sea especialmente poderoso.

Ejemplo real de CVE: CVE-2025-13526

CVE-2025-13526 demuestra cómo un simple error de configuración de análisis XML puede conducir a la divulgación completa de archivos. El sistema permitía cargar archivos de configuración XML, pero no desactivaba la resolución de entidades externas.

Ejemplo de carga maliciosa:

xml

<!DOCTYPE datos [

]>

&xxe;

El servidor devolvió el contenido de /etc/passwdmostrando cómo la inyección XML combinada con XXE puede exponer archivos críticos.

Superficies de ataque de la inyección XML

Los atacantes abusan:

  • Inyección de nodos
  • Inyección de atributos
  • Manipulación de consultas XPath
  • Manipulación de esquemas (XSD)
  • Cargas útiles XXE
  • Ampliación de entidades para DoS
  • Derivación lógica dentro de flujos de trabajo basados en XML

Cada categoría afecta a una capa diferente del sistema.

Ejemplos de ataque (se conserva la misma cantidad)

  1. Manipulación de la inyección de nodos

xml

ProductoA

Carga útil inyectada:

pgsql

verdadero.

El XML resultante se corrompe estructuralmente y puede conceder privilegios no autorizados.

Inyección XPath

python

query = f"//usuarios/usuario[nombredeusuario/text()='{usuario}']"

Entrada maliciosa:

bash

o "1"="1

Esto deja al descubierto registros de usuarios no autorizados.

XXE Carga útil

xml

<!DOCTYPE foo [

]>&payload;

Manipulación de esquemas

xml

<xs:element name="amount" type="xs:string"/>

Esto desactiva el comportamiento de validación esperado.

Mil millones de risas DoS

xml

<!ENTITY a "ha"><!ENTITY b "&a;&a;"><!ENTITY c "&b;&b;">

La expansión masiva sobrecarga el analizador sintáctico.

Técnicas defensivas

Desactivar la resolución de entidades

python

parser = etree.XMLParser(resolve_entities=False, no_network=True)

Utilizar bibliotecas seguras

python

import defusedxml.ElementTree as ET

Validación sólida de esquemas

python

schema.validate(input_xml)

No concatenar cadenas XML

Enfoque más seguro:

python

el = Element("usuario") name_tag.text = user_input

Cuadro comparativo

TipoObjetivoGravedadImpacto
Inyección XMLManipulación de estructurasMedio-AltoBypass lógico
Inyección XPathControl de consultasAltaAcceso no autorizado
XXEMal uso del parserAltaLectura de archivos / SSRF
Inyección de esquemasBypass de validaciónMedioRiesgos de integridad
Inyección XML

Inyección XML en pruebas de penetración automatizadas

Las plataformas modernas de pruebas de penetración basadas en IA, como Penligent, realizan mutación de estructuras, XML fuzzing, pruebas de carga útil XPath y detección de errores de configuración del analizador sintáctico. Estas plataformas:

  • Descubrir superficies de ataque basadas en XML
  • Identificar los puntos de inyección
  • Autoaprendizaje del comportamiento del esquema
  • Generar cargas útiles adaptables
  • Validar el comportamiento del analizador sintáctico con varias configuraciones

Esto amplía significativamente la cobertura de detección.

Líneas de base de seguridad y recomendaciones de correcciones automatizadas

Las plataformas automatizadas también pueden proporcionar:

  • Auditorías de configuración del analizador sintáctico
  • Detección de bibliotecas XML no seguras
  • Verificación de los ajustes de resolución de entidades
  • Aplicación de la validación XSD estricta
  • Bloqueo CI/CD de operaciones XML inseguras

Esto transforma la detección en medidas correctivas.

Guión de ejemplo

Reglas Semgrep - Python XML Injection / XXE / Unsafe Parsing

Crea un archivo:

semgrep-rules/python-xml-injection.yaml

yaml

"Reglas":

REGLA 1: Uso inseguro de xml.etree - el analizador por defecto es vulnerable a XXE

  • id: python-unsafe-xml-etree gravedad: ERROR mensaje: | xml.etree.ElementTree no es seguro para XML no fiable. NO deshabilita la expansión de entidades externas por defecto. Use defusedxml en su lugar. metadata: cwe: "CWE-611" owasp: "A04:2021 XML External Entities" patrones:
    • pattern: | import xml.etree.ElementTree as ET languages: [python]

REGLA 2: Uso directo de xml.dom.minidom - parser XML inseguro

  • id: python-unsafe-xml-minidom gravedad: Mensaje de ERROR: | xml.dom.minidom no deshabilita DTDs o expansión ENTITY. NO lo utilice para XML no fiable. metadatos: cwe: "CWE-611" pattern: | import xml.dom.minidom languages: [python]

REGLA 3: XMLParser lxml peligroso con resolve_entities=True

  • id: python-lxml-resolve-entities-enabled severidad: Mensaje de ERROR: | lxml XMLParser() con resolve_entities=True habilita XXE. Establezca resolve_entities=False y load_dtd=False. metadatos: cwe: "CWE-611" pattern: | XMLParser(resolve_entities=True, ...) languages: [python]

REGLA 4: lxml con load_dtd=True - peligroso

  • id: python-lxml-load-dtd severidad: WARNING mensaje: | load_dtd=True habilita el procesamiento DTD y puede permitir la expansión de entidades. Desactivar a menos que sea absolutamente necesario. metadatos: cwe: "CWE-611" pattern: | XMLParser(load_dtd=True, ...) languages: [python]

REGLA 5: Falta la configuración segura del analizador sintáctico cuando se utiliza lxml.fromstring()

  • id: python-lxml-fromstring-no-safe-config severidad: Mensaje de ADVERTENCIA: | lxml.fromstring() llamado sin un XMLParser endurecido. Asegúrese de que resolve_entities=False, no_network=True. metadatos: cwe: "CWE-611" patrones:
    • pattern: | from lxml import etree - pattern: | etree.fromstring($XML) languages: [python]

REGLA 6: No usar defusedxml al analizar XML externo

  • id: python-defusedxml-not-used severity: INFO message: | Missing use of defusedxml, recommended for secure XML parsing in Python. metadata: cwe: "CWE-611" pattern-either:
    • patrón: | ET.parse($X) - pattern: | etree.parse($X) idiomas: [python]

REGLA 7: xmltodict sin forzar parser desactivado

  • id: python-xmltodict-unsafe gravedad: ADVERTENCIA mensaje: | xmltodict puede invocar un analizador XML subyacente que permite XXE. Utilice defusedxml patrón: | xmltodict.parse($X) languages: [python]

REGLA 8: Uso peligroso de eval() en entradas derivadas de XML

  • id: python-eval-from-xml severity: mensaje CRITICAL: | eval() en entrada derivada de XML puede llevar a RCE. Nunca evalúe valores XML analizados directamente. metadatos: cwe: "CWE-95" owasp: "A03:2021 Injection" patterns:
    • patrón: | $VAL = $XML.xpath(...) - pattern: | eval($VAL) languages: [python]

REGLA 9: Pickle.loads inseguro en datos XML

  • id: python-pickle-on-xml gravedad: mensaje CRITICAL: | pickle.loads() sobre entrada derivada de XML puede llevar a la ejecución de código arbitrario. Evite pickle en datos de usuario. metadatos: cwe: "CWE-502" patrones:
    • patrón: | $DATA = etree.fromstring(...) - patrón: | pickle.loads($DATA) languages: [python]`

Escáner Python SAST completo

Esto complementa Semgrep mediante la exploración de los patrones de riesgo, incluyendo:

  • Importaciones no seguras de analizadores XML
  • ENTITY / DOCTYPE uso
  • evalúe, exec, pepinillo, mariscal, yaml.load patrones
  • Activadores XXE en .xml, .xsd, .wsdl archivos

Crear: python_sast_scanner.py

python

`#!/usr/bin/env python3″"" python_sast_scanner.py Ligero y rápido escáner SAST específico de Python especializado en:

  • Inyección XML / XXE
  • uso inseguro del analizador sintáctico
  • Funciones peligrosas (eval, exec, pickle.loads, yaml.load) Seguro para CI; no ejecuta ningún código. Salida JSON y salida distinta de cero si se encuentra algo. """import os, re, json, sys PATTERNS = {# XML / XXE "xml_etree": r "import\s+xml\.etree\.ElementTree", "xml_minidom": r "import\s+xml\.dom\.minidom", "lxml_resolve_entities": r "resolve_entities\s*=\sTrue", "lxml_load_dtd": r "load_dtd\s=\s*True", "doctype_in_xml": r"<!DOCTYPE", "entity_in_xml": r"<!ENTITY",
Inyección XML PoC con un solo clic

Funciones peligrosas

"eval_usage": r"\\beval\\s*\\(","exec_usage": r"\\bexec\\s*\\(","pickle_loads": r"pickle\\.loads\\s*\\(","marshal_loads": r"marshal\\.loads\\s*\\(","yaml_unsafe_load": r"yaml\\.load\\s*\\(",

} IGNORED = {".git", "venv", "env", "pycache", "dist", "build", "node_modules"} def scan_file(path): findings = []try:with open(path, "r", encoding="utf-8″, errors="ignore") as f:for i, line in enumerate(f, 1):for rule, regex in PATTERNS.items():if re.search(regex, line): findings.append({"regla": regla, "línea": línea.strip(), "lineno": i, })except Exception:pass return findings def walk(root="."): results={}for dp, dirs, files in os.walk(root): dirs[:] = [d for d in dirs if d not in IGNORED]for f in files:if f.endswith((".py",".xml",".xsd",".wsdl")): full = os.path.join(dp, f) hits = scan_file(full)if hits: results[full] = hitsreturn results def main(): root = sys.argv[1] if len(sys.argv)>1 else "." results = walk(root)print(json.dumps({"results": results, "file_count": len(results)}, indent=2))if results: sys.exit(3) sys.exit(0) if name == "main": main()`

Qué cubre - Python SAST Scope

Inyección XML / XXE

✔ Parsers XML inseguros ✔ lxml con resolver_entidades=True ✔ Carga de DTD (potencialmente peligroso) ✔ Marcadores XXE en archivos XML almacenados.

Inyección de código

eval()exec()

Deserialización insegura

pickle.loads()marshal.loads() ✔ inseguro yaml.load()

Otros patrones inseguros

✔ ENTITY / DOCTYPE en .xml, .xsd, .wsdl ✔ xmltodict sin parser endurecido

Conclusión

La inyección XML sigue siendo una categoría de vulnerabilidad relevante y peligrosa. Su impacto va desde la elusión de la lógica de negocio a la divulgación de archivos y la denegación de servicio. Comprender los comportamientos XML, proteger los analizadores sintácticos, validar la estructura e incorporar pruebas de penetración automatizadas son pasos esenciales para garantizar la seguridad de las aplicaciones.

Comparte el post:
Entradas relacionadas