GHSA-728h-4mwj-f2p4: Flowise: mass assignment breaks cross-workspace isolation

GHSA-728h-4mwj-f2p4 HIGH
Published May 14, 2026
CISO Take

Flowise versions up to 3.1.1 contain a mass assignment flaw in the CustomTemplate service where `Object.assign(entity, body)` allows any authenticated user to overwrite the `workspaceId` field on a persisted row, silently transferring AI workflow templates between workspaces without authorization. In multi-tenant or enterprise Flowise deployments—where different teams or clients share a single instance—this constitutes a full tenant boundary violation: workspace UUIDs are exposed in standard API responses, making target selection trivial for any authenticated user. There is no active exploitation recorded in CISA KEV and no public exploit code at this time, but the exploit chain requires nothing more than a standard HTTP PUT request with one extra JSON field, placing this squarely in script-kiddie territory for any authenticated insider or compromised account. Organizations running Flowise in multi-workspace mode should upgrade to 3.1.2 immediately; as an interim control, restrict the CustomTemplate API endpoints to trusted internal network ranges and audit the `workspace_id` column of the `custom_template` table for unexpected ownership changes.

Sources: GitHub Advisory ATLAS

What is the risk?

High risk for multi-tenant Flowise deployments; negligible for single-workspace installations. Exploitation requires only a valid authenticated session and knowledge of target workspace UUIDs—both low bars in practice since UUIDs are exposed in standard API responses. The vulnerability is a textbook CWE-915 mass assignment bug requiring no special AI/ML knowledge: any developer-level Flowise user can execute it with a single curl command. Severity is contextual: single-workspace deployments face no effective blast radius, while enterprise or MSP deployments where multiple teams or clients share an instance face complete workspace boundary collapse.

Attack Kill Chain

