T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/authorize.py:34
- Finding
- Overprivileged OAuth Scope and Unrestricted MCP Tool Dispatch## Vulnerability Details **File Location**: `scripts/authorize.py:34-37`; `scripts/mcp_client.py:1458-1476`; `scripts/mcp_client.py:1515-1516` **Vulnerability Type**: Least-privilege violation and unrestricted remote tool invocation **Risk Level**: Medium ### Vulnerable Code `scripts/authorize.py:34-37`: ```python SCOPE = ( "mcp:tools artifacts:write images:generate videos:generate music:generate " "speech:generate voices:read voices:write wallet:spend tasks:read artifacts:read tasks:cancel" ) ``` `scripts/mcp_client.py:1458-1476`: ```python def _run_command(command: str, tool_name: str | None = None) -> dict[str, Any]: session = _session_with_registration( state_dir=Path.home() / ".beatra", post_json=_default_post_json, ) if command == "tools": return session.request(2, "tools/list", {}) try: arguments = json.load(os.sys.stdin) except json.JSONDecodeError as exc: raise RuntimeError("Tool arguments on stdin must be one JSON object") from exc if not isinstance(arguments, dict): raise RuntimeError("Tool arguments on stdin must be one JSON object") assert tool_name is not None return session.request( 2, "tools/call", {"name": tool_name, "arguments": arguments}, ) ``` `scripts/mcp_client.py:1515-1516`: ```python call = subparsers.add_parser("call", help="Call one tool with a JSON object on stdin") call.add_argument("tool_name") ``` ### Technical Analysis The Skill’s declared workflow requires image generation, speech synthesis, video animation, media upload and retrieval, model and voice discovery, task polling, limited billing queries, and installation registration. The authorization request nevertheless includes capabilities outside that workflow, notably `music:generate` and `voices:write`. This broad authorization is combined with a generic command dispatcher that accepts any MCP tool name from a command-line argument and forwards it to ...[truncated 2346 chars]
- Remediation
- ## Remediation Suggestions 1. **Reduce the authorization scope** - Remove `music:generate` because the declared workflow performs no music generation. - Remove `voices:write` unless the Skill has a documented, user-approved voice-management feature. - Review whether `tasks:cancel` is required by default or should be requested only when the user explicitly asks to cancel a task. - Request only the minimum artifact, model, voice-read, generation, task-read, and billing permissions needed by this package. 2. **Add a strict MCP tool allowlist** - Reject any tool name not explicitly required by the Skill. - Include only documented operations such as required model and voice discovery, image generation, speech synthesis, video animation, asset upload, task retrieval, narrowly scoped wallet reads, and installation registration. - Keep administrative and unrelated generation tools outside the allowlist. 3. **Separate privilege levels** - Use read-only authorization for discovery, task inspection, wallet balance, and ledger queries. - Require a separate explicit approval before enabling spending, cancellation, resource modification, or other state-changing capabilities. - If supported by the backend, use a package-specific credential instead of one shared full-scope credential across multiple Skills. 4. **Validate calls against the declared workflow** - Check both the tool name and argument schema locally. - Require explicit user confirmation before billable or destructive calls. - Deny unknown tools by default, even if the remote server advertises them. 5. **Add security regression tests** - Verify that `music:generate`, voice-write operations, and unknown tool names are rejected. - Verify that required image, speech, video, upload, task, and read-only billing operations continue to function with the reduced scope.
