CVE-2026-73487
Prompt Injection to RCE and SSRF via Python Validator Bypass
01Record
| Identifier | CVE-2026-73487 |
|---|---|
| Project | Flowise |
| Component | pythonCodeValidator.ts |
| CWE | CWE-94 |
| CVSS | 9.3 |
| Disclosed | 2026-07-29 |
| Endor reference | ENDOR-VUL-2026-1704 |
| Writeup | Link |
02Detail
Description: Flowise's CSV Agent and Airtable Agent nodes ask an LLM to write Python that operates on a pandas DataFrame, then execute it in Pyodide. The only control in front of eval is validatePythonCodeForDataFrame() in packages/components/src/pythonCodeValidator.ts, a 38-pattern regex blocklist over source text. The executor pre-imports pandas and numpy, so generated code never needs to write import at all, and the word-boundary in \bimport\b does not match importlib. Six independent bypasses passed the validator; the one that was blocked, import os, was the control case.
The payload keeps dangerous names as data until evaluation. bk and ik assemble __builtins__ and __import__ from character codes, so neither literal appears in the source and /\b__builtins__\b/ and /\b__import__\s*\(/ have nothing to match. object.__getattribute__(pd.core.dtypes.cast, bk) is the pivot: every module object carries a __builtins__ reference, and pd.core.dtypes.cast matches no pattern in the file. Pyodide's js bridge then reaches Node's own scope, which yields process.mainModule.require('child_process') and execSync, and the agent's dataset leaves through the same bridge in the query string of a _js.fetch().
The whole chain is one POST /api/v1/prediction/<uuid> with no credential and no account: configuring Flowise auth does not cover the prediction path, because that path sits on the server's whitelist. Affects flowise and flowise-components through 3.1.2.
Impact: Unauthenticated Code Execution, SSRF, and dataset exfiltration.
The CSV Agent, the Airtable Agent, and pythonCodeValidator.ts were removed in 3.1.3 rather than repaired. Upgrading stopped being the answer shortly afterwards: development ceased on 2026-07-29 and the repository was archived on 2026-08-10, so a running deployment is unmaintained software holding cloud credentials. Supersedes GHSA-3hjv-c53m-58jj (ZDI-CAN-29411), the earlier validator bypass via import aliasing fixed in 3.1.0. Full analysis is in the technical whitepaper.
Discovered by Peyton Kennedy (p80n).