flawopen.com/Ruby YAML/Ruby YAML
¿Es seguro YAML.load con entradas no confiables?
Comprueba la versión de Psych que carga realmente la aplicación: Psych 4, incluido en Ruby 3.1, cambió YAML.load para usar deserialización segura por defecto. Las versiones anteriores de Psych construían objetos sin esa restricción; Psych también se puede actualizar independientemente de Ruby. YAML.unsafe_load y Marshal.load deserializan objetos Ruby y nunca deben recibir entradas no confiables.
# Psych < 4: YAML.load used unsafe # object construction by default. YAML.load(params[:config]) # Every Psych version: explicitly unsafe. YAML.unsafe_load(user_input) Psych.unsafe_load(user_input) # Marshal has no restricted safe-load API. Marshal.load(cookie_value)
# Explicit restricted types; keep this list minimal. require "yaml" require "date" data = YAML.safe_load( input, permitted_classes: [Date], permitted_symbols: [], aliases: false ) # For ordinary external data, prefer JSON and # validate its shape, values, and input size. data = JSON.parse(input)
Por qué YAML puede ser peligroso
YAML tiene etiquetas que Psych puede convertir en objetos Ruby. Con una carga insegura, un documento etiquetado puede solicitar la construcción de una clase y proporcionar valores para su estado serializado; el impacto depende de las clases disponibles y de su comportamiento. Así se forman cadenas de gadgets de deserialización. Use carga segura para YAML no confiable y valide por separado los datos resultantes. El riesgo general también existe con Python pickle, PHP unserialize y Marshal.load en Ruby.
Rails y otras aplicaciones pueden cargar muchas dependencias, lo que amplía el conjunto de clases y comportamientos disponibles para una cadena de deserialización insegura. Depende del despliegue; no es una propiedad de toda aplicación Rails ni de cualquier documento YAML.
Por qué el cambio de versión generó confusión
Psych 4 cambió YAML.load para usar carga segura por defecto e introdujo unsafe_load para el comportamiento anterior de construcción de objetos. Ruby 3.1 incluyó Psych 4, pero las aplicaciones pueden seleccionar otra versión de la gema Psych; audite la dependencia resuelta y el runtime, no solo la versión de Ruby. Como la carga segura puede rechazar clases específicas de la aplicación o alias, migre con una lista explícita y mínima de clases permitidas en vez de cambiar a unsafe_load.
Si una actualización lleva a introducir unsafe_load, trate esa llamada como un hallazgo cuando la entrada pueda controlarse fuera del límite de despliegue confiable. Prefiera safe_load con la lista mínima necesaria de permitted_classes; no la amplíe solo para silenciar errores de compatibilidad.
FAQ
¿YAML.safe_load es completamente seguro?
¿Y si cargo mis propios archivos de configuración?
¿Marshal puede ser aceptable?
Otro riesgo de Ruby: Marshal.load
A diferencia de YAML, la documentación de Ruby indica que Marshal.load puede reconstruir casi cualquier clase cargada en el proceso y provocar ejecución remota de código si los datos no son confiables. Mantén los datos Marshal dentro de un límite de confianza; nunca deserialices bytes enviados por usuarios o influenciados por atacantes.
Referencias
- Ruby documentation — Psych (YAML)
- Psych 4.0 — Ruby 3.1 API documentation
- Ruby documentation — Marshal security considerations
- CVE-2024-35221 — YAML alias denial of service in RubyGems metadata
- CWE-502 — Deserialization of Untrusted Data
- Is Python's pickle safe for untrusted data?
- Is PHP's unserialize() safe on user input?
- Documentación de Ruby — advertencia de seguridad de Marshal.load