T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/authorize.py:33
- Finding
- Overprivileged Shared Credential and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:33-37`; `scripts/mcp_client.py:1448-1474`; `references/mcp-connection.md:8-10` **Vulnerability Type**: Excessive authorization scope and missing tool allowlist **Risk Level**: High ### Vulnerable Code Authorization requests capabilities unrelated to earnings-script narration: ```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 generic command accepts an arbitrary MCP tool name: ```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}, ) ``` The CLI places no restriction on that tool name: ```python call = subparsers.add_parser("call", help="Call one tool with a JSON object on stdin") call.add_argument("tool_name") ``` The documented credential model confirms that the token is shared and full-scope: ```text They share the one full-scope Device Token stored in `~/.beatra/credentials.json`. ``` ### Technical Analysis The declared function requires text-to-speech, optional voice cloning, authorized media upload, model discovery, task monitoring, and limited billing information. The requested credential additionally permits image, video, and music gen ...[truncated 1710 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope credential with a package-specific or capability-scoped token. 2. Request only the operations needed by this Skill: - Text-to-speech model and voice discovery. - Speech synthesis. - Optional voice cloning when explicitly requested. - Authorized asset upload. - Task creation/read access for tasks created by this package. - Read-only wallet operations when requested. 3. Remove unrelated image, video, and music generation scopes. 4. Separate wallet-read access from wallet spending, and avoid granting spending as a general scope where per-operation authorization is possible. 5. Add a strict local allowlist of MCP tool names and reject every other name before establishing the authenticated session. 6. Scope task and artifact access to package-created resources where the service supports resource-level authorization. 7. Use distinct credentials between packages so compromise of one Skill cannot affect every Beatra Skill installed for the user. ]]>
