Résumé
Flowise Sandbox Escape to RCE
Détails de l’avis
============================================================================= Security Advisory elttam
Topic: Flowise JavaScript Sandbox Escape
Module: FlowiseAI/Flowise, FlowiseAI/nodevm
Disclosed: 11-Apr-2026
Credits: Luke Jahnke and Alex Brown
Affects: FlowiseAI/Flowise 3.1.1, FlowiseAI/nodevm 3.9.25
I. Background
Flowise AI is an open-source, low-code platform for building AI applications—such as chatbots, workflows, and autonomous agents—through an intuitive drag-and-drop interface, minimising the need for extensive coding.
The platform also enables execution of custom JavaScript within a sandboxed environment via the Custom Function Agent Flow node or Custom Tool. By default, this sandbox is powered by patriksimek/vm2, a fork of the patriksimek/vm2 package.
II. Problem Description
NOTE: This vulnerability still impacts commit dddfb3c90eec900d747790a439bd362a764039cd (the latest commit on the main branch at the time of writing). The original report was incorrectly closed, due to a misunderstanding that the report was about the use of an outdated and vulnerable version of the patriksimek/vm2 sandbox. The sandbox escape that this report documents is an issue with Flowise, and patching the vm2 sandbox would not resolve it.
The patriksimek/vm2 sandbox executes JavaScript within the same Node.js process, which introduces significant security limitations and makes safely isolating untrusted code inherently difficult. Due to these concerns, the maintainers had deprecated the project and previously issued the following warning:
The library contains critical security issues and should not be used in production. Maintenance has been discontinued. Consider migrating to
isolated-vm.
To demonstrate the risks associated with the use of the vm2 sandbox, a sandbox escape specific to Flowise was investigated. The code snippet below shows the allowed modules that could be used within custom JavaScript code on Flowise.
https://github.com/FlowiseAI/Flowise/blob/flowise%403.1.1/packages/components/src/utils.ts#L124
const defaultAllowExternalDependencies = ['axios', 'moment', 'node-fetch'] <1>
<1> Allows custom JavaScript code to use the axios, moment and node-fetch dependencies.
Notably, the moment dependency had a previously reported path traversal vulnerability (CVE-2022-24785) that could lead to RCE when user input is passed to the locale function. The patch for CVE-2022-24785 was implementing regex check to disallow / or \ characters within a locale name, as shown in the code snippet below.
Patch for CVE-2022-24785 in moment (https://github.com/moment/moment/commit/4211bfc8f15746be4019bba557e29a7ba83d54c5)
function isLocaleNameSane(name) {
// Prevent names that look like filesystem paths, i.e contain '/' or '\'
return name.match('^[^/\\\\]*#39;) != null; <1>
}
function loadLocale(name) {
var oldLocale = null,
aliasedRequire;
// TODO: Find a better way to register and load all the locales in Node
if (
locales[name] === undefined &&
typeof module !== 'undefined' &&
module &&
module.exports &&
isLocaleNameSane(name) <1>
) {
try {
oldLocale = globalLocale._abbr;
aliasedRequire = require;
aliasedRequire('./locale/' + name); <2>
getSetGlobalLocale(oldLocale);
} catch (e) {
// mark as not found to avoid repeating expensive file require call causing high CPU
// when trying to find en-US, en_US, en-us for every format call
locales[name] = null; // null means not found
}
}
return locales[name];
}
<1> Performs a regex check to disallow / or \ characters within the provided locale name.
<2> The vulnerable sink that introduced CVE-2022-24785.
Flowise used moment version v2.29.3, which had the CVE-2022-24785 patch applied. However, the patch is ineffective in preventing directory traversal in a sandbox context. The validation function uses the match function from the provided object, so an object with a match function that always returns true would bypass the validation check, as shown in the following proof-of-concept script.
fake = new String("../../../../../../../../../../../../../../../etc/passwd");
fake.match = function(regexp){return true;}; <1>
require("moment").locale(fake);
<1> Bypasses the validation check for CVE-2022-24785.
In commit e765367fdc9761a7d9cf01a048cac15c78903b85 (https://github.com/FlowiseAI/Flowise/commit/e765367fdc9761a7d9cf01a048cac15c78903b85), the default sandbox was changed to the E2B sandbox, as shown in the code snippet below.
export const executeJavaScriptCode = async (
code: string,
sandbox: ICommonObject,
options: {
timeout?: number
useSandbox?: boolean
libraries?: string[]
streamOutput?: (output: string) => void
nodeVMOptions?: ICommonObject
} = {}
): Promise<any> => {
const { timeout = 300000, useSandbox = true, streamOutput, libraries = [], nodeVMOptions = {} } = options <1>
if (useSandbox && !process.env.E2B_APIKEY) { <1>
throw new Error(
'Sandboxed code execution requires E2B_APIKEY to be configured. ' +
'Set E2B_APIKEY in your environment or contact your administrator.'
)
}
let timeoutMs = timeout
if (process.env.SANDBOX_TIMEOUT) {
timeoutMs = parseInt(process.env.SANDBOX_TIMEOUT, 10)
}
...
<1> The default was changed to use the E2B sandbox.
However, there are several components within the application that still use the insecure vm2 sandbox, as shown in the following grep output.
$ grep -r 'useSandbox: false'
packages/components/nodes/tools/AgentAsTool/AgentAsTool.ts: useSandbox: false
packages/components/nodes/tools/ChatflowTool/ChatflowTool.ts: useSandbox: false
packages/components/nodes/sequentialagents/ExecuteFlow/ExecuteFlow.ts: useSandbox: false
The above files also contain an injection vulnerability into the sandboxed code, due to an improper URL validation check validating the baseURL input. The following code snippets demonstrate the injection vulnerability within AgentAsTool.ts and the broken isValidURL validation function.
class AgentAsTool_Tools implements INode {
...
async init(nodeData: INodeData, input: string, options: ICommonObject): Promise<any> {
...
const baseURL = (nodeData.inputs?.baseURL as string) || (options.baseURL as string)
// Validate agentflowid is a valid UUID
if (!selectedAgentflowId || !isValidUUID(selectedAgentflowId)) {
throw new Error('Invalid agentflow ID: must be a valid UUID')
}
// Validate baseURL is a valid URL
if (!baseURL || !isValidURL(baseURL)) { <1>
throw new Error('Invalid base URL: must be a valid URL')
}
...
}
}
class AgentflowTool extends StructuredTool {
...
// @ts-ignore
protected async _call(
arg: z.infer<typeof this.schema>,
_?: CallbackManagerForToolRun,
flowConfig?: { sessionId?: string; chatId?: string; input?: string }
): Promise<string> {
...
const code = `
const fetch = require('node-fetch');
const url = "${this.baseURL}/api/v1/prediction/${this.agentflowid}"; <2>
const body = $callBody;
const options = $callOptions;
try {
const re
Références
- https://github.com/advisories/GHSA-wg86-r78f-74mp
- https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wg86-r78f-74mp
- https://github.com/FlowiseAI/Flowise/pull/6417
- https://github.com/FlowiseAI/Flowise/commit/3f257bdc8196082a178da7134a075824401b13b9
- https://github.com/FlowiseAI/Flowise/releases/tag/flowise@3.1.3
Vulnérabilités liées
Tout Supply chain →- CRITICALCVE-2026-71867
Orval: RCE via schema property name -> computed-property-key injection in the MSW mock generator
- CRITICALCVE-2026-71865
Orval: Import-time RCE via query parameter name -> computed-property-key injection in the zod cli
- CRITICALCVE-2026-71864
Orval: Import-time RCE via header parameter name -> computed-property-key injection in the zod client
- CRITICALCVE-2026-71866
Orval: Import-time RCE via schema property name -> computed-property-key injection in the zod client
- HIGHCVE-2026-73231
Faker: helpers.fake exploitable into arbritary code execution
- CRITICALCVE-2026-54569
senaite.core Vulnerable to Eval Injection and Missing Authorization