
SonicWall Capture Labs threat research team became aware of the threat CVE-2026-33057, assessed its impact, and developed mitigation measures for this vulnerability. The flaw, also known as the Mesop AI Sandbox /exec-py Unauthenticated RCE, is a critical remote code execution vulnerability affecting Google-originated Mesop in PyPI versions up to and including 1.2.2. The vulnerability allows a remote attacker to execute arbitrary Python in the Mesop server process by sending a single POST /exec-py request whose code form parameter contains a urlsafe-base64-encoded Python payload. Classified under CWE-94 (Improper Control of Generation of Code) and rated CVSS 9.8 (Critical, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), the flaw was reported through GitHub Security Advisory GHSA-gjgx-rvqr-6w6v. A complete proof-of-concept is published in the advisory: a single curl request that drops attacker-controlled Python on disk and runs it. The EPSS score of 8.42% places this vulnerability well above the typical baseline for newly published CVEs and reflects the trivial reproducibility of the exploit. Affected products include every Mesop deployment that surfaces the bundled ai/sandbox/ Flask blueprint (the AI authoring helper shipped alongside the public PyPI distribution), notably AI demo containers and developer port-forwards. Fixes are available in Mesop 1.2.3, which deletes the entire ai/ source tree. Users should upgrade immediately.
Mesop is an open-source Python UI framework that originated at Google and is now maintained at mesop-dev/mesop, with roughly 6.5K GitHub stars and an Apache 2.0 license. Mesop builds AI web applications in pure Python on top of Flask and ships an in-tree AI authoring helper under ai/sandbox/ that registers a small WSGI application designed to host attacker-supplied modules. That sandbox WSGI app is the surface affected by this vulnerability.
The root cause of CVE-2026-33057 lives in ai/sandbox/wsgi_app.py inside the Mesop source distribution. The function exec_py_route() is registered on the public Flask blueprint as POST /exec-py with no authentication decorator, no CSRF token, no shared-secret check, and no origin or Host validation. The handler reads the code form parameter, calls base64.urlsafe_b64decode() on it without any allowlist, writes the resulting bytes verbatim to temp_module_<counter>.py in the gunicorn worker's current working directory, and invokes mesop.cli.execute_module.execute_module() on the file. Because execute_module() imports and runs the module, the attacker's Python source executes immediately in the gunicorn worker process, with the worker user's full privileges and environment.

Mesop's public PyPI package itself does not auto-mount the ai/sandbox/ blueprint, but the sandbox is shipped in the source repository, in the AI authoring documentation, and in container images that bundle gunicorn plus the ai/sandbox/main.py entrypoint. Where it is mounted, the route is reachable on whichever port the operator chose for gunicorn (commonly 32123, the Mesop default). The fact that the route exists in any production-shaped image means a single misconfigured port forward, an exposed AI demo, or a developer laptop accessible over a corporate network is enough to give an unauthenticated attacker a full RCE primitive.

Reaching the sink requires no bypass and no chained vulnerability. The body must be valid urlsafe base64 (alphabet [A-Za-z0-9_\-=]) so that base64.urlsafe_b64decode() succeeds; anything else fails to decode and the route returns HTTP 500 before any code runs. Once the bytes decode, they are written verbatim and handed to execute_module(). There are no syntax, length, or content checks. Because the decoded bytes are arbitrary Python source, the impact is bounded only by what Python can do in the gunicorn worker: shell command execution, file read or write, secret theft from the process environment, outbound network connections, and a full reverse shell.

Validation against mesop 1.2.2 on Ubuntu 22.04 confirmed every step of the chain. A short curl payload dropped a file containing the output of id on the target. A custom Python exploit produced a 200 OK response in well under one second and wrote attacker-controlled Python to disk on the target. A reverse shell variant connected back from the gunicorn worker to a remote attacker listener and dropped the attacker into a pty-backed bash session running as the worker user, with full process and filesystem access.

The security fix in Mesop 1.2.3 (commit 825f5597) deletes the entire ai/ directory from the source tree, removing ai/sandbox/wsgi_app.py outright along with the two internal callers in ai/src/ai/offline_common/eval.py and ai/src/ai/offline_common/eval_lib.py. With the source files gone, the /exec-py route can no longer be registered, no matter how an operator launches the package. The fix is a hard removal rather than a patch, which makes verification trivial: in 1.2.3, ls site-packages/ai/sandbox/ returns no such directory.

