CVE-2025-71333
Flowise - Arbitrary File Upload via Unauthenticated /api/v1/attachments Endpoint
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api/v1/attachments endpoint when storageType is set to local. Attackers can exploit path traversal in the chatId and chatflowId parameters to upload malicious files to arbitrary directories, potentially enabling remote code execution and server compromise.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
9.3
Flowise - Arbitrary File Upload via Unauthenticated /api/v1/attachments Endpoint
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api/v1/attachments endpoint when storageType is set to local. Attackers can exploit path traversal in the chatId and chatflowId parameters to upload malicious files to arbitrary directories, potentially enabling remote code execution and server compromise.
- Record
CVE-2025-71333- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-73
- Updated
- 2026-11-02
EUVDEUVD-2025-210339
9.3
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api/v1/attachments endpoint when storageType is set to local. Attackers can exploit path traversal in the chatId and chatflowId parameters to upload malicious files to arbitrary directories, potentially enabling remote code execution and server compromise.
- Record
EUVD-2025-210339- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-grch-cc26-w2fv
9.3
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api...
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api/v1/attachments endpoint when storageType is set to local. Attackers can exploit path traversal in the chatId and chatflowId parameters to upload malicious files to arbitrary directories, potentially enabling remote code execution and server compromise.
- Record
GHSA-grch-cc26-w2fv- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-73
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-h42x-xx2q-6v6g
9.3
Flowise Pre-auth Arbitrary File Upload
Summary
An unauthorized attacker can leverage the whitelisted route /api/v1/attachments to upload arbitrary files when the storageType is set to local (default).
Details
When a new request arrives, the system first checks if the URL starts with /api/v1/. If it does, the system then verifies whether the URL is included in the whitelist (whitelistURLs). If the URL is whitelisted, the request proceeds; otherwise, the system enforces authentication.
@ /packages/server/src/index.ts
this.app.use(async (req, res, next) => {
// Step 1: Check if the req path contains /api/v1 regardless of case
if (URL_CASE_INSENSITIVE_REGEX.test(req.path)) {
// Step 2: Check if the req path is case sensitive
if (URL_CASE_SENSITIVE_REGEX.test(req.path)) {
// Step 3: Check if the req path is in the whitelist
const isWhitelisted = whitelistURLs.some((url) => req.path.startsWith(url))
if (isWhitelisted) {
next()
} else if (req.headers['x-request-from'] === 'internal') {
basicAuthMiddleware(req, res, next)
} else {
const isKeyValidated = await validateAPIKey(req)
if (!isKeyValidated) {
return res.status(401).json({ error: 'Unauthorized Access' })
}
next()
}
} else {
return res.status(401).json({ error: 'Unauthorized Access' })
}
} else {
// If the req path does not contain /api/v1, then allow the request to pass through, example: /assets, /canvas
next()
}
}
The whitelist is defined as follows
export const WHITELIST_URLS = [
'/api/v1/verify/apikey/',
'/api/v1/chatflows/apikey/',
'/api/v1/public-chatflows',
'/api/v1/public-chatbotConfig',
'/api/v1/prediction/',
'/api/v1/vector/upsert/',
'/api/v1/node-icon/',
'/api/v1/components-credentials-icon/',
'/api/v1/chatflows-streaming',
'/api/v1/chatflows-uploads',
'/api/v1/openai-assistants-file/download',
'/api/v1/feedback',
'/api/v1/leads',
'/api/v1/get-upload-file',
'/api/v1/ip',
'/api/v1/ping',
'/api/v1/version',
'/api/v1/attachments',
'/api/v1/metrics'
]
This means that every route in the whitelist does not require authentication. Now, let's examine the /api/v1/attachments route.
@ /packages/server/src/routes/attachments/index.ts
const router = express.Router()
// CREATE
router.post('/:chatflowId/:chatId', getMulterStorage().array('files'), attachmentsController.createAttachment)
export default router
After several calls, the request reaches the createFileAttachment function @ (packages/server/src/utils/createAttachment.ts)
Initially, the function retrieves chatflowid and chatId from the request without any additional validation. The only check performed is whether these parameters exist in the request.
const chatflowid = req.params.chatflowId
if (!chatflowid) {
throw new Error(
'Params chatflowId is required! Please provide chatflowId and chatId in the URL: /api/v1/attachments/:chatflowId/:chatId'
)
}
const chatId = req.params.chatId
if (!chatId) {
throw new Error(
'Params chatId is required! Please provide chatflowId and chatId in the URL: /api/v1/attachments/:chatflowId/:chatId'
)
}
Next, the function retrieves the uploaded files and attempts to add them to the storage by calling the addArrayFilesToStorage function.
const files = (req.files as…
- Record
GHSA-h42x-xx2q-6v6g- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-434
- Updated
- 2026-11-02
NVD
9.3
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api/v1/attachments endpoint when storageType is set to local. Attackers can exploit path traversal in the chatId and chatflowId parameters to upload malicious files to arbitrary directories, potentially enabling remote code execution and server compromise.
- Record
CVE-2025-71333- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-73
- Updated
- 2026-11-02
OSV
9.3
Flowise - Arbitrary File Upload via Unauthenticated /api/v1/attachments Endpoint
Flowise through 2.2.4 contains an unauthenticated arbitrary file upload vulnerability in the /api/v1/attachments endpoint when storageType is set to local. Attackers can exploit path traversal in the chatId and chatflowId parameters to upload malicious files to arbitrary directories, potentially enabling remote code execution and server compromise.
- Record
CVE-2025-71333- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-73
- Updated
- 2026-11-02
OSVGHSA-h42x-xx2q-6v6g
9.3
Flowise Pre-auth Arbitrary File Upload
Summary
An unauthorized attacker can leverage the whitelisted route /api/v1/attachments to upload arbitrary files when the storageType is set to local (default).
Details
When a new request arrives, the system first checks if the URL starts with /api/v1/. If it does, the system then verifies whether the URL is included in the whitelist (whitelistURLs). If the URL is whitelisted, the request proceeds; otherwise, the system enforces authentication.
@ /packages/server/src/index.ts
this.app.use(async (req, res, next) => {
// Step 1: Check if the req path contains /api/v1 regardless of case
if (URL_CASE_INSENSITIVE_REGEX.test(req.path)) {
// Step 2: Check if the req path is case sensitive
if (URL_CASE_SENSITIVE_REGEX.test(req.path)) {
// Step 3: Check if the req path is in the whitelist
const isWhitelisted = whitelistURLs.some((url) => req.path.startsWith(url))
if (isWhitelisted) {
next()
} else if (req.headers['x-request-from'] === 'internal') {
basicAuthMiddleware(req, res, next)
} else {
const isKeyValidated = await validateAPIKey(req)
if (!isKeyValidated) {
return res.status(401).json({ error: 'Unauthorized Access' })
}
next()
}
} else {
return res.status(401).json({ error: 'Unauthorized Access' })
}
} else {
// If the req path does not contain /api/v1, then allow the request to pass through, example: /assets, /canvas
next()
}
}
The whitelist is defined as follows
export const WHITELIST_URLS = [
'/api/v1/verify/apikey/',
'/api/v1/chatflows/apikey/',
'/api/v1/public-chatflows',
'/api/v1/public-chatbotConfig',
'/api/v1/prediction/',
'/api/v1/vector/upsert/',
'/api/v1/node-icon/',
'/api/v1/components-credentials-icon/',
'/api/v1/chatflows-streaming',
'/api/v1/chatflows-uploads',
'/api/v1/openai-assistants-file/download',
'/api/v1/feedback',
'/api/v1/leads',
'/api/v1/get-upload-file',
'/api/v1/ip',
'/api/v1/ping',
'/api/v1/version',
'/api/v1/attachments',
'/api/v1/metrics'
]
This means that every route in the whitelist does not require authentication. Now, let's examine the /api/v1/attachments route.
@ /packages/server/src/routes/attachments/index.ts
const router = express.Router()
// CREATE
router.post('/:chatflowId/:chatId', getMulterStorage().array('files'), attachmentsController.createAttachment)
export default router
After several calls, the request reaches the createFileAttachment function @ (packages/server/src/utils/createAttachment.ts)
Initially, the function retrieves chatflowid and chatId from the request without any additional validation. The only check performed is whether these parameters exist in the request.
const chatflowid = req.params.chatflowId
if (!chatflowid) {
throw new Error(
'Params chatflowId is required! Please provide chatflowId and chatId in the URL: /api/v1/attachments/:chatflowId/:chatId'
)
}
const chatId = req.params.chatId
if (!chatId) {
throw new Error(
'Params chatId is required! Please provide chatflowId and chatId in the URL: /api/v1/attachments/:chatflowId/:chatId'
)
}
Next, the function retrieves the uploaded files and attempts to add them to the storage by calling the addArrayFilesToStorage function.
const files = (req.files as…
- Record
GHSA-h42x-xx2q-6v6g- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-434
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
flowisenpm |
through 2.2.7 | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2025-71333 is a critical vulnerability (CVSS 9.3) in Flowise, published March 13, 2025. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.90%, the 59th percentile. No source names a fixed version.
References
github.com/FlowiseAI/Flowise/security/advisories/GHSA-h42x-xx2q-6v6g
vulncheck.com/advisories/flowise-arbitrary-file-upload-via-unauthenticated-api-v1-attachments-endpoint
nvd.nist.gov/vuln/detail/CVE-2025-71333
github.com/advisories/GHSA-grch-cc26-w2fv
github.com/FlowiseAI/Flowise/commit/c2b830f279e454e8b758da441016b2234f220ac7
github.com/advisories/GHSA-h42x-xx2q-6v6g
github.com/CVEProject/cvelistV5/tree/main/cves/2025/71xxx/CVE-2025-71333.json
github.com/FlowiseAI/Flowise
Left out here: the rest of 2 source descriptions. The JSON record has them.