GitHub Advisoryadvisory · npm

GHSA-jv9m-vf54-chjj Flowise is vulnerable to arbitrary file write through its WriteFileTool

CRITICAL Published 2025-10-09 Modified 2025-11-15 Official page ↗
Aliases
CVE-2025-61913
Ecosystem
npm
Packages
flowise, flowise-components, Flowise
Severity
Critical
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Weaknesses
CWE-22
Reviewed
2025-10-09

Affected packages

• npm flowise: < 3.0.8 → fixed in 3.0.8 • npm flowise-components: < 3.0.8 → fixed in 3.0.8 • npm Flowise: < 3.0.8 → fixed in 3.0.8

Description

Summary The WriteFileTool in Flowise does not restrict the file path for reading, allowing authenticated attackers to exploit this vulnerability to write arbitrary files to any path in the file system, potentially leading to remote command execution. Details Flowise supports providing WriteFileTool for large models, which is used to write files to the server's file system. The implementation of this tool is located at packages/components/nodes/tools/WriteFile/WriteFile.ts. ``` /** • Class for writing data to files on the disk. Extends the StructuredTool • class. */ export class WriteFileTool extends StructuredTool { static lc_name() { return 'WriteFileTool' } schema = z.object({ file_path: z.string().describe('name of file'), text: z.string().describe('text to write to file') }) as any name = 'write_file' description = 'Write file from disk' store: BaseFileStore constructor({ store, ...rest }: WriteFileParams) { super(rest) this.store = store } async _call({ file_path, text }: z.infer) { await this.store.writeFile(file_path, text) return 'File written to successfully.' } } ``` This tool directly uses the file_path parameter passed to it without verifying whether the path belongs to Flowise's working directory. Authenticated attackers can exploit this vulnerability to write files with arbitrary content to any path on the server. There are numerous ways to achieve remote command execution through arbitrary file write vulnerabilities, which will not be elaborated here. For example, attackers could write their own public key to ~/.ssh/authorized_keys to gain remote SSH access, or overwrite /etc/ld.so.preload to hijack dynamic libraries and execute arbitrary code. Flowise's historical vulnerability information (https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-8vvx-qvq9-5948) also describes steps to achieve remote command execution by overwriting the start command in package.json. PoC This file writing vulnerability has been verified to exist in the latest Flowise Docker image (https://hub.docker.com/layers/flowiseai/flowise/latest/images/sha256-26300377397818a451e0710389eb77615256b0f3ecc895194850ab35dda3ae7b). The reproduction steps are as follows: 1. Pull the Flowise Docker image ``` docker pull flowiseai/flowise ``` 2. Start the Flowise service ``` docker run -d --name flowise -p 3000:3000 flowise ``` 3. Access the Flowise service at server ip:3000 in your browser and register an account 4. Save the following content as agent.json ``` { "nodes": [ { "id": "startAgentflow_0", "type": "agentFlow", "position": { "x": -203, "y": 37 }, "data": { "id": "startAgentflow_0", "label": "Start", "version": 1.1, "name": "startAgentflow", "type": "Start", "color": "#7EE787", "hideInput": true, "baseClasses": [ "Start" ], "category": "Agent Flows", "description": "Starting point of the agentflow", "inputParams": [ { "label": "Input Type", "name": "startInputType", "type": "options", "options": [ { "label": "Chat Input", "name": "chatInput", "description": "Start the conversation with chat input" }, { "label": "Form Input", "name": "formInput", "description": "Start the workflow with form inputs" } ], "default": "chatInput", "id": "startAgentflow_0-input-startInputType-options", "display": true }, { "label": "Form Title", "name": "formTitle", "type": "string", "placeholder": "Please Fill Out The Form", "show": { "startInputType": "formInput" }, "id": "startAgentflow_0-input-formTitle-string", "display": false }, { "label": "Form Description", "name": "formDescription", "type": "string", "placeholder": "Complete all fields below to continue", "show": { "startInputType": "formInput" }, "id": "startAgentflow_0-input-formDescription-string", "display": false }, { "label": "Form Input Types", "name": "formInputTypes", "description": "Specify the type of form input", "type": "array", "show": { "startInputType": "formInput" }, "array": [ { "label": "Type", "name": "type", "type": "options", "options": [ { "label": "String", "name": "string" }, { "label": "Number", "name": "number" }, { "label": "Boolean", "name": "boolean" }, { "label": "Options", "name": "options" } ], "default": "string" }, { "label": "Label", "name": "label", "type": "string", "placeholder": "Label for the input" }, { "label": "Variable Name", "name": "name", "type": "string", "placeholder": "Variable name for the input (must be camel case)", "description": "Variable name must be camel case. For example: firstName, lastName, etc." }, { "label": "Add Options", "name": "addOptions", "type": "array", "show": { "formInputTypes[$index].type": "options" }, "array": [ { "label": "Option", "name": "option", "type": "string" } ] } ], "id": "startAgentflow_0-input-formInputTypes-array", "display": false }, { "label": "Ephemeral Memory", "name": "startEphemeralMemory", "type": "boolean", "description": "Start fresh for every execution without past chat history", "optional": true, "id": "startAgentflow_0-input-startEphemeralMemory-boolean", "display": true }, { "label": "Flow State", "name": "startState", "description": "Runtime state during the execution of the workflow", "type": "array", "optional": true, "array": [ { "label": "Key", "name": "key", "type": "string", "placeholder": "Foo" }, { "label": "Value", "name": "value", "type": "string", "placeholder": "Bar", "optional": true } ], "id": "startAgentflow_0-input-startState-array", "display": true }, { "label": "Persist State", "name": "startPersistState", "type": "boolean", "description": "Persist the state in the same session", "optional": true, "id": "startAgentflow_0-input-startPersistState-boolean", …

Related

Alias · CVE (1)

  • CVE-2025-61913 Flowise is a drag & drop user interface to build a customized large language model flow. vulnerability

Weakness · CWE (1)

  • CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness

References