T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/authorize.py:31
- Finding
- Authorization Requests Permissions Beyond the Skill's Declared Functionality## Vulnerability Details **File Location**: `scripts/authorize.py:31-35` **Vulnerability Type**: Excessive OAuth authorization scope **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 broad credential is subsequently accepted by the generic tool-call interface in `scripts/mcp_client.py:1462-1480`: ```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 workflow requires product-image upload, image-to-video generation, model discovery, task monitoring, cancellation, and limited billing operations. The authorization scope additionally grants music generation, speech generation, voice creation and reading, general image generation, and broad wallet-spending authority. This violates least privilege. The local client also accepts an arbitrary MCP tool name rather than enforcing a package-specific allowlist. Consequently, any process capable of invoking the bundled client can attempt to use unrelated capabilities covered by the shared bearer credential. The issue does not prove ...[truncated 1264 chars]
- Remediation
- ## Remediation Suggestions 1. Replace the broad scope with the smallest set required for: - artifact upload and read access; - model-card discovery; - image-to-video generation only; - task read and user-requested cancellation; - narrowly scoped wallet balance, ledger, and approved spending operations. 2. Remove music, speech, voice, and unrelated image-generation permissions. 3. Add a local allowlist in `mcp_client.py` and reject every tool not explicitly required by this package. 4. Separate read-only wallet access from paid-generation authorization where the service supports it. 5. Bind authorization grants to the package slug and enforce that binding server-side. 6. Require reauthorization after narrowing the scope so previously issued broad credentials do not remain active.
