· via dev.to (home feed)
CVE-2026-120338: Prefab UI sandbox let MCP callers read and write host files
JFrog has disclosed CVE-2026-120338 in PrefectHQ's Prefab UI: the Generative UI Python sandbox could read and write files on the host. Versions 0.14.0–0.20.2 are affected; 0.21.0 fixes it.

JFrog Security Research published CVE-2026-120338 on November 1, a flaw in Prefab UI — the generative UI framework from PrefectHQ — that let anyone able to submit code to its Python sandbox read and write files on the host server. The GitHub advisory gives it a maximum 10.0 CVSS score. Versions 0.14.0 through 0.20.2 are affected, and the fix shipped in 0.21.0 on October 26, days before the disclosure went public.
How the sandbox leaked
Prefab's Generative UI runs caller-supplied Python inside Pyodide, a WebAssembly build of Python, inside a Deno subprocess — a design that looks well isolated. According to JFrog, two implementation choices defeated both layers. The launcher started Deno with unrestricted --allow-read, --allow-write and --allow-net flags, handing the outer process full filesystem and network access. The runner also left the Deno API on JavaScript's global object, which Pyodide's js module proxies — so Python code inside the sandbox could call js.Deno.readTextFileSync() and js.Deno.writeTextFileSync() directly against the host. JFrog additionally notes that the runner's comments and the public documentation described the subprocess as read-only, which it was not.
From file write to code execution
Write access alone was enough to escalate. On version 0.20.2, JFrog planted a .pth file in the server virtualenv's site-packages directory. Python's site module executes import lines found in .pth files with exec() every time an interpreter starts in that environment, so a single written file became persistent code execution outside the sandbox.
Who is exposed
The common remote path is FastMCP's GenerativeUI provider, registered with one call to add_provider(GenerativeUI()). FastMCP's documentation describes the resulting generate_prefab_ui tool as accepting Python code, running it in the Pyodide sandbox and rendering the output, and JFrog found that the code argument is passed straight through without extra checks.
The 10.0 score assumes FastMCP's default auth=None configuration, meaning an unauthenticated, network-reachable server. With authentication enabled, JFrog still scores the issue 9.9, because any client permitted to call tools reaches the bug. There is also an indirect route: the tool executes model-written code, so a prompt injection hidden in a document or web page could steer a trusted, authenticated client into submitting hostile Python.
Two conditions limit exposure: Generative UI is opt-in, and the host must have Deno installed. The second is weaker than it sounds, since FastMCP's docs say Deno installs automatically on first use. Neither the GitHub advisory nor Strix's CVE entry reports exploitation in the wild, and the CVE is not in CISA's KEV catalog. Also worth noting: the fastmcp[apps] extra pulls in prefab-ui, so a deployment can carry the vulnerable package without anyone adding it by name.
What version 0.21 changes
The fix landed in PR #538, merged on October 25. The short version is that permissions needed during bootstrap are dropped before any generated code executes. JFrog breaks that into three changes: the runner revokes Deno read, write and network permissions once the runtime and Prefab sources are loaded but before it accepts code; Deno starts with --no-prompt, so later permission requests cannot win access back; and bootstrap network access is limited to cdn.jsdelivr.net:443. JFrog reports that both its read and write payloads now fail with a Deno permission error on 0.21.0 and later.
What operators should do
Check which prefab-ui version each environment has installed, search the codebase for GenerativeUI registrations, and upgrade to at least 0.21.0 — 0.21.1 was the latest on PyPI as of November 1. Upgrading does not undo a file that was already written, so the dev.to write-up by Gabriel Anhaia recommends activating a previously exposed server's virtualenv and inspecting the .pth files in its site-packages for unexpected import lines. Some are legitimate, such as those from editable installs. If upgrading is not yet possible, JFrog's advice is blunt: do not register GenerativeUI on a server that untrusted clients can reach.
Why it matters
This is a maximum-severity flaw in a package many FastMCP users inherit transitively, and the sandbox it bypassed was not a hollow one — Pyodide inside Deno is a reasonable isolation design. It failed on configuration: broad permission flags and a leftover global object gave sandboxed code a direct path to the host. That pattern generalises to every stack that executes model-written code, and as generative UI spreads across MCP servers, these sandboxes become a primary security boundary. The practical takeaway, echoed by the researcher, is to treat "sandbox" as a claim to test: run code that tries to read outside its directory, write a file and open an outbound connection, and watch what actually fails.
- #security
- #vulnerability
- #mcp
- #python
- #deno