En febrero de 2026 se hizo pública una vulnerabilidad crítica de escape del entorno de pruebas en n8n, la plataforma de código abierto para la automatización de flujos de trabajo ampliamente utilizada. Registrada con el identificador CVE-2026-25049, esta vulnerabilidad permite a los usuarios autenticados eludir el entorno de pruebas de evaluación de expresiones y ejecutar comandos arbitrarios del sistema en el servidor anfitrión, lo que da lugar a una ejecución remota de código total con una puntuación CVSS v3.1 de 9,9.
En el marco del Programa de BecasOPSWAT , nuestros becarios llevaron a cabo un análisis técnico exhaustivo de CVE-2026-25049, en el que examinaron su causa principal, su mecanismo de explotación y su impacto en las organizaciones.
Este blog ofrece un análisis detallado de la vulnerabilidad, desde la arquitectura de procesamiento de expresiones de n8n y sus controles de seguridad por capas hasta la técnica concreta que burla las cinco capas defensivas al mismo tiempo.

CVE-2026-25049 es una vulnerabilidad crítica de escape del entorno de ejecución de expresiones en n8n, clasificada bajo CWE-913: Control inadecuado de los recursos de código gestionados dinámicamente. La vulnerabilidad afecta a todas las versiones de n8n anteriores a la 1.123.17, así como a las versiones 2.0.0 a 2.5.1, y ha sido corregida en las versiones 1.123.17 y 2.5.2. Permite a los usuarios autenticados con permisos de creación de flujos de trabajo crear expresiones JavaScript maliciosas que eluden el entorno de ejecución aislado de expresiones de la plataforma, logrando en última instancia la ejecución de comandos arbitrarios en el servidor host.

La vulnerabilidad es especialmente grave porque n8n suele ocupar una posición privilegiada dentro de la infraestructura de una organización. Como centro de automatización de flujos de trabajo, n8n suele tener acceso directo a API internas, bases de datos, almacenes de credenciales y servicios de terceros. Una instancia de n8n comprometida no solo deja al descubierto el servidor de automatización, sino que constituye un punto de acceso a todos los sistemas conectados, lo que amplía drásticamente el alcance de la explotación.
CVE-2026-25049 no es un hallazgo independiente, sino una forma de eludir el parche para CVE-2025-68613, una fuga del entorno de pruebas anterior en el evaluador de expresiones de n8n. A pesar de haber implementado múltiples capas de defensa tras la vulnerabilidad inicial, una brecha fundamental en la forma en que el sanitizador procesa los tipos de nodos del Árbol de Sintaxis Abstracta (AST) de JavaScript permitió que la clase de ataque original resurgiera a través de un vector sintáctico diferente. Este patrón —en el que un parche aborda la técnica de explotación específica en lugar de la debilidad de diseño subyacente— pone de relieve el desafío persistente que supone proteger los entornos de evaluación de código dinámico.
La vulnerabilidad se dio a conocer el 4 de febrero de 2026, junto con otros diez avisos de seguridad relativos a n8n, y ha sido analizada de forma independiente por varios equipos de investigación en seguridad.
Acerca de n8n
n8n es una plataforma de código abierto para la automatización de flujos de trabajo que permite a las organizaciones conectar sistemas, automatizar procesos y crear integraciones entre cientos de servicios. Gracias a su amplia aceptación y a las más de 1.300 integraciones disponibles, n8n se ha convertido en una de las herramientas más populares de su categoría, utilizada por equipos de desarrollo y empresas para automatizar todo tipo de tareas, desde herramientas internas hasta flujos de datos críticos para el negocio.

La plataforma admite tanto implementaciones autohospedadas como en la nube y ofrece un generador visual de flujos de trabajo, además de compatibilidad directa con JavaScript para la lógica personalizada. La arquitectura de n8n se basa en nodos: los flujos de trabajo se componen de nodos interconectados que transmiten datos en formato JSON entre desencadenantes, acciones y pasos de función. La ejecución puede realizarse en modo manual para realizar pruebas o en modo de producción para la implementación en vivo. Esta arquitectura, combinada con la compatibilidad nativa con expresiones JavaScript y el acceso a API internas y almacenes de credenciales, convierte a n8n en una potente herramienta de automatización, pero también en un objetivo de gran valor cuando surgen vulnerabilidades.
Antecedentes técnicos
Árboles de sintaxis abstracta
Un árbol de sintaxis abstracta (AST) es una representación jerárquica del código fuente generada por un analizador sintáctico. En lugar de tratar el código como una cadena plana, un AST lo descompone en nodos estructurados que representan sus elementos sintácticos: declaraciones de variables, expresiones de función, expresiones de miembro, identificadores y literales.

