Skip to content

RAGFlow Remote Code Execution Vulnerability

High
yingfeng published GHSA-8xw3-v6c2-j84j Dec 31, 2025

Package

RAGFlow (github)

Affected versions

v0.22.0-31-g13e212c8 (and possibly earlier versions)

Patched versions

None

Description

  1. Product Information
    • Product: RAGFlow (Open-source Knowledge Base / RAG Platform)
    • Version: v0.22.0-31-g13e212c8 (and possibly earlier versions)
    • Deployment: Default Docker deployment / Source code deployment

  1. Impact Scope & Severity
    • A low-privileged authenticated user (normal login account) can execute arbitrary system commands on the server host process via the frontend Canvas CodeExec component, completely bypassing sandbox isolation.
    • CIA Impact: Full compromise. Attackers can obtain host-level privileges, steal data, and establish persistence.
    • Estimated CVSS: 9.9 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H)

  1. Major Vulnerability Points

  2. Frontend Remote Code Execution (Core Issue)
    • File: agent/tools/code_exec.py
    • Code: rt = eval(body.get("stdout", "")) (around lines 186–214)
    • Issue: The sandbox-returned stdout is directly passed to eval(). The stdout value is completely controlled by the user.
    • Exploit: The attacker only needs to print a single expression in the CodeExec script, which is then executed by the host process:

def main(**kw):
print("import('os').system('id > /tmp/pwn.log')")

After execution, /tmp/pwn.log on the host contains the output of id, demonstrating RCE. This can be replaced with a reverse shell or any arbitrary payload.

  1. Reproduction Steps (Core RCE)
    1. Log in to the frontend using a normal user account.
    2. Create a new Canvas and add a CodeExec node.
    3. Input the following script:

def main(**kw):
print("import('os').system('id > /tmp/pwn.log')")

4.	Run the node.
5.	On the host server, view /tmp/pwn.log and observe the uid/gid output, confirming the command executed on the host system.

(If outbound network is restricted, the payload can be changed to file-writing or other side-effect operations.)

  1. Technical Root Cause
    • Untrusted data (stdout) is parsed using eval() with no filtering or sandboxing.
    • The intended design was to “automatically convert string results into Python objects,” but this effectively executes attacker-controlled code.
    • Additional endpoints lack access control or contain inverted permission logic, significantly expanding the attack surface and enabling chained exploitation.
image-20251117155403909 image

Reporter: bilisheep of Xmirror Security Team

Severity

High

CVE ID

CVE-2025-68700

Weaknesses

No CWEs

Credits