- 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
⸻
- 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)
⸻
-
Major Vulnerability Points
-
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.
⸻
- Reproduction Steps (Core RCE)
- Log in to the frontend using a normal user account.
- Create a new Canvas and add a CodeExec node.
- 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.)
⸻
- 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.
Reporter: bilisheep of Xmirror Security Team
• 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
⸻
• 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)
⸻
Major Vulnerability Points
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.
⸻
def main(**kw):
print("import('os').system('id > /tmp/pwn.log')")
(If outbound network is restricted, the payload can be changed to file-writing or other side-effect operations.)
⸻
• 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.
Reporter: bilisheep of Xmirror Security Team