T09 · Insecure Skill Coding Practices
- Location
scripts/mcp_client.py:2299- Finding
Billable MCP operations can bypass the required user confirmation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/mcp_client.py:2299-2316
Related Authorization Requirements:SKILL.md:104,SKILL.md:137
Vulnerability Type: Missing enforcement of user authorization for billable operations
Risk Level: MediumVulnerable code:
python def _run_command( command: str, tool_name: str | None = None, arguments: dict[str, Any] | 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", {}) if arguments is None: arguments = _read_tool_arguments() assert tool_name is not None return session.request( 2, "tools/call", {"name": tool_name, "arguments": arguments}, )The Skill instructions establish explicit approval gates before paid operations:
markdown Show the speech card and wait:and:
markdown Show the video card and wait:Technical Analysis
The command entry point accepts an unrestricted MCP tool name and a JSON argument object from standard input. It then forwards both directly to
tools/callusing the bearer credential stored in~/.beatra/credentials.json.The executable path does not distinguish read-only operations from billable operations such as voice cloning, speech synthesis, or video animation. It also does not require evidence that:
- the user received the required six-field cost card;
- the user explicitly approved the specific paid stage;
- the approved operation matches the submitted tool and arguments;
- the approved price, count, and request identity remain valid.
Consequently, the confirmation requirement exists only in the Skill documentation. A caller that invokes the bundled client directly can bypass it. The authorization helper obtains ...[truncated 1850 chars]
- Remediation
View remediation
Remediation Suggestions
Enforce paid-operation approval in executable code rather than relying exclusively on Agent instructions:
- Maintain an explicit allowlist that classifies each MCP tool as read-only, non-billable, or billable.
- Reject billable
calloperations unless they include a short-lived approval artifact bound to:- the exact tool name;
- a canonical hash of the complete arguments;
- the current price and operation count;
- the opaque
client_request_id; - the authenticated account or installation;
- an expiration time.
- Have the service issue or validate this approval artifact after the user approves the displayed cost card. Do not rely on a caller-provided Boolean such as
confirmed: true. - Invalidate the approval after use, or bind it to an idempotent request identity so it cannot authorize modified or additional work.
- Provide separate client entry points for read-only and billable operations. The billable entry point should fail closed when approval evidence is absent, expired, malformed, or does not match the request.
- Add tests proving that direct invocations of voice cloning, speech synthesis, video animation, and other spending-capable tools are rejected without valid operation-bound approval.
- Preserve the existing staged confirmations so approval for cloning, speech, or video cannot implicitly authorize another stage.
