T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/authorize.py:31
- Finding
- Overprivileged Shared Device Token and Unrestricted MCP Tool Invocation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:31-35`; `scripts/mcp_client.py:1458-1472` **Vulnerability Type**: Excessive authorization scope and missing client-side tool allowlist **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" ) ``` The command dispatcher accepts an arbitrary 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 exposes that unrestricted parameter: ```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 function is course narration. Its legitimate operations include text-to-speech generation, voice listing or cloning, narrator-sample upload, relevant artifact access, task polling, and billing reads. The requested bearer-token scope additionally authorizes unrelated image, video, and music generation, general wallet spending, task cancellation, and broad artifact/task access. The documentation identifies this as a shared, full-scope device token used by multiple Beatra Skills. The local client ...[truncated 1714 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Issue a package-specific token limited to the exact narration operations required by this Skill. 2. Remove unrelated image, video, and music generation scopes. 3. Separate wallet reads from spending authority. Grant spending only for explicitly supported speech or voice operations. 4. Restrict task and artifact access to resources created by this package or installation. 5. Add a hardcoded client-side allowlist of accepted tool names and reject every other `tool_name`. 6. Require explicit user confirmation immediately before each billable tool call. 7. Use separate tokens for separate Skills instead of sharing one full-account bearer token. 8. Where the backend supports it, bind authorization to the package slug, installation identifier, operation class, and resource ownership. ]]>