Comprender los tipos de nodos AST es fundamental para este análisis, ya que los controles de seguridad de n8n operan a nivel de AST. Los sanitizadores inspeccionan tipos de nodos específicos para detectar y bloquear patrones peligrosos. La vulnerabilidad aprovecha el hecho de que una misma operación semántica —acceder a la propiedad de un objeto— puede generar tipos de nodos AST totalmente diferentes en función de la sintaxis de JavaScript utilizada.

Por ejemplo, la expresión `obj.constructor ` genera un nodo `MemberExpression `, mientras que `const { constructor } = obj` genera una `VariableDeclaration ` que contiene un `ObjectPattern` con un nodo `Property`. Ambas extraen la misma propiedad, pero las estructuras del AST son fundamentalmente diferentes, y los sanitizadores de n8n solo inspeccionan el primer patrón.
Evaluación de expresiones y arquitectura de seguridad de n8n
La arquitectura de n8n se organiza en cinco capas: Frontend, CLI, Core, Workflow y Nodes. La capa Workflow se encarga de la evaluación de expresiones, que es el componente relevante para esta vulnerabilidad.

n8n permite a los usuarios insertar expresiones JavaScript en los parámetros de los nodos del flujo de trabajo para manipular datos de forma dinámica. Estas expresiones se evalúan en el servidor mediante una biblioteca llamada Tournament, que analiza las expresiones en un árbol sintáctico abstracto (AST) antes de su ejecución. Los ganchos de saneamiento se integran directamente en el proceso de creación de Tournament, realizando comprobaciones durante la construcción del AST para interceptar patrones peligrosos antes de que se ejecute ningún código.

Dado que estas expresiones se ejecutan dentro del mismo proceso de Node.js que el servidor de n8n, la plataforma cuenta con cinco capas de seguridad distintas diseñadas para evitar que el código no fiable salga del entorno aislado.
Nivel 1: Sobrescritura del contexto global
Antes de evaluar cualquier expresión, n8n crea un contexto de ejecución restringido sobrescribiendo los objetos y funciones globales peligrosos. Propiedades como document, window, globalThis, eval, setTimeout, setInterval y Function se sustituyen por objetos vacíos, lo que impide el acceso directo a estas funciones.


Este enfoque tiene una limitación inherente: si un atacante logra escapar del contexto restringido y acceder al objeto de proceso global real, las propiedades sobrescritas pierden toda relevancia.
Capa 2: validación mediante expresiones regulares
Antes de que la expresión llegue al evaluador, n8n aplica una comprobación de expresiones regulares a la cadena de la expresión sin procesar para bloquear el acceso a la propiedad del constructor, una vía habitual para obtener el constructor de la función y lograr la ejecución del código.

La expresión regular /\.\s*constructor/gm detecta el acceso mediante notación de puntos a .constructor. Sin embargo, esta comprobación tiene una limitación fundamental, ya que JavaScript ofrece múltiples formas sintácticas de acceder a la misma propiedad, y no todas ellas utilizan la notación de puntos.
Capa 3 - Sanitizador de tiempo de ejecución de AST – PrototypeSanitizer
La defensa más sofisticada se activa durante la construcción del AST. El gancho PrototypeSanitizer recorre el AST e inspecciona los nodos MemberExpression para determinar si la propiedad a la que se accede figura en una lista de propiedades de objetos no seguras, entre las que se incluyen constructor, __proto__, prototype, mainModule y binding.

El sanitizador gestiona tres casos: la notación de puntos (obj.prop), en la que comprueba el nombre del identificador; la notación de corchetes estática (obj['prop']), en la que comprueba el valor de la cadena literal; y las expresiones dinámicas, que se envuelven en una función de sanitización en tiempo de ejecución. Como se muestra en la figura 10, solo se inspeccionan los nodos MemberExpression; los patrones de desestructuración no se recorren.
Capa 4 - Función de saneamiento en tiempo de ejecución de AST: ThisSanitizer
Añadido como parche directo para CVE-2025-68613, FunctionThisSanitizer intercepta las expresiones de función de invocación inmediata (IIFE) y las reescribe para vincular «this» a un objeto vacío. Esto evita la técnica utilizada en el exploit original, en la que (function(){ return this })() provocaba una fuga del objeto global del proceso a través de la referencia «this» sin vincular.

