A sandbox that started with the keys
Prefab UI's Generative UI feature has a specific job: take code supplied by a caller — including interface code written by a language model — and execute it inside an environment intended to isolate untrusted code. The CVE published on November 1 describes how that boundary failed. Python runs inside Pyodide in a Deno subprocess, but the launcher started Deno with unrestricted read, write and network permissions, while the runner left the Deno API accessible through the JavaScript global object. Pyodide's js module exposes that global to Python. Supplied code could therefore call Deno's file functions directly, reading and writing files as the server's operating-system user. JFrog also demonstrated persistence by placing a .pth file in the virtual environment's site-packages, where a subsequent Python process could execute the planted import.
None of this needs a memory-corruption exploit or a clever escape. The permissions were granted at launch and never taken away before the untrusted code ran. The sandbox boundary existed in the architecture diagram; at runtime, the door was open.
How a caller reaches it
Locally supplied code is one route. The remote route the CVE record names is the one that earns the network vector in the score.
JFrog assigns the unauthenticated attack path a CVSS 3.1 score of 10.0. Its report gives the authenticated path, where an attacker must already be permitted to call tools, a score of 9.9.
The remote path described by JFrog runs through FastMCP's GenerativeUI provider, which registers an MCP tool, generate_prefab_ui, and forwards its code argument into the sandbox. Where the server has Generative UI enabled, the host has Deno installed and no authentication is configured, a client able to reach the MCP server can call the tool and supply code. Where authentication is configured, the attacker must be a client permitted to call tools.
That distinction matters for triage. A Prefab deployment that never enabled Generative UI is not affected. One that enabled it without Deno installed cannot run the feature. One that enabled it behind an authenticated MCP server has a different risk from one exposed without authentication, even though all four sit under the same 10.0 headline until someone reads the conditions.
What the fix does, and what to do
Version 0.21.0 keeps the same architecture and removes the grant. The runner loads the runtime and the Prefab sources first, then revokes Deno's read, write and network permissions before it accepts caller code. The process starts with `--no-prompt`, so a permission request cannot quietly hand the rights back, and the bootstrap network access that remains is limited to cdn.jsdelivr.net. The change is a single pull request (538), which makes it easy to inspect.
For anyone running Prefab, upgrade to 0.21.0 or later. If an immediate upgrade is not possible, JFrog advises not registering the GenerativeUI provider on an MCP server accessible to untrusted clients. Where the feature must remain available, restrict it to trusted users and verify that authentication is configured rather than assuming it is.
Because the vulnerable versions could write into the Python environment itself, an upgrade alone does not answer whether a .pth file was already planted; that check is worth doing on any host where an untrusted client could actually reach the tool.
Why a library flaw is an AI story
The pattern is becoming familiar. A tool built to execute model-written code inherits the model's threat surface: the code is untrusted by design, it arrives through a tool call, and its author may be a language model responding to someone else's prompt. Prefab's documentation understood that, which is why the feature is a sandbox at all. The failure was not a missing concept. It was a launch flag.
Sources
- [1] JFrog Security Research, November 1, 2026 — "Prefab UI is vulnerable to Remote Code Execution via a Pyodide js Bridge to Deno" (CVE-2026-120338 / JFSA-2026-001699278; primary vulnerability analysis and published proof of concept, read first-hand)Read source
- [2] PrefectHQ — pull request 538, "Refresh dependencies and fix renderer and sandbox regressions" (merged October 25, 2026; read first-hand)Read source
- [3] PrefectHQ — fix commit 030f074f85e0b1be0dd44b0283185aecb26337a2 (read first-hand)Read source
- [4] PrefectHQ — prefab v0.21.0 release (published October 26, 2026)Read source
- [5] CVE-2026-120338 — JFrog CNA record (two CVSS scenarios: 10.0 unauthenticated, 9.9 authenticated)Read source
- [6] OffSeq Threat Radar — CVE-2026-120338 status snapshot, November 1, 2026Read source
- [7] GitHub advisory GHSA-595q-jv4r-q7j9 (reference listed in the CVE record; the advisory page was not independently inspected — it returned 404 to repeated fetch attempts)Read source