Events Secure.com at Black Hat USA 2026

Prefab UI Shipped a Sandbox With Full Host Access for Seven Months

A Prefab UI sandbox escape let caller code read and write host files. Check your prefab-ui version, upgrade to 0.21.0, and hunt for .pth files.

A sandbox meant to hold untrusted code in Prefab UI started with full read, write and network rights on the host. It stayed that way from March until late October. JFrog published the details on November 1.

What Happened?

Prefab UI is a PrefectHQ package that builds interfaces for FastMCP, installed with its apps option. Its Generative UI sandbox runs caller code through Pyodide inside a Deno subprocess. From version 0.14.0 through 0.20.2, that subprocess started with unrestricted read, write and network permissions, and the Deno API stayed reachable from the Python inside.

JFrog’s proof of concept, tracked as CVE-2026-120338, read a host file and wrote a new one. It also planted a .pth file in the server virtualenv, which the next Python process there ran. Version 0.21.0, released October 26, revokes those permissions before generated code runs.

What’s the Impact?

Exposure is narrow. Generative UI has to be switched on, Deno has to be installed, and untrusted callers have to reach the server. When all three are true, caller code reads and writes as the server’s user. JFrog scored it 10.0 out of 10 without a login, 9.9 with one.

Exposure check · November 3, 2026

Three things have to be true at once.

A CVSS score of 10.0 describes the worst case, not your case. Prefab UI’s sandbox escape only reaches a host where all three conditions below line up.

01
Generative UI is on
Opt in. Off by default.
02
Deno is installed
Required on the host to run the sandbox.
03
Untrusted callers reach it
Anyone who can call the tool can send code.
AND · AND
Then, and only then
Caller code reads and writes as the server user
10.0
CVSS v3.1
no auth
9.9
CVSS v3.1
authenticated
0.77%
EPSS
at time of check

Not listed in CISA’s KEV catalog. Narrow exposure, maximum blast radius where it applies.

What a Caller Could Actually Do

Reading comes first. Config files, tokens, keys, anything on disk the service account can open.

Writing is the part that lasts. A .pth file dropped into site-packages runs on every interpreter start, so the next pip command or service restart executes whatever the caller left behind. That survives the patch.

Nobody is reporting attacks. The flaw is absent from CISA’s KEV catalog, and EPSS, which estimates the chance a flaw gets attacked in the next 30 days, put it at 0.77% when we checked.

The Scanner Gap

The entry in GitHub’s advisory database carries no package name and no version range, as of November 3. GitHub marks it unreviewed and says Dependabot alerts are unsupported for it. Anything reading that feed has nothing to match against. The CVE record itself does carry the package and the version range, so what your tooling tells you depends on which source it reads.

The dependency floor does not help either. FastMCP’s apps option accepts prefab-ui 0.18.0 or later with no upper bound, so a fresh install pulls the fixed build while an existing lock file keeps a vulnerable one.

How to Avoid This

  • Check the installed prefab-ui version. The FastMCP version will not tell you
  • Upgrade to 0.21.0 or later
  • Search the virtualenv for unexpected .pth files before running pip
  • Switch off Generative UI on any server untrusted callers can reach
  • Rotate secrets readable by the server’s OS user
CVE-2026-120338 · Hunting reference

What to look for on a Prefab UI host

Proof of concept artifacts

IndicatorWhat it means
/etc/passwdRead target in the published proof of concept. A sandboxed payload reading it is the demonstrated file read.
/tmp/prefab-ui-sandbox-proof.txtWrite target in the published proof of concept. Its presence means someone ran the public payload against the host.
*.pth in site-packagesPersistence. A line starting with import runs on every interpreter start unless -S is passed. Check before running pip.

Behavioral indicators

SignalWhy it matters
generate_prefab_uiThe tool that reaches the sandbox. A call whose code references Deno or imports js is an incident, not a false positive.
Deno launched with
–allow-read –allow-write –allow-net
Unscoped permissions. This is the vulnerable launcher behavior on 0.14.0 through 0.20.2.
Deno permission errorsOn 0.21.0 and later the public payloads fail this way. Errors here mean someone tried.
Outbound from sandbox
to anything but cdn.jsdelivr.net:443
0.21.0 scopes bootstrap network access to that host only. Other destinations warrant a look.

Version and config checks

WhereWhat to confirm
prefab-ui installed versionAffected: 0.14.0 up to and including 0.20.2. Fixed: 0.21.0 and later. Check the package itself, not the FastMCP version.
fastmcp-slim 4.1.6 apps extraAccepts prefab-ui>=0.18.0 with no upper bound, so a lock file can still pin a vulnerable build.
*.lock, requirements*.txtWhere a vulnerable prefab-ui pin hides.
Deno on PATHNo Deno, no sandbox, no exposure through this path.

Hunt commands

# 1. Is Generative UI wired up anywhere in this codebase?
grep -rnE "GenerativeUI|prefab_ui\.sandbox" --include="*.py" .

# 2. What version is actually pinned?
grep -rn -A1 "prefab-ui" --include="*.lock" --include="requirements*.txt" .

# 3. Run this BEFORE any pip command. pip starts Python,
#    and a planted .pth file runs on startup.
find /path/to/venv -name '*.pth' -ls

# 4. Any .pth line starting with import is executable code.
grep -n '^import' /path/to/venv/lib/python*/site-packages/*.pth

# 5. Proof of concept write target.
ls -la /tmp/prefab-ui-sandbox-proof.txt 2>/dev/null
If you find a planted .pth file: upgrading does not remove it. Rebuild the server from a clean image, then rotate every secret the server’s OS user could read. The upgrade closes the path. It does nothing about what already went out.

Sources: JFrog Security Research advisory JFSA-2026-001699278, the CVE record for CVE-2026-120338, and PyPI package metadata. Verified November 3, 2026.

Also Worth a Look

JFrog published three Beta9 container escape advisories on November 1, each scored 9.9. Two are fixed in worker 0.1.756. The third, a gateway side volume ownership check, also needs gateway 0.1.776.

Start With the Version Number on the Host

Secure.com relies on your scanners to see the prefab-ui Python package. As of 3 November, we found no package version advisory for CVE-2026-120338 that a scanner could match, so check the installed prefab-ui version directly.

When your vulnerability scanner reports CVE-2026-120338 on a host or a container image, Secure.com shows it on that asset with its KEV status, EPSS score and exploit evidence.