The following conditions must be met for successful exploitation of CVE-2026-33057:
Critical Note: No authentication, no user interaction, no token, and no pre-existing foothold are required. The route was intended for an internal AI test harness but is registered on the public Flask blueprint with no access control. Reaching gunicorn over the network is the only attack precondition.
Exploiting CVE-2026-33057 requires only a single unauthenticated HTTP POST. The wire format is fixed by the vulnerable code itself: method POST, URI /exec-py, body prefix code=, body alphabet urlsafe base64. Every functional exploit looks identical at the framing level and differs only in the bytes that follow code=. The base64 payload contains arbitrary Python source, so the attacker chooses what to do with the code execution: a shell command, a file drop, a reverse shell, secret exfiltration, or any combination.
The attacker writes a small Python program (the post-exploitation action) to a buffer, encodes it with base64.urlsafe_b64encode, URL-encodes the result inside an application/x-www-form-urlencoded body, and POSTs it to /exec-py. The Mesop sandbox decodes the parameter, writes the bytes to disk as temp_module_<n>.py, and runs them with execute_module(). The HTTP response returns 200 OK with body OK once the module loads cleanly.

| Component | Value | Purpose |
|---|---|---|
| Target Endpoint | POST /exec-py | Unauthenticated Flask route registered by ai/sandbox/wsgi_app.py |
| Default Port | 32123 | Mesop sandbox gunicorn default; any reachable port is exploitable |
| Body Encoding | application/x-www-form-urlencoded | Required so request.form.get("code") returns the parameter |
| Required Parameter | code=<urlsafe-base64> | Passed unmodified to base64.urlsafe_b64decode() then written to disk |
| Decoded Payload | Arbitrary Python source | Runs through execute_module() in the gunicorn worker process |
| Server Response | HTTP/1.1 200 OK body OK | Returned once execute_module() completes without raising |
Step 1. Reconnaissance: The attacker probes for a live Mesop sandbox by sending GET /exec-py. The vulnerable build returns HTTP 405 Method Not Allowed (the route exists but only accepts POST), which is a high-confidence fingerprint that the sandbox blueprint is mounted.
Step 2. Payload Construction: The attacker writes the desired Python action (for example, a reverse-shell program that opens a TCP socket to an attacker-controlled host and dups it onto /bin/bash), then base64-encodes the source with the urlsafe alphabet so it traverses the form body cleanly.
Step 3. Exploit Delivery: The attacker sends a single POST /exec-py with Content-Type: application/x-www-form-urlencoded and body code=<base64>. Mesop decodes the value, writes temp_module_<n>.py to the gunicorn working directory, and calls execute_module() on the file.
Step 4. Post-Exploitation: The attacker's Python runs as the gunicorn worker user. Routine actions include reading process environment for API keys and DB connection strings, dropping a webshell into the worker's CWD, exfiltrating local files, opening a reverse shell, or installing persistence. None of these are part of the vulnerability itself; they are the natural consequence of arbitrary Python in the server process.
Validation against Mesop 1.2.2 with gunicorn bound to 0.0.0.0:32123 confirmed full exploitation. A curl payload (Figure 6) caused the target to write a file containing the output of id. A Python exploit returned HTTP 200 with body OK in well under one second and produced attacker-controlled output on the target. A reverse shell variant fired from a remote attacker host connected back to a netcat listener almost immediately after the worker began executing the decoded payload. The session held a pty-backed bash shell running as the worker user.
To ensure SonicWall customers are prepared for any exploitation that may occur due to this vulnerability, the following signature has been released:
| Signature ID | Signature Name |
|---|---|
| IPS: 22160 | Mesop wsgi_app Remote Code Execution |
The risks posed by CVE-2026-33057 can be mitigated or eliminated by:
Vulnerability coordinated through the Mesop maintainer team and disclosed via GitHub Security Advisory GHSA-gjgx-rvqr-6w6v.
Third-party vulnerability database mirrors:
Share This Article

An Article By
An Article By
Security News
Security News