---
id: 2026-10-xoscar-xinference-actor-pool-cloudpickle-rce-opt-in-auth-cve-2026-49950
title: "Xoscar through 0.11.2, the actor layer under Xinference, ran cloudpickle on any TCP peer (CVE-2026-49950, 9.3); 0.12.0 adds opt-in auth only"
date_disclosed: 2026-10-13
last_updated: 2026-10-17
severity: high
status: mitigated
ecosystems: [pypi, llm-infrastructure, self-hosted, inference-server, python]
tools_affected: ["xoscar 0.1.0 through 0.11.2 (actor-pool TCP and UCX transports)", "xoscar 0.12.0 and later without XOSCAR_AUTH_KEY set on every process", "Xinference supervisors and workers on any release (4.0.1 requires xoscar >= 0.12.0, authentication still off by default)", "anything else built on Xorbits' actor framework"]
tags: [cve, rce, cloudpickle, pickle-deserialization, missing-authentication, actor-framework, xoscar, xinference, inference-server, opt-in-fix, configuration-required-after-upgrade, vulncheck, mitigated]
---

## TL;DR
Xoscar, the Python actor framework that Xinference's supervisor and workers talk through, accepted a message on its actor-pool TCP channel and passed it to `cloudpickle.loads()` before checking the message type, so anyone who could reach the port ran code as the server process, which the record says commonly runs as root on GPU nodes (CVE-2026-49950, VulnCheck CNA, 2026-10-13, CVSS 4.0 9.3, 3.1 9.8; reporter Valentin Lobstein). Affected 0.1.0 through 0.11.2. Xoscar 0.12.0 (PyPI 2026-10-16) adds HMAC-SHA256 authentication of every frame, checked before deserialization, for the Socket and UCX transports, and Xinference 4.0.1 (same day) requires it. Authentication is off until `XOSCAR_AUTH_KEY` is set to the same non-empty value on every process; the release notes say so, and keyed and unkeyed processes cannot talk, so turning it on is a coordinated restart. An upgrade with no further action changes nothing about who can reach the actor port. Xinference's HTTP API key does not protect the actor ports either. Three earlier Xinference records this year (a 10.0 `eval()` in Llama3 tool-call parsing fixed in 2.7.0, `trust_remote_code` hard-wired on before 2.12.0, an unauthenticated file read in 3.3.0) had no file here and are listed below.

## What happened

Xinference (`xorbitsai/inference`, PyPI `xinference`) is a self-hosted model-serving platform that runs LLM, embedding, rerank, speech and image models behind an OpenAI-compatible API, and it is one of the serving layers a self-hosted RAG or agent backend ends up on. Its processes are actors: the supervisor, each worker and each model are Xoscar actors exchanging messages over TCP (and UCX on supported hardware). VulnCheck's record for CVE-2026-49950 says `SocketChannel.recv()` hands received bytes to `cloudpickle.loads()` with no validation, and a pickle `__reduce__` gadget runs "before message type validation," giving remote code execution as the process; the two references are the serialization core and the socket backend at v0.11.2. The advisory page lists only the publication date, 2026-10-13, and names no fixed version. It does not mention Xinference; the dependency link is from Xinference's own release notes and package metadata.

The vendor's response is on the two release pages. Xoscar v0.12.0 (2026-10-16) has a Security section: opt-in HMAC-SHA256 authentication for the Socket and UCX transports, covering framing metadata, the serialized header and every payload buffer, verified "before deserializing Python objects"; unauthenticated, mis-keyed and tampered messages are rejected; "Authentication is disabled by default"; when `XOSCAR_AUTH_KEY` is unset or empty the legacy wire format and v0.11.2 compatibility are preserved; keyed and unkeyed processes cannot communicate and there is no mixed-mode rolling upgrade. The notes link the CVE. Xinference v4.0.1 (2026-10-16) raises the dependency to `xoscar>=0.12.0` in the package and the CPU image, passes the key through the standalone and distributed Docker Compose files, and states that actor transport authentication is off unless a non-empty `XOSCAR_AUTH_KEY` is set, that upgrading alone does not enable it, and that HTTP API authentication does not protect actor ports. PyPI confirms the pin: `xinference` 4.0.1 requires `xoscar>=0.12.0`.

