T05 · Unauthorized Access and Privilege Escalation
- Location
- scripts/authorize.py:31
- Finding
- Overprivileged Shared Device Token and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:31-35`; `scripts/mcp_client.py:1463-1482` **Vulnerability Type**: Excessive authorization scope and unrestricted privileged tool dispatch **Risk Level**: High ### 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" ) ``` ```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 Skill's declared function is to synthesize shift-handoff speech and, optionally, clone an authorized voice sample. Its authorization request nevertheless grants image, video, and music generation in addition to speech, voice, artifact, task, cancellation, and wallet-spending capabilities. The resulting full-scope token is stored as a shared Beatra device credential. The bundled client then accepts an arbitrary MCP tool name from the command line and forwards it through `tools/call` without a local allowlist restricting the operation to the tools needed by this Skill. Server-side authorization may still restrict the exact tools available, but the local implementation places no narrower boundary around this package. The combination of a bro ...[truncated 1435 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace the full shared scope with a package-specific least-privilege scope containing only: - Text-to-speech generation. - Voice listing and optional voice cloning. - Required artifact upload/read operations. - Model discovery. - Task creation and task-status reads. - Wallet reads only when explicitly requested. 2. Do not grant image, video, or music generation to this Skill. 3. Separate wallet-spending authority from read-only wallet access where the service supports it. 4. Add a hardcoded local allowlist for this package, for example: - `beatra.models.list` - `beatra.voices.list` - `beatra.voices.clone` - `beatra.speech.synthesize` - `beatra.assets.upload` - `beatra.tasks.get` - `beatra.tasks.list` - `beatra.tasks.cancel` - Explicitly required wallet-read tools 5. Reject every other tool name before establishing or using an authenticated session. 6. Prefer per-package tokens over a single full-scope credential shared among unrelated Skills. 7. Require explicit user confirmation immediately before wallet-spending or task-cancellation operations. ]]>
