CVE-2026-0766: Remote Code Execution in OpenWebUI


OpenWebUI is one of the most popular self-hosted front ends for local language models. Its Tools feature lets an administrator add small Python functions the model can call. That feature is also where CVE-2026-0766 lives: tool code is handed straight to Python’s exec() with no sandbox, so creating a tool runs arbitrary code on the server.

This is the short version. The full writeup, with the complete payload and a working proof of concept, is linked at the end. The bug was originally reported through the Zero Day Initiative (ZDI-26-032); what follows is our own analysis and PoC.

Root cause

The Tools feature stores Python source and executes it with something close to:

exec(content, module.__dict__)

There is a replace_imports() step, but all it does is rewrite import paths. It never validates or restricts what the code actually does. So any Python you put in a tool runs with the privileges of the OpenWebUI process.

The detail that makes it sharp

The code runs at tool creation, not at tool use. You do not need anyone to invoke the tool, and you do not need the model to call it. The moment the tool is saved, exec() fires. That collapses the whole exploit down to a single authenticated API call.

Preconditions

You have to be authenticated, and tool creation defaults to administrator access. So this is a privileged-user-to-server-RCE bug, not an anonymous internet-facing one. It still matters. It turns a malicious admin, a stolen admin session, or an admin who imports a tool they were handed, into full server access, and it crosses the line from “app admin” to “shell on the box.”

Getting output back

Running code is one thing, reading the result is another. The writeup shows a tidy way to do it: build the output into a Pydantic model so it comes back inside the tool’s own valves spec response. Roughly:

UserValves = type('UserValves', (BaseModel,), {
    'data': Field(default=output, description=output)
})

The command output then rides out in the JSON the valves endpoint returns. No reverse shell needed to read a file or run a command, though a reverse shell is also on the table.

Impact

Remote code execution at the privilege level of the OpenWebUI process: command execution, file reads, outbound shells. On a typical self-hosted deployment that is the whole box, and often the model weights, API keys, and whatever data the instance can reach.

If you run OpenWebUI

  • Restrict tool creation to administrators you actually trust, and review who currently has admin.
  • Audit existing tools for anything that does more than it claims to.
  • Run the service with least privilege: a non-root user, a read-only filesystem where you can manage it, and egress filtering so a successful exploit has nowhere to phone home.
  • The real fix is upstream: stop feeding user content to raw exec(). Use RestrictedPython, an AST allow-list, or run tool code in an isolated container.