Cruising for Shells in Flowise – 6 RCEs That Rode Flowise Low and Slow Researchers identified six new remote code execution (RCE) vulnerabilities in Flowise v3.1.1 and v3.1.2, a generative AI development platform, adding to a series of high and critical security flaws disclosed in its advisories. The findings include account takeover via password reset token exposure (CVE-2025-58434), multiple JavaScript injection points (CVE-2025-59434, CVE-2025-59528, GHSA-7944-7c6r-55vv), and insecure password/email change features. The researchers also noted that a previously patched RCE in the CSVAgent node (CVE-2026-41264) was insufficiently fixed, allowing additional attack vectors. With the plethora of LLMs and AI products available today, it is not uncommon for developers to be subscribed to multiple services at once. Although these services can be very powerful individually, stringing them together into a single, coherent workflow is often anything but straightforward. So it came as no surprise to us that Flowise https://flowiseai.com/ has become one of the top GitHub repositories in this space. Flowise advertises itself as a "generative AI development platform for building AI Agents and LLM workflows".It offers a self-hosted option, as well as a cloud/enterprise plan where users can pay for support and additional enterprise features such as multiple workspaces. Imagine our surprise when we navigated to Flowise's security advisories https://github.com/FlowiseAI/Flowise/security on GitHub and saw that it was full of high and critical vulnerabilities. As we reviewed these advisories, our curiosity was piqued even further, and we decided to spend some time reviewing the codebase as well. Most of the patched issues were of high or critical severity, and the technical details behind them were alarming. For example, CVE-2025-58434 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wgpv-6j63-x5ph described how the password reset flow allowed account takeovers.This was due to its original implementation sending the password reset token in the response when requesting a password reset token for an email address of a registered user. Then there are also multiple instances where user input was executed as pure JavaScript, as seen in: CVE-2025-59434 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-435c-mg9p-fv22 , CVE-2025-59528 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-3gcm-f6qx-ff7p , GHSA-7944-7c6r-55vv https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-7944-7c6r-55vv , and many more. There were also account-related issues, which can be used as part of an exploit chain. For example, the password change feature https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-fjh6-8679-9pch did not require the user to re-enter their password.The email change feature https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-x39m-3393-3qp4 also had a similar issue. Flowise's custom Model Context Protocol MCP node has also been associated with multiple prior Remote Code Execution RCE vulnerabilities, including CVE-2026-40933 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-c9gw-hvqq-f33r , CVE-2026-41268 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-cvrr-qhgw-2mm6 , CVE-2025-59528 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-3gcm-f6qx-ff7p , and GHSA-6933-jpx5-q87q https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-6933-jpx5-q87q . These issues reflect a broader, systemic problem across the AI industry involving the insecure use of stdio MCP servers https://modelcontextprotocol.io/specification/2025-06-18/basic/transports stdio , as discussed in Having reviewed all the low-hanging fruit covered thus far, we were determined to sweep the codebase for further vulnerabilities, with a particular focus on identifying Remote Code Execution RCE issues. After diving into this massive codebase, we were able to identify 6 more ways to achieve RCE in Flowise v3.1.1 and v3.1.2 As we were writing up this post after having our submissions accepted, Flowise published https://github.com/FlowiseAI/Flowise/security/advisories?state=published a batch of vulnerabilities that were reported by ZDI and other researchers. These were vulnerabilities that affected versions prior to 3.1.0 . Interestingly, CVE-2026-41264 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-3hjv-c53m-58jj was an RCE vulnerability in the CSVAgent node, which was what we reported as well. This meant that the patch was insufficient, and we were able to find additional vectors to exploit the issue in the patched version. CVE-2025-26319 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-5w3r-f6gm-c25w describes a sandbox escape vulnerability regarding the use of Flowise's nodevm https://github.com/FlowiseAI/nodevm , a fork of the insecure vm2 sandbox puppeteer and playwright modules that were permitted within the sandbox. node-fetch , axios , and moment by default moment vulnerability CVE-2022-24785 CVE-2026-41268 https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-cvrr-qhgw-2mm6 exploited the configuration of a Flowise Custom MCP node to inject a NODE OPTIONS environment variable for a spawned node process. A part of Flowise's patch was to include NODE OPTIONS in a denylist validation check https://github.com/FlowiseAI/Flowise/pull/5667 , but from our The other three RCE vulnerabilities we reported were novel and did not have previously documented variants. We identified multiple instances where Flowise permitted users to supply arbitrary options when initialising the TypeORM DataSource class https://typeorm.io/docs/data-source/data-source , enabling exploitation of parameters such as entities to load and execute arbitrary JavaScript code. The SQL Database Chain and SQLite Record Manager nodes also allowed users to write a SQLite database to an arbitrary file path. We exploited this capability to create a polyglot shell script that was subsequently executed by chromium when launched via puppeteer .The following sections provide a technical analysis of all RCE vulnerabilities that we identified in Flowise. You might be wondering what pandas https://pandas.pydata.org/ has to do with this Node.js codebase. As it turns out, there were a few occurrences where pyodide https://pyodide.org/en/stable/ was used to run Python code. This is because Flowise allows users to write their own pandas code to process CSV files, if they choose to. One example is the CSVAgent node, which can be added to a Chatflow: We observed that when creating a CSVAgent node in Flowise, there are 2 sources that we can influence: csvFileBase64 - the uploaded CSV file that gets processed. customReadCSVFunc - the pandas Python code.The first source is csvFileBase64 , which comes from the uploaded CSV file: The second source is customReadCSVFunc , which is entered through the Additional Parameters window: The maintainers know how dangerous allowing users to execute Python code is, so in order to mitigate against RCEs, the validatePythonCodeForDataFrame function was used to validate user input: Eventually, both sources end up in this Python code that gets executed via pyodide.runPythonAsync : The base64String variable was not useful to us as the input was base64-encoded before it reached this sink. This encoded string then gets decoded by the Python code. Since this was a dead-end, we explored customReadCSVFunc instead. One way to exploit this sink would be to look for a bypass in the denylist. The good thing is, if we find a bypass, exploitation should be straightforward since the code is run directly on the server. Alternatively, we can go for a clean exploit by leveraging pandas itself. pd.read pickle is a prime candidate since we can control the functions called from pd . read pickle is somewhat of a wrapper that calls pickle.load , so in theory we can achieve RCE since we can specify what gets unpickled. First, we generate the base64-encoded pickled RCE payload that sends a reverse shell to our specified host and port: We are using a base64-encoded payload because the raw byte string contains null bytes, which will break the exploit later. Before using the payload directly in the customReadCSVFunc variable to perform pd.read pickle , we need to take care of a few constraints: read pickle only pickle.load expects a file handler as well. import or other related reserved words to use BytesIO for feeding an object into read pickle . open or other related functions to write the payload to disk to obtain a file handler either. pyodide sandbox does not have raw socket capabilities. pyodide.http.pyfetch , which we are unable to due to the need for import .So, one way to overcome this is to create a custom class that simulates BytesIO .The main functions called by read pickle are read and readline , so we just need to make sure they exist: Combining this MiniBytesIO class with the read pickle payload gives us the final PoC. PoC Over at Flowise, authenticate and create a new Chatflow: Drag a CSV Agent node onto the canvas: Click on Additional Parameters and fill the PoC in: Close the window and click the Save icon on the top right. Then, note the UUID in the current URL, which will be used to trigger the Chatflow later. Start a listening shell, then, in another terminal, send a curl command to the following URL replacing