GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

PYSEC-2026-3946

Vulnerability from pysec - Published: 2026-09-10 09:44 - Updated: 2026-09-10 11:02
VLAI
Details

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/restful_api.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 handle_chat_result_non_streaming(). If the request contains a tools field, Xinference calls _post_process_completion() to parse tool-call output from the model response.

The Llama3 tool-call parser is implemented in xinference/model/llm/tool_parsers/llama3_tool_parser.py. In affected versions, extract_tool_calls() parsed model output with eval():

def extract_tool_calls(
    self, model_output: str
) -> List[Tuple[Optional[str], Optional[str], Optional[Dict[str, Any]]]]:
    try:
        data = eval(model_output, {}, {})
        return [(None, data["name"], data["parameters"])]
    except Exception:
        return [(model_output, 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(model_output, {}, {}) 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:

__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)
Impacted products
Name purl
xinference pkg:pypi/xinference

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "xinference",
        "purl": "pkg:pypi/xinference"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.7.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "0.0.0",
        "0.0.1",
        "0.0.2",
        "0.0.3",
        "0.0.4",
        "0.0.5",
        "0.0.6",
        "0.1.0",
        "0.1.1",
        "0.1.2",
        "0.1.3",
        "0.10.0",
        "0.10.1",
        "0.10.2",
        "0.10.2.post1",
        "0.10.3",
        "0.11.0",
        "0.11.1",
        "0.11.2",
        "0.11.2.post1",
        "0.11.3",
        "0.12.0",
        "0.12.1",
        "0.12.2",
        "0.12.2.post1",
        "0.12.3",
        "0.13.0",
        "0.13.1",
        "0.13.2",
        "0.13.3",
        "0.13.4",
        "0.14.0",
        "0.14.0.post1",
        "0.14.1",
        "0.14.1.post1",
        "0.14.2",
        "0.14.3",
        "0.14.4",
        "0.14.4.post1",
        "0.15.0",
        "0.15.1",
        "0.15.2",
        "0.15.3",
        "0.15.4",
        "0.16.0",
        "0.16.1",
        "0.16.2",
        "0.16.3",
        "0.2.0",
        "0.2.1",
        "0.2.2",
        "0.2.3",
        "0.3.0",
        "0.4.0",
        "0.4.1",
        "0.4.2",
        "0.4.3",
        "0.4.4",
        "0.5.0",
        "0.5.1",
        "0.5.2",
        "0.5.3",
        "0.5.4",
        "0.5.5",
        "0.5.6",
        "0.6.0",
        "0.6.1",
        "0.6.2",
        "0.6.3",
        "0.6.4",
        "0.6.5",
        "0.7.0",
        "0.7.1",
        "0.7.2",
        "0.7.3",
        "0.7.3.1",
        "0.7.4",
        "0.7.4.1",
        "0.7.5",
        "0.8.0",
        "0.8.1",
        "0.8.2",
        "0.8.3",
        "0.8.3.1",
        "0.8.4",
        "0.8.5",
        "0.9.0",
        "0.9.1",
        "0.9.2",
        "0.9.3",
        "0.9.4",
        "1.0.0",
        "1.0.1",
        "1.1.0",
        "1.1.1",
        "1.10.0",
        "1.10.1",
        "1.11.0",
        "1.11.0.post1",
        "1.12.0",
        "1.13.0",
        "1.14.0",
        "1.15.0",
        "1.16.0",
        "1.17.0",
        "1.17.1",
        "1.2.0",
        "1.2.1",
        "1.2.2",
        "1.3.0",
        "1.3.0.post1",
        "1.3.0.post2",
        "1.3.1",
        "1.3.1.post1",
        "1.4.0",
        "1.4.1",
        "1.5.0",
        "1.5.0.post1",
        "1.5.0.post2",
        "1.5.1",
        "1.6.0",
        "1.6.0.post1",
        "1.6.1",
        "1.7.0",
        "1.7.0.post1",
        "1.7.1",
        "1.7.1.post1",
        "1.8.0",
        "1.8.1",
        "1.8.1rc1",
        "1.9.0",
        "1.9.1",
        "2.0.0",
        "2.1.0",
        "2.2.0",
        "2.3.0",
        "2.4.0",
        "2.5.0"
      ]
    }
  ],
  "aliases": [
    "CVE-2026-61539",
    "GHSA-x2rj-828p-hx9m"
  ],
  "details": "### Summary\n\nXinference used Python\u0027s 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.\n\n### Details\n\nUsers can interact with deployed models through Xinference\u0027s OpenAI-compatible `/v1/chat/completions` API. The request entry point is implemented in `xinference/api/restful_api.py`; non-streaming requests call the model instance\u0027s `chat()` method and return the inference result.\n\nWhen 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 `handle_chat_result_non_streaming()`. If the request contains a `tools` field, Xinference calls `_post_process_completion()` to parse tool-call output from the model response.\n\nThe Llama3 tool-call parser is implemented in `xinference/model/llm/tool_parsers/llama3_tool_parser.py`. In affected versions, `extract_tool_calls()` parsed model output with `eval()`:\n\n```python\ndef extract_tool_calls(\n    self, model_output: str\n) -\u003e List[Tuple[Optional[str], Optional[str], Optional[Dict[str, Any]]]]:\n    try:\n        data = eval(model_output, {}, {})\n        return [(None, data[\"name\"], data[\"parameters\"])]\n    except Exception:\n        return [(model_output, None, None)]\n```\n\nThe 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(model_output, {}, {})` 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:\n\n```python\n__import__(\u0027os\u0027).system(\u0027touch /tmp/hacked\u0027)\n```\n\nWhen 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.\n\n### Score\n\nSeverity: Critical\n\nCVSS v3.1: 10.0\n\nVector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H`\n\nRationale:\n\n- AV:N: the vulnerable API is remotely reachable over the network;\n- AC:L: exploitation only requires a crafted chat-completion request and tool-call parameter;\n- PR:N: the tested default configuration did not require authentication;\n- UI:N: no user interaction is required;\n- S:C: command execution can affect resources beyond the Xinference application boundary;\n- C:H/I:H/A:H: remote code execution can fully compromise confidentiality, integrity, and availability.\n\n### Credit\n\nThis vulnerability was discovered by:\n\n- XlabAI Team of Tencent Xuanwu Lab (xlabai@tencent.com)\n- Atuin Automated Vulnerability Discovery Engine\n- Guannan Wang (wgnbuaa@gmail.com), Zhanpeng Liu (pkugenuine@gmail.com), Guancheng Li (lgcpku@gmail.com)",
  "id": "PYSEC-2026-3946",
  "modified": "2026-09-10T11:02:37.167860Z",
  "published": "2026-09-10T09:44:52.936049Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/xorbitsai/inference/security/advisories/GHSA-x2rj-828p-hx9m"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xorbitsai/inference/pull/4786"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xorbitsai/inference/commit/1b3d220f342ce68d34cec4586d9409d457dadc42"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/xorbitsai/inference"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xorbitsai/inference/releases/tag/v2.7.0"
    },
    {
      "type": "PACKAGE",
      "url": "https://pypi.org/project/xinference"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-x2rj-828p-hx9m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-61539"
    }
  ],
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Xinference vulnerable to remote code execution via unsafe `eval()` in Llama3 tool-call parsing"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…