Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-69264 — flowise

🔴 CVSS 9.5 — Critical ✅ No Known Exploit CWE-94 NVD
9.5
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Flowise: RCE via CSVAgent csvFile data URI base64 segment is interpolated into Python source without validation

Summary

Flowise's CSVAgent interpolates an attacker-controlled segment of the

csvFile data URI directly into a Python source-code template that is then

executed by Pyodide. Because Pyodide is loaded with the default js bridge

to globalThis (which on Node.js exposes eval and dynamic import()), the

attacker can break out of the Python string literal, hand a JS string to

js.eval, dynamically import any Node built-in module (fs, child_process,

…), and execute arbitrary file I/O or OS commands as the Flowise process.

The two validator paths around this code (validatePythonCodeForDataFrame

and validateCustomReadCSVFunction) are never applied to the bootstrap

template.

A workspace user with chatflows:create (or any agentflows/chatflows

update permission) plants a CSV Agent node with a crafted csvFile. Once the

chatflow is exposed via the (whitelisted, public) POST /api/v1/prediction/:id

endpoint, *any unauthenticated* request triggers the host RCE.

Details

Vulnerable file: packages/components/nodes/agents/CSVAgent/CSVAgent.ts

The run() method extracts the file segment from the data URI by splitting on

, and using two pop() calls (lines 127–138):

```ts

} else {

if (csvFileBase64.startsWith('[') && csvFileBase64.endsWith(']')) {

files = JSON.parse(csvFileBase64)

} else {

files = [csvFileBase64]

}

for (const file of files) {

if (!file) continue

const splitDataURI = file.split(',')

splitDataURI.pop() // discards trailing filename segment

base64String += splitDataURI.pop() ?? '' // captures the segment we attack

}

}

```

The captured base64String is then interpolated verbatim into a Python

source string at lines 156–171:

```ts

const code = `import pandas as pd

import base64

from io import StringIO

import json

base64_string = "${base64String}" // ← line 161: interpolation sink

decoded_data = base64.b64decode(base64_string)

csv_data = StringIO(decoded_data.decode('utf-8'))

df = pd.${customReadCSVFunc}

my_dict = df.dtypes.astype(str).to_dict()

print(my_dict)

json.dumps(my_dict)`

dataframeColDict = await pyodide.runPythonAsync(code) // ← line 171: sink

```

Validator gaps:

  • validateCustomReadCSVFunction(customReadCSVFunc) runs on line 147, but

this only validates the customReadCSV field, not base64String.

  • validatePythonCodeForDataFrame(pythonCode) runs on line 198, but only

against the *LLM-emitted* Python that runs later — never against this

bootstrap template.

  • No content check (^[A-Za-z0-9+/=]*$) is applied to base64String before

interpolation.

Pyodide configuration (packages/components/nodes/agents/CSVAgent/core.ts,

lines 7–16):

```ts

export async function LoadPyodide(): Promise<PyodideInterface> {

if (pyodideInstance === undefined) {

const { loadPyodide } = await import('pyodide')

const obj: any = { packageCacheDir: path.join(getUserHome(), '.flowise', 'pyodideCacheDir') }

pyodideInstance = await loadPyodide(obj)

await pyodideInstance.loadPackage(['pandas', 'numpy'])

}

return pyodideInstance

}

```

Pyodide is loaded with default options. On Node.js, the default js module

inside Pyodide bridges to globalThis, exposing the JS eval function and

top-level dynamic import(). From injected Python, the attacker runs:

```python

import js

await js.eval(

"(async () => {"

" const fs = await import('fs');"

" fs.writeFileSync('proof.txt', 'pwned');"

"})()"

)

```

…which executes in the host Node.js process, not inside Pyodide's WASM

sandbox. Substituting await import('child_process') for await import('fs')

yields arbitrary OS-command execution via cp.execSync(...) with the same

primitive.

> Node-version note. The original PoC for this issue used

> js.process.mainModule.require("child_process"), which is a one-liner but

> only works on Node ≤ 13 because process.mainModule was deprecated and now

> returns undefined on Node 14+. The js.eval + dynamic-import() form

> above works on any Node 13.2+ in both CommonJS and ESM contexts, and was

> confirmed end-to-end against a stock [email protected] running on Node

> 20.20.2 — see [Verified end-to-end against live Flowise](#verified-end-to-end-against-live-flowise)

> below.

Trigger path (post-plant): the route POST /api/v1/prediction/:id is in

WHITELIST_URLS (packages/server/src/utils/constants.ts:12); when the

chatflow has no apikeyid set, it is reachable unauthenticated. A prediction

request runs the chatflow, instantiates CSVAgent, and executes the malicious

bootstrap.

PoC

Verified end-to-end on the cloned repo (commit

a3ffe6611b0986d646b9cd8bb8787d4fdcf9be6d, the same commit the prior audit

was based on).

Reproducer setup

Two files. Save the first

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. Rated impact: confidentiality high, integrity high, availability high.

CVSS metrics in full

The score comes from this vector: 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

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Attack requirements: None — no deployment-specific condition has to hold.
  • Privileges required: Low — an ordinary user account is enough.
  • User interaction: None — nobody has to be tricked into anything.
  • Confidentiality impact: High — total loss, or loss the attacker controls.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: High — total loss, or loss the attacker controls.

Weakness class

CVE-2026-69264 is classified as CWE-94: Code Injection. Input is incorporated into code that the runtime evaluates, so an attacker can have their own code executed.

Affected software

CVE-2026-69264 is recorded against 3 packages.

  • flowise
  • flowise-components
  • unknown

Timeline and source

Published on 4 August 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
github.com (Web)
github.com (Web)
github.com (Package)
github.com (Web)

Other advisories for this package

flowise has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-94: Code Injection) in other software:

Details

Severity CRITICAL
CVSS Score 9.5
CVSS Vector 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
CWE CWE-94
Public Exploit ✅ No
Source NVD
Published 2026-08-04
Updated 2026-08-20
Modified 2026-08-04
Fix URL N/A

Affected Packages

Software From version Fixed in
flowise
flowise-components
unknown

Similar Threats

Exploit Protection

Are you running flowise?

CVE-2026-69264 carries CVSS 9.5 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2026-69264 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026