So the fix is real and the default is off. This file follows the sweep's rule for a fix that the default leaves off: status `mitigated`, where the operator sets the key, not `patched`. The same shape appears in [sandboxed.sh's opt-in flag](2026-10-continue-cli-bash-rule-chaining-bypass-vulncheck-agent-sandbox-batch.md) and in [the MCP SDKs' audience checks](2026-09-mcp-python-sdk-oauth-issuer-validation-credential-redirect.md), filed under their own files' statuses because other findings in those files set them; here the opt-in authentication is the whole fix. Whether the unauthenticated path still deserializes untrusted bytes when no key is set is answered by the compatibility sentence: the legacy wire format is preserved, so yes. A deployment that upgrades and does nothing else is in the same position as before.

Three Xinference records from August and September were untracked here and belong beside this one, because they describe the same product's other inputs:

- **CVE-2026-61539** (GitHub CNA, 2026-08-21, CVSS 3.1 10.0; vendor advisory GHSA-x2rj-828p-hx9m): Xinference passed model-generated Llama3 tool-call output to `eval()` in the tool parser, reachable from `/v1/chat/completions` with a `tools` field; the record says affected before 2.7.0 and the description says 2.5.0 and earlier; fixed in 2.7.0 (PR #4786). A model's output is attacker-influenced through the prompt, so this is prompt injection to code execution on the serving host.
- **CVE-2026-76841** (VulnCheck, 2026-08-24, 8.7): six loader call sites passed `trust_remote_code=True` as a literal or unconditional default, so any model repository's custom code ran at load with no setting to disable it before 2.12.0 (PR #5027).
- **CVE-2026-85668** (VulnCheck, 2026-09-04, 8.7): `POST /v1/models/llm/auto-register` took a caller-supplied `model_path` with no authentication and no path confinement and reflected the parsed `config.json`, `tokenizer_config.json` and `chat_template.jinja` from any directory; the record names 3.3.0 and commit 4a94832 and no fix (issue #5176).

Xinference's own tab also carries GHSA-jv65-rccw-j2j6, fixed in 3.5.0 (2026-09-25), for a custom-model registration that could claim built-in provenance and bypass the repository-code restriction; the release page says to check saved registrations for an unexpected `is_builtin: true`, because the patch does not rewrite old ones. That one has no CVE and was read from the releases page only.

Severity here is `high` against the CNA's 9.3. The actor port must be reachable: a single-host install that binds its actor transport to loopback is reached only from the host, a distributed install with workers on other machines exposes it on whatever interface the operator chose, and the record's "commonly runs as root on GPU nodes" is the blast radius once reached. The Hacker News front page carried a Medium post on 2026-10-17 titled "CVE-2026-49950 and Why Upgrading Xinference Isn't Enough"; the page returned 403 to this sweep and is not cited, but its title matches what the two release pages say.

## Am I affected?

```bash
pip show xoscar xinference 2>/dev/null | grep -iE '^(name|version)'   # xoscar <= 0.11.2 is CVE-2026-49950; 0.12.0 fixes nothing until keyed
# xinference < 2.7.0: CVE-2026-61539; < 2.12.0: CVE-2026-76841; 3.3.0 line: CVE-2026-85668 (no fix stated); < 3.5.0: GHSA-jv65-rccw-j2j6
echo "XOSCAR_AUTH_KEY set: ${XOSCAR_AUTH_KEY:+yes}"                    # empty on any process = authentication off on that process
ss -ltnp 2>/dev/null | grep -iE 'xinference|xoscar|python'           # actor ports bound to 0.0.0.0 are reachable by whoever can route to the host
```

Affected if any process runs xoscar 0.11.2 or earlier with an actor port reachable off-host, or runs 0.12.0 or later with the key unset on any process in the cluster. Not affected only if every actor port is loopback-only or every process carries the same non-empty key.

## If you are affected

Upgrade to xoscar 0.12.0 and Xinference 4.0.1 or later, then set `XOSCAR_AUTH_KEY` to the same high-entropy value on every supervisor and worker and restart them together; the release notes say a rolling upgrade is not supported, and a half-keyed cluster stops talking rather than falling back. Until then, bind the actor transports to loopback or a private network with no route from clients, and run the processes as a non-root user. If an actor port was reachable from an untrusted network while unauthenticated, treat the host as compromised: rebuild, rotate the model-provider and cloud credentials it held per [rotating-cloud-credentials.md](../playbooks/rotating-cloud-credentials.md), and follow [if-your-webapp-was-compromised.md](../playbooks/if-your-webapp-was-compromised.md). For the Xinference records, move to 3.5.0 or later, audit saved custom-model registrations for `is_builtin: true`, and do not load model repositories you did not vet.

## Prevention

- An inference platform's inter-process ports are a control plane; isolate them and authenticate them, and read the release notes for the word "default" before counting an upgrade as a fix ([supply-chain-attack-surface.md](../prevention/supply-chain-attack-surface.md)).
- Run model servers in a container with no other credentials and a non-root user ([agent-sandboxing.md](../prevention/agent-sandboxing.md)); the record's root-on-GPU-node observation is the deployment pattern, not the bug.
- Model repositories are code when `trust_remote_code` is on; vet them like packages ([package-vetting-checklist.md](../prevention/package-vetting-checklist.md)).

## Sources
- [VulnCheck, Xorbits Xoscar 0.11.2 Unauthenticated Deserialization RCE via Actor Pool](https://www.vulncheck.com/advisories/xorbits-xoscar-unauthenticated-deserialization-rce-via-actor-pool) — 2026-10-13; CVE-2026-49950, 9.3, range 0.1.0 through 0.11.2, no fixed version, the two code references, credit; Xinference not named.
- [CVE-2026-49950, CVE Services record (VulnCheck CNA)](https://cveawg.mitre.org/api/cve/CVE-2026-49950) — published 2026-10-13, updated 2026-10-16; 9.3 and 9.8 vectors, "commonly runs as root on GPU nodes."
- [xorbitsai/xoscar release v0.12.0](https://github.com/xorbitsai/xoscar/releases/tag/v0.12.0) — 2026-10-16; the Security section: HMAC-SHA256 on Socket and UCX, verified before deserialization, "Authentication is disabled by default," `XOSCAR_AUTH_KEY`, no mixed-mode upgrade, CVE link. [Releases index](https://github.com/xorbitsai/xoscar/releases) — v0.11.2 (2026-10-07), v0.11.1, v0.11.0 carry no security notes.
- [xorbitsai/inference releases](https://github.com/xorbitsai/inference/releases) — v4.0.1 (2026-10-16): requires Xoscar 0.12.0, key pass-through in Compose, "upgrading alone doesn't enable it," HTTP API auth does not protect actor ports; v3.5.0 (2026-09-25): GHSA-jv65-rccw-j2j6 and the `is_builtin` check.
- PyPI metadata, queried 2026-10-17: `xoscar` 0.11.2 uploaded 2026-10-07, 0.12.0 on 2026-10-16, latest; `xinference` 4.0.1 uploaded 2026-10-16 with `xoscar>=0.12.0` in `requires_dist`.
- CVE Services records, fetched 2026-10-17: [CVE-2026-61539](https://cveawg.mitre.org/api/cve/CVE-2026-61539) (GitHub CNA, 10.0, before 2.7.0, PR #4786), [CVE-2026-76841](https://cveawg.mitre.org/api/cve/CVE-2026-76841) (VulnCheck, 8.7, before 2.12.0, PR #5027), [CVE-2026-85668](https://cveawg.mitre.org/api/cve/CVE-2026-85668) (VulnCheck, 8.7, 3.3.0, issue #5176, no fix).
- [GitHub Advisory Database, query xinference](https://github.com/advisories?query=xinference+sort%3Apublished-desc) — five rows on 2026-10-17, all unreviewed; none for CVE-2026-49950, which is filed against `xoscar`.
- Hacker News, 2026-10-17: "CVE-2026-49950 and Why Upgrading Xinference Isn't Enough" (Medium) — the page returned 403 to this sweep; title only, not cited for any fact.
- Related in this corpus: [LMCache CVE-2026-105192](2026-10-lmcache-unauthenticated-pickle-rce-vllm-kv-cache.md), [the SGLang July to October wave](2026-10-sglang-july-october-cve-wave-dumper-eval-injection-unfixed-pickle-bypass-cert-cc-silence.md).
