Skip to content
FlowiseGHSA-x6vm-w76m-8j7g

Flowise: Remote Code Execution Vulnerability in CSVAgent

CriticalCVE-2026-69256 · Published Aug 4, 2026

GitHub advisory

Affected versions

PackageAffectedFixed in
flowise
npm
< 3.1.33.1.3
Details and references

### Summary The CSVAgent node was observed to allow users to write Python code which gets executed via `pyodide`. The original intent was to allow users to utilise the `pandas` library for CSV processing. Although there is a denylist that checks for dangerous Python constructs from being passed in, `pandas` has a `read_pickle()` [function](https://pandas.pydata.org/docs/reference/api/pandas.read_pickle.html) that deserialises a pickled payload and this can be leveraged to achieve code execution. ### Details The affected file is the `CSVAgent` node, found in: `flowise-components/nodes/agents/CSVAgent/CSVAgent.ts`. ```js try { const code = `import pandas as pd import base64 from io import StringIO import json base64_string = "${base64String}" decoded_data = base64.b64decode(base64_string) csv_data = StringIO(decoded_data.decode('utf-8')) df = pd.${customReadCSVFunc} <1> my_dict = df.dtypes.astype(str).to_dict() print(my_dict) json.dumps(my_dict)` dataframeColDict = await pyodide.runPythonAsync(code) } catch (error) { throw new Error(error) } ``` At <1>, the `customReadCSVFunc` is supplied by the user. This input goes through input validation that denies dangerous Python constructs from being passed in: ```py const FORBIDDEN_PATTERNS: Array<{ pattern: RegExp; reason: string }> = [ // Imports (the executor pre-imports pandas and numpy; LLM code must not add any imports) { pattern: /\bfrom\s+\S+\s+import\b/g, reason: 'import statement (from...import)' }, { pattern: /\bimport\b/g, reason: 'import statement (all imports forbidden; pandas and numpy are pre-imported by the executor)' }, // Dangerous builtins { pattern: /\beval\s*\(/g, reason: 'eval()' }, { pattern: /\bexec\s*\(/g, reason: 'exec()' }, { pattern: /\bcompile\s*\(/g, reason: 'compile()' }, { pattern: /\b__import__\s*\(/g, reason: '__import__()' }, { pattern: /\bopen\s*\(/g, reason: 'open()' }, { pattern: /\bbreakpoint\s*\(/g, reason: 'breakpoint()' }, { pattern: /\binput\s*\(/g, reason: 'input()' }, { pattern: /\braw_input\s*\(/g, reason: 'raw_input()' }, { pattern: /\bglobals\s*\(/g, reason: 'globals()' }, { pattern: /\blocals\s*\(/g, reason: 'locals()' }, { pattern: /\bgetattr\s*\(/g, reason: 'getattr()' }, { pattern: /\bsetattr\s*\(/g, reason: 'setattr()' }, { pattern: /\bdelattr\s*\(/g, reason: 'delattr()' }, { pattern: /\breload\s*\(/g, reason: 'reload()' }, { pattern: /\bfile\s*\(/g, reason: 'file()' }, { pattern: /\bexecfile\s*\(/g, reason: 'execfile()' }, // Dangerous modules / attributes { pattern: /\bos\./g, reason: 'os module' }, { pattern: /\bsubprocess\./g, reason: 'subprocess module' }, { pattern: /\bsys\./g, reason: 'sys module' }, { pattern: /\bsocket\./g, reason: 'socket module' }, { pattern: /\burllib\./g, reason: 'urllib module' }, { pattern: /\brequests\./g, reason: 'requests module' }, { pattern: /\b__builtins__\b/g, reason: '__builtins__' }, { pattern: /\b__loader__\b/g, reason: '__loader__' }, { pattern: /\b__spec__\b/g, reason: '__spec__' }, { pattern: /\b__class__\b/g, reason: '__class__ (reflection)' }, { pattern: /\b__subclasses__\s*\(/g, reason: '__subclasses__()' }, { pattern: /\b__bases__\b/g, reason: '__bases__' }, { pattern: /\b__mro__\b/g, reason: '__mro__' }, { pattern: /\b__globals__\b/g, reason: '__globals__' }, { pattern: /\b__code__\b/g, reason: '__code__' }, { pattern: /\b__closure__\b/g, reason: '__closure__' }, { pattern: /\bvars\s*\(/g, reason: 'vars()' }, { pattern: /\bdir\s*\(/g, reason: 'dir()' }, { pattern: /\b__dict__\b/g, reason: '__dict__ (attribute reflection)' }, { pattern: /\b__module__\b/g, reason: '__module__ (module reflection)' } ] ``` However, by using `pandas.read_pickle()`, an attacker can achieve code execution without hitting any of the denied words. ### PoC First, generate a pickled payload that performs an OS command (replace

CVSS 4.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Severity from
GitHub (reviewed advisory)
Weakness
CWE-94
Also known as
CVE-2026-69256

More Flowise advisories

All Flowise
DateAdvisory
Aug 4Flowise: IDOR vulnerability exists at the GET /api/v1/organization/customer-default-source endpoint
CVE-2026-73488Mediumfixed in 3.1.3
Aug 4Flowise: Unauthenticated OAuth2 Refresh Enables Non-Blind SSRF and Secret Exfiltration
CVE-2026-69250Highfixed in 3.1.3
Aug 4Flowise RCE via TypeORM DataSource
CVE-2026-69251Criticalfixed in 3.1.3
Aug 4Flowise: Missing authorization on `/api/v1/files` allows low-privileged API keys to list and delete files across workspaces within the same organization
CVE-2026-69252Highfixed in 3.1.3
Aug 4Flowise Sandbox Escape to RCE
CVE-2026-69253Criticalfixed in 3.1.3
Aug 4Flowise: RCE via NodeVM Sandbox Escape in executeJavaScriptCode() nodeVMOptions Override
CVE-2026-69254Criticalfixed in 3.1.3

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.