GHSA-x2rj-828p-hx9m: Critical severity pip/xinference vulnerability
Summary
Xinference used Python's unsafe eval() function when parsing Llama3 tool-call output generated by a large language model. Because the model output can be influenced by attacker-controlled prompts sent to the chat completion API, a remote attacker can craft prompts that cause the model to return a Python expression. Xinference then evaluates that expression on the server while post-processing the tool-call result. In the tested default deployment, authentication was not enabled, so the vulnerability was exploitable by an unauthenticated remote attacker through the /v1/chat/completions endpoint.
Details
Users can interact with deployed models through Xinference's OpenAI-compatible /v1/chat/completions API. The request entry point is implemented in xinference/api/restfulapi.py; non-streaming requests call the model instance's chat() method and return the inference result.
When the Transformers backend is used, inference results flow through the batching logic in xinference/model/llm/transformers/core.py. Non-streaming chat results are handled by handlechatresultnonstreaming(). If the request contains a tools field, Xinference calls postprocesscompletion() to parse tool-call output from the model response.
The Llama3 tool-call parser is implemented in xinference/model/llm/toolparsers/llama3toolparser.py. In affected versions, extracttoolcalls() parsed model output with eval():
python def extracttoolcalls( self, modeloutput: str ) -> List[Tuple[Optional[str], Optional[str], Optional[Dict[str, Any]]]]: try: data = eval(modeloutput, {}, {}) return [(None, data["name"], data["parameters"])] except Exception: return [(modeloutput, None, None)]
The intended behavior was to convert a Python dictionary-like string generated by the model into a dictionary object. However, eval() executes the input as a Python expression, and eval(modeloutput, {}, {}) is not a security sandbox. If an attacker can influence the model output through prompt injection or direct chat input, the attacker can cause the model to return an expression such as:
python import('os').system('touch /tmp/hacked')
When the expression reaches eval(), it is executed in the Xinference server process context. The harmless touch /tmp/hacked command can be replaced with other payloads, such as a reverse shell, malware download, sensitive file read, or lateral-movement payload.
Score
Severity: Critical
CVSS v3.1: 10.0
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Rationale:
- AV:N: the vulnerable API is remotely reachable over the network; - AC:L: exploitation only requires a crafted chat-completion request and tool-call parameter; - PR:N: the tested default configuration did not require authentication; - UI:N: no user interaction is required; - S:C: command execution can affect resources beyond the Xinference application boundary; - C:H/I:H/A:H: remote code execution can fully compromise confidentiality, integrity, and availability.
Credit
This vulnerability was discovered by:
- XlabAI Team of Tencent Xuanwu Lab (xlabai@tencent.com) - Atuin Automated Vulnerability Discovery Engine - Guannan Wang (wgnbuaa@gmail.com), Zhanpeng Liu (pkugenuine@gmail.com), Guancheng Li (lgcpku@gmail.com)
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/xinferenceto a version that resolves this vulnerability.Fixed in 2.7.0
Event History
Frequently Asked Questions
Which deployments are most exposed?
Deployments using the Transformers backend with Llama3 tool-call handling are exposed when clients can reach the OpenAI-compatible /v1/chat/completions API. The tested default deployment had authentication disabled, allowing unauthenticated remote access.
What must an attacker do to trigger the issue?
The attacker needs to send a chat-completion request whose prompt influences the model to emit a Python expression in its Llama3 tool-call output. The request must include a tools field so Xinference performs tool-call post-processing.
Which request flow contains the vulnerable processing?
The described path is a non-streaming chat-completion request handled through the Transformers backend. Xinference processes the result in handle_chat_result_non_streaming() and evaluates attacker-influenced model output during tool-call post-processing.