Es importante destacar que este sanitizador solo admite nodos FunctionExpression. Se detiene explícitamente de forma anticipada ante cualquier objeto llamado que no sea un FunctionExpression, incluidas las funciones flecha.
Las propiedades peligrosas, como `eval`, `Function` y `process.mainModule`, se eliminan o se sobrescriben en el contexto de ejecución, lo que impide el acceso directo a las primitivas de ejecución de código, incluso si se eluden las capas anteriores.
Análisis de vulnerabilidades
Causa principal
La causa principal de CVE-2026-25049 radica en una suposición común a las cinco capas de seguridad: todas ellas partían de la base de que el acceso a las propiedades se produciría mediante la notación de puntos (obj.constructor) o la notación entre corchetes (obj['constructor']). Ninguna de ellas tuvo en cuenta la sintaxis de desestructuración de JavaScript.
La desestructuración en JavaScript permite extraer propiedades de los objetos utilizando una estructura AST fundamentalmente diferente:
// Traditional access - produces MemberExpression node
obj.constructor; // Blocked by regex, AST sanitizer, and runtime checks
// Destructuring - produces ObjectPattern → Property node
const { constructor } = obj; // Not checked by any layerAunque ambos patrones logran el mismo resultado, generan representaciones AST totalmente diferentes. El PrototypeSanitizer solo inspecciona los nodos MemberExpression, y la expresión regular solo coincide con los patrones .constructor. Las asignaciones de desestructuración crean nodos VariableDeclaration → ObjectPattern → Property, que ninguno de los sanitizadores recorre.
A esto se suma el tratamiento que n8n da a las funciones flecha. El FunctionThisSanitizer solo intercepta los nodos FunctionExpression y los reescribe para vincular «this» a un contexto seguro. Las funciones flecha generan nodos AST de tipo ArrowFunctionExpression, que el sanitizador no procesa. Dado que las funciones flecha heredan «this» del ámbito que las rodea (el «this» léxico), permiten acceder al contexto global sin sanitizar.
En conjunto, estos dos descuidos dan lugar a un bypass total: la desestructuración extrae el constructor de la función sin activar ninguna comprobación de acceso a las propiedades, y las funciones flecha proporcionan un contexto de ejecución que FunctionThisSanitizer no intercepta.
Explotación
El exploit combina ambas vulnerabilidades para burlar todas las capas de seguridad al mismo tiempo. Nuestros compañeros han identificado la siguiente ruta de explotación:
Paso 1: Introducción a las funciones flecha. La carga útil comienza con una función flecha envuelta en una expresión de función de invocación inmediata (IIFE):
={{(() => {
// Función flecha: evita el uso de FunctionThisSanitizer
...
})()}}
La función `FunctionThisSanitizer` comprueba si el objeto al que se llama es una `FunctionExpression`; dado que se trata de una `ArrowFunctionExpression`, el sanitizador sale prematuramente sin reescribir la llamada. La función flecha se ejecuta con acceso total al contexto global real.
Paso 2: Omisión de la desestructuración. Dentro de la función flecha, la desestructuración extrae el constructor `Function` de una instancia de función flecha:
const { constructor } = () => {};
Dado que se trata de una asignación de desestructuración, el AST contiene un nodo `ObjectPattern` en lugar de un `MemberExpression`. La comprobación mediante expresiones regulares no detecta ningún patrón `.constructor`, y el `PrototypeSanitizer` nunca inspecciona el nombre de la propiedad. El atacante dispone ahora de una referencia al constructor `Function`.
Paso 3: Ejecución dinámica de código. Una vez obtenido el constructor de la función, el atacante crea y ejecuta código arbitrario:
return constructor(
'return process.mainModule.require("child_process").execSync("whoami").toString()',
);
La función construida dinámicamente se ejecuta fuera del contexto del entorno aislado y tiene acceso completo al objeto de proceso de Node.js, lo que permite la ejecución de comandos arbitrarios del sistema en el host.

Prueba de concepto
Para demostrar el impacto real de esta vulnerabilidad, nuestros becarios reprodujeron el exploit en un entorno de laboratorio controlado. El escenario del ataque consiste en alojar una instancia vulnerable de n8n e importar un flujo de trabajo que contenga la carga maliciosa dentro de un parámetro de nodo, dirigiéndose específicamente al nodo «Edit Fields», que permite la evaluación de expresiones.

Una vez que se activa el flujo de trabajo, la carga útil elude las cinco capas de saneamiento y ejecuta un shell inverso en el servidor de destino, lo que devuelve al atacante la capacidad total de ejecutar comandos.

Escalada de webhook a ejecución remota de código sin autenticación
La gravedad de esta vulnerabilidad aumenta considerablemente cuando se combina con la funcionalidad de webhooks de n8n. n8n permite que los flujos de trabajo expongan puntos finales HTTP como webhooks con opciones de autenticación configurables, entre las que se incluyen tokens de portador, autenticación básica y —lo que es más grave— ninguna autenticación. Un atacante con acceso para crear flujos de trabajo puede configurar un webhook público con la autenticación «none», incrustar la carga útil de RCE en un nodo conectado y activar el flujo de trabajo. En ese momento, cualquier solicitud HTTP a la URL del webhook —desde cualquier lugar de Internet— desencadena la ejecución de comandos arbitrarios en el servidor host.
Esta vía de escalada convierte la vulnerabilidad CVE-2026-25049, que en un principio era una vulnerabilidad interna que requería autenticación, en un vector de ataque que, en la práctica, no requiere autenticación y que queda expuesto a toda la red.
Mitigación
El equipo de n8n ha solucionado la vulnerabilidad CVE-2026-25049 en las versiones 1.123.17 y 2.5.2 mediante la implementación de una comprobación de tipos en tiempo de ejecución adecuada en las funciones de saneamiento y la ampliación de la cobertura del árbol de sintaxis abstracta (AST) para gestionar los patrones de desestructuración. Las organizaciones que utilicen las versiones afectadas deben actualizar el software de inmediato.
Si no es posible realizar una actualización inmediata, los administradores deben limitar los permisos de creación y edición de flujos de trabajo únicamente a los usuarios de plena confianza e implementar n8n en un entorno reforzado con privilegios restringidos del sistema operativo y acceso limitado a la red.
Dada la gravedad crítica y la facilidad con la que se puede explotar esta vulnerabilidad —especialmente cuando se combina con webhooks públicos—, las organizaciones también deberían auditar los flujos de trabajo existentes en busca de expresiones sospechosas, supervisar la ejecución anómala de comandos del sistema procedentes del proceso n8n y revisar las configuraciones de los webhooks para detectar cualquier punto de acceso expuesto sin autenticación.
Mitigación con OPSWAT
Al aprovechar OPSWAT , las organizaciones pueden identificar rápidamente los componentes n8n vulnerables dentro de su infraestructura y tomar medidas antes de que se produzca un ataque. OPSWAT , una tecnología fundamental de la plataforma MetaDefender®, ofrece un inventario completo de todos los componentes de software, bibliotecas y dependencias que se utilizan en el entorno de una organización.

Como se muestra en la figura 15, MetaDefender analizó el archivo package.json que contiene la dependencia n8n y marcó automáticamente la vulnerabilidad CVE-2026-25049 como «Crítica», mostrando el rango de versiones afectadas y las versiones corregidas recomendadas para su corrección. Esto permite a los equipos de seguridad identificar y priorizar rápidamente la vulnerabilidad en todo su entorno de implementación.
OPSWAT está disponible en MetaDefender y MetaDefender Software Chain™, lo que permite a los equipos de seguridad:
- Localice rápidamente los componentes vulnerables: identifique de inmediato las dependencias de código abierto afectadas por vulnerabilidades de escape del entorno aislado y de ejecución de código, lo que permite su rápida corrección o eliminación.
- Garantizar la aplicación proactiva de parches y actualizaciones: supervisar continuamente los componentes de código abierto para detectar paquetes obsoletos o inseguros, lo que permite realizar actualizaciones oportunas y reducir la exposición a riesgos.
- Garantizar el cumplimiento normativo y la presentación de informes: cumplir con los requisitos normativos, ya que los marcos reguladores exigen cada vez más transparencia en las cadenas de suministro de software.
Referencias
- NVD - CVE-2026-25049
- Aviso de seguridad de n8n - GHSA-6cqr-8cfr-67f8
- n8n RCE(s): Una historia en cuatro actos - Fatih Çelik
- Análisis en profundidad de CVE-2026-25049 - SecureLayer7
- CVE-2026-25049: Vulnerabilidad de escape de expresiones que permite la ejecución remota de código en n8n - Endor Labs
- Aviso de seguridad de n8n - CVE-2025-68613 (GHSA-v98v-ff95-f3cp)
