CVE-2026-70470critical
CVE-2026-70470: Flowise Critical RCE Flaw Patched
A Unicode homoglyph bypass in Flowise allows attackers to execute arbitrary code on host systems by tricking the Python code validation engine.
Vendor / Productnpm/flowise, npm/flowise-components
Affected Versionsnpm/flowise (before 3.1.3), npm/flowise-components (before 3.1.3)
Fixed In3.1.3
Advertisement
What This Means
Advisory ID: GHSA-52fh-8v99-63c2 (CVE-2026-70470)
Summary: Flowise: Pyodide validator Unicode homoglyph bypass leads to RCE
Severity: critical
Affected packages: npm/flowise (patched in 3.1.3), npm/flowise-components (patched in 3.1.3)
Details: ### Summary
The validatePythonCodeForDataFrame blacklist in packages/components/src/pythonCodeValidator.ts can be bypassed with Unicode homoglyph identifiers, allowing arbitrary Python execution inside Pyodide and full OS command execution on the Flowise host via Pyodide's js module interop. This reopens the RCE paths patched as GHSA-3hjv-c53m-58jj (CSV Agent) and GHSA-v38x-c887-992f (Airtable Agent).
### Details
packages/components/src/pythonCodeValidator.ts gates every call to pyodide.runPythonAsync in packages/components/nodes/agents/CSVAgent/CSVAgent.ts (lines 147, 198) and packages/components/nodes/agents/AirtableAgent/AirtableAgent.ts (line 186). The gate is a regex blacklist:
```ts
{ pattern: /\bimport\b/g, ... },
{ pattern: /\b__class__\b/g, ... },
{ pattern: /\b__subclasses__\s*\(/g, ... },
{ pattern: /\b__builtins__\b/g, ... },
{ pattern: /\b__mro__\b/g, ... },
// ... about 30 similar rules
```
Two design flaws combine into a bypass:
1. JavaScript regex `\b` is ASCII-only. Word boundaries are computed against the ASCII word class `[A-Za-z0-9_]`. A Unicode letter such as U+1D41A (mathematical bold small a) is treated as a non-word character, so `\b__class__\b` never matches `__cl𝐚ss__`.
2. Python 3 (PEP 3131) NFKC-normalizes every identifier at parse time. `__cl𝐚ss__`, `__subcl𝐚sses__`, `__b𝐚se__`, `__b𝐮iltins__`, and similar homoglyph forms are all parsed as their ASCII equivalents.
Attribute access `obj.__cl𝐚ss__` is normalized because attribute names are identifiers. Dict string keys such as `bi['__import__']` are not normalized, but they are free text and can be assembled with `chr()` to avoid literal matches on patterns like `\bimport\b` or `\b__import__\s*\(/`.
From inside Pyodide, `__builtins__['__import__']('js')` yields the JS host bridge. In the Node.js host that runs Flowise, that bridge exposes `process.mainModule.require('child_process').execSync`, which runs native commands on the host with the privileges of the Flowise process.
AHow to Fix It
- Upgrade to version 3.1.3 or later
- Restrict network access to the Flowise interface
- Run the service with the least privilege necessary
- Monitor logs for suspicious process activity
Source
Last updated August 4, 2026 UTC