Initial Access
Attacker authenticates to the Flowise instance using valid credentials for their assigned workspace, obtaining a session cookie or JWT with standard member permissions.
AML.T0012
Reconnaissance
Attacker enumerates target workspace UUIDs from standard Flowise API responses that expose `workspaceId` fields on shared or cross-referenced objects, requiring no elevated privileges.
AML.T0006
Exploitation
Attacker issues a crafted PUT request to `/api/v1/customtemplates/<id>` with `workspaceId` set to the target workspace UUID, triggering the mass assignment flaw to overwrite the ownership field on the persisted database row.
AML.T0049
Impact
Target workspace gains the attacker-transferred template in their marketplace (or attacker's workspace gains victim templates via create-path `id` override), breaking tenant isolation and enabling AI workflow intellectual property theft with no anomalous audit trail.
AML.T0085.001

What systems are affected?

Package Ecosystem Vulnerable Range Patched
flowise npm <= 3.1.1 3.1.2

Do you use flowise? You're affected.

Severity & Risk

CVSS 3.1
N/A
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

What should I do?

5 steps
  1. Upgrade Flowise to version 3.1.2 (PR #6129 applies the explicit field allowlist fix, commit f64047b).

  2. If immediate upgrade is blocked, restrict /api/v1/customtemplates/* endpoints to trusted internal network CIDRs via reverse proxy or WAF rule as an interim control.

  3. Audit the database for tampering: SELECT id, workspace_id, updated_at, created_at FROM custom_template ORDER BY updated_at DESC LIMIT 500; — cross-reference workspace_id against the authenticated user's workspace at the time of creation using access logs; any mismatch is a candidate for tampering.

  4. Scan HTTP access logs for PUT/PATCH requests to the customtemplates endpoint containing workspaceId in the request body — this is the primary exploit signature.

  5. Review all sibling entity controllers in the Flowise codebase for the same Object.assign(entity, body) pattern without an explicit field allowlist, as the advisory notes this is a recurring pattern.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 9 - Risk management system
ISO 42001
A.6.2 - AI system access control
NIST AI RMF
MANAGE 2.2 - Risk treatment and residual risk management
OWASP LLM Top 10
LLM08 - Excessive Agency

Frequently Asked Questions

What is GHSA-728h-4mwj-f2p4?

Flowise versions up to 3.1.1 contain a mass assignment flaw in the CustomTemplate service where `Object.assign(entity, body)` allows any authenticated user to overwrite the `workspaceId` field on a persisted row, silently transferring AI workflow templates between workspaces without authorization. In multi-tenant or enterprise Flowise deployments—where different teams or clients share a single instance—this constitutes a full tenant boundary violation: workspace UUIDs are exposed in standard API responses, making target selection trivial for any authenticated user. There is no active exploitation recorded in CISA KEV and no public exploit code at this time, but the exploit chain requires nothing more than a standard HTTP PUT request with one extra JSON field, placing this squarely in script-kiddie territory for any authenticated insider or compromised account. Organizations running Flowise in multi-workspace mode should upgrade to 3.1.2 immediately; as an interim control, restrict the CustomTemplate API endpoints to trusted internal network ranges and audit the `workspace_id` column of the `custom_template` table for unexpected ownership changes.

Is GHSA-728h-4mwj-f2p4 actively exploited?

No confirmed active exploitation of GHSA-728h-4mwj-f2p4 has been reported, but organizations should still patch proactively.

How to fix GHSA-728h-4mwj-f2p4?

1. Upgrade Flowise to version 3.1.2 (PR #6129 applies the explicit field allowlist fix, commit f64047b). 2. If immediate upgrade is blocked, restrict `/api/v1/customtemplates/*` endpoints to trusted internal network CIDRs via reverse proxy or WAF rule as an interim control. 3. Audit the database for tampering: `SELECT id, workspace_id, updated_at, created_at FROM custom_template ORDER BY updated_at DESC LIMIT 500;` — cross-reference `workspace_id` against the authenticated user's workspace at the time of creation using access logs; any mismatch is a candidate for tampering. 4. Scan HTTP access logs for PUT/PATCH requests to the customtemplates endpoint containing `workspaceId` in the request body — this is the primary exploit signature. 5. Review all sibling entity controllers in the Flowise codebase for the same `Object.assign(entity, body)` pattern without an explicit field allowlist, as the advisory notes this is a recurring pattern.

What systems are affected by GHSA-728h-4mwj-f2p4?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, multi-tenant AI workflow platforms, LLM orchestration pipeline management, RAG pipeline template repositories.

What is the CVSS score for GHSA-728h-4mwj-f2p4?

No CVSS score has been assigned yet.

Technical Details

NVD Description

## Summary **Type:** Mass assignment via `Object.assign(entity, body)` -> client-controlled `workspaceId` (and on create, `id`) overwritten on the CustomTemplate entity -> cross-workspace data takeover and IDOR. **File:** `packages/server/src/services/marketplaces/index.ts` **Root cause:** The CustomTemplate controller/service constructs a `new CustomTemplate()` and copies the request body into it via `Object.assign(...)` without an explicit field allowlist. The request body therefore can include `workspaceId`, `id`, `createdDate`, `updatedDate`. The server only rebinds *some* of these after the assign (e.g. on create, it overwrites `workspaceId` but not `id`; on update, it overwrites `id` but not `workspaceId`). The remaining client-controlled values land directly on the persisted row, breaking workspace isolation. Same root pattern as the customtemplate entity's sibling controllers and as `DocumentStore` before it was patched in commit 840d2ae. ## Affected Code **File:** `packages/server/src/services/marketplaces/index.ts` ```ts // at line 211 Object.assign(newTemplate, body) // <-- BUG: body.id, body.workspaceId accepted ``` **Why it's wrong:** `Object.assign(target, source)` copies every own enumerable property of `source` onto `target`. The TypeORM/SQL persistence layer below it does not strip ownership-bearing columns, so `workspaceId` set in the request body lands as the new `workspaceId` of the persisted row. The DocumentStore patch (commit 840d2ae) demonstrated the intended fix shape (explicit field-by-field allowlist) but it has not been applied to this entity. ## Exploit Chain 1. Attacker is an authenticated member of workspace A. They have a session cookie / JWT for the Flowise web UI. State at this point: attacker can read and write entities scoped to workspace A. 2. Attacker creates a customtemplate in workspace A via the documented API (or reuses an existing one they own). They note its entity `id`. 3. Attacker issues a `PUT /api/v1/customtemplates/<id>` (or equivalent endpoint) with a JSON body that includes `"workspaceId": "<workspace-B-id>"` (an arbitrary other workspace's UUID). State at this point: the request reaches the controller as a workspace-A authenticated request. 4. The controller calls `Object.assign(updateEntity, body)`. The body's `workspaceId` overwrites the entity's `workspaceId` field. The persistence layer commits the row. 5. Final state: the customtemplate row is now owned by workspace B. Workspace B members can see it, modify it, and use it. Workspace A loses access (it no longer satisfies their workspace filter). The original creator's workspace audit shows nothing because the operation looked like a normal update. ## Security Impact **Severity:** High. Cross-workspace boundary violation by any authenticated workspace member. **Attacker capability:** Any authenticated user with permission to update a customtemplate can move it to any workspace whose UUID they can guess or enumerate (workspace UUIDs are exposed in many API responses, so enumeration is trivial). CustomTemplates encode reusable workflow templates scoped to a workspace. Cross-workspace movement via `workspaceId` overwrite makes the template appear in another workspace's marketplace listing. **Preconditions:** Authenticated session with edit permission for the source customtemplate. No second factor required. Workspace UUIDs are exposed via the `/api/v1/workspaces` listing or via any cross-referenced object's `workspaceId` field, so target enumeration is trivial. **Differential:** PoC-verified by source inspection of the original GHSA-q4pr-4r26-c69r. Patched build (with the suggested fix below) refuses the `workspaceId` field; vulnerable build accepts it and persists it. ## Suggested Fix Already fixed in PR https://github.com/FlowiseAI/Flowise/pull/6129 (allowlist pattern applied). ```ts // Allowlist pattern (matches commit 840d2ae for DocumentStore): const updatedCustomTemplate = new CustomTemplate() if (body.<allowed_field_1> !== undefined) updatedCustomTemplate.<allowed_field_1> = body.<allowed_field_1> if (body.<allowed_field_2> !== undefined) updatedCustomTemplate.<allowed_field_2> = body.<allowed_field_2> // ...whitelist only the documented fields. Never copy id, workspaceId, createdDate, updatedDate from the client. ``` Regression tests should assert that a request body containing `workspaceId`, `id`, `createdDate`, or `updatedDate` is rejected (or at minimum: does not change those columns on the persisted row) for both create and update paths.

Exploitation Scenario

An attacker employed as a contractor holds valid Flowise credentials for Team A's workspace in an enterprise deployment shared by multiple teams. Wanting to exfiltrate Team B's proprietary LLM orchestration templates, the attacker first retrieves Team B's workspace UUID by inspecting any cross-referenced object in a standard API response (e.g., a shared resource listing or a CVE feed integration object that includes `workspaceId`). The attacker then selects a CustomTemplate they own in Team A and issues `PUT /api/v1/customtemplates/<their-template-id>` with body `{"name": "copy", "workspaceId": "<Team-B-UUID>"}`. The Flowise service calls `Object.assign(updateEntity, body)`, the TypeORM persistence layer commits `workspaceId = Team-B-UUID`, and the template now appears in Team B's marketplace. For the reverse direction (reading Team B's templates), the attacker uses the create-path `id` override: `POST /api/v1/customtemplates` with `{"id": "<Team-B-template-UUID>", ...}`, pulling that template into their own workspace. The entire operation leaves no anomalous audit trail in Team A or Team B's activity logs.

Timeline

Published
May 14, 2026
Last Modified
May 14, 2026
First Seen
May 14, 2026

Related Vulnerabilities