T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/authorize.py:31
- Finding
- Overbroad OAuth scopes combined with unrestricted MCP tool invocation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:31-35`; `scripts/mcp_client.py:1463-1481` **Vulnerability Type**: Violation of least privilege through excessive authorization and unrestricted tool forwarding **Risk Level**: Medium ### Vulnerable Code ```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" ) ``` The client then permits an arbitrary MCP tool name to be supplied: ```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}, ) ``` ### Technical Analysis The declared Skill functionality is corporate podcast production using text-to-speech, catalog or cloned voices, artifact uploads, and asynchronous task handling. The authorization request nevertheless includes permissions for image, video, and music generation, in addition to wallet spending and task cancellation. These unrelated media-generation permissions are not necessary for the declared podcast workflow. Moreover, the generic `call` subcommand does not enforce a local allowlist of approved Beatra tools. Any caller able to invoke the bundled script can provide an arbitrary tool name and JSON arguments, which are forwarded to the MCP endpoint using ...[truncated 2184 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Reduce the requested OAuth scopes to those required by this Skill: - Speech generation. - Voice listing and, only when cloning is selected, voice writing. - Required artifact upload/read operations. - Model discovery and task polling. - Read-only wallet operations only when the user requests balance or ledger information. 2. Remove image, video, and music generation scopes from this package. 3. Separate sensitive capabilities into explicit, confirmation-gated grants: - Request voice-write access only for a user-approved cloning workflow. - Request task-cancellation authority only when cancellation is explicitly requested. - Avoid a general wallet-spending scope where the service supports narrower operation-specific grants. 4. Add a local allowlist in `_run_command`, rejecting any tool outside the documented podcast workflow. A suitable allowlist should be limited to the exact Beatra tool names required by `SKILL.md`. 5. Apply per-tool argument validation before forwarding requests, including rejecting unknown fields and requiring user confirmation for paid or destructive calls. 6. Do not share one full-scope credential among Skills with unrelated functions. Use package-specific or capability-specific credentials where supported. 7. Add automated tests proving that unrelated image, video, music, administrative, and unknown tools are rejected locally. ]]>
