Back to skill

Security audit

course-video-studio

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to support the advertised course-video workflow, but it also grants broad Beatra account authority and silently self-updates local executable skill files by default.

Install only if you trust Beatra to hold a shared device credential and to update this skill automatically. Consider running `python3 scripts/mcp_client.py update --auto off` after install, and use this only with media and accounts where broad Beatra generation, upload, task, wallet, and voice permissions are acceptable.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding
Unsigned Automatic Updates Enable Remote Payload Retrieval and Execution## Vulnerability Details **File Location**: `scripts/mcp_client.py:27-28, 334-356, 469-491, 969-1019, 1543`; `SKILL.md:164-179`; `references/automatic-updates-and-safety.md:3-7` **Vulnerability Type**: Unsigned remote code update with automatic installation **Risk Level**: High ### Vulnerable Code ```python PACKAGE_DISCOVERY_URL = "https://beatra.ai/skills/course-video-studio/channels/clawhub/install.json" PACKAGE_CDN_BASE_TEMPLATE = "https://cdn.beatra.ai/agent-packages/course-video-studio/channels/clawhub/v{version}" ``` ```python def maybe_auto_update( *, state_dir: Path | None = None, install_root: Path | None = None, get_bytes: GetBytes = _default_get_bytes, now: float | None = None, ) -> bool: """Best-effort silent update. Never block the requested MCP command.""" resolved_state = state_dir or Path.home() / ".beatra" try: resolved_root = (install_root or _current_install_root()).resolve() update_home = _update_home(resolved_state, resolved_root) observed_at = time.time() if now is None else now nonce = _lock_update(update_home, now=observed_at) if nonce is None: return False try: recover_update(state_dir=resolved_state, install_root=resolved_root) state = _read_update_state(update_home) if state.get("auto_update", True) is False: return False last_checked = state.get("last_checked_at") if ( isinstance(last_checked, (int, float)) and observed_at - float(last_checked) < UPDATE_CHECK_MAX_AGE_SECONDS ): return False state["last_checked_at"] = observed_at _write_private_json(update_home / "state.json", state) checked = check_update(get_bytes=get_bytes) if not checked["update_available"]: ...[truncated 3634 chars]
Remediation
## Remediation Suggestions 1. Sign release metadata with an offline-controlled publisher key and embed the corresponding verification public key in the installed client. 2. Verify the digital signature before trusting the version, URLs, manifest hashes, archive hashes, or file list. 3. Separate update discovery from installation: automatic checks may remain available, but package replacement should require explicit user approval. 4. Default automatic installation to disabled, particularly for updates that replace executable scripts or Agent instructions. 5. Display the target version and security-relevant file changes before installation. 6. Consider a trusted package registry or transparency log that supports signed, immutable releases and rollback detection. 7. Retain the existing redirect rejection, hostname restrictions, checksum verification, path validation, size limits, ownership checks, transaction journal, and rollback logic as defense-in-depth controls.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/authorize.py:33
Finding
Over-Privileged Shared OAuth Token and Unrestricted Generic Tool Invocation## Vulnerability Details **File Location**: `scripts/authorize.py:33-36`; `scripts/mcp_client.py:1466-1481`; `references/installation-and-auth.md:73-75`; `references/mcp-connection.md:9-10` **Vulnerability Type**: Excessive authorization scope and insufficient tool-level restriction **Risk Level**: Medium ### 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 declared course-video workflow legitimately requires asset uploads, voice lookup or cloning, speech synthesis, video generation, model discovery, task status reads, and wallet or billing queries. The requested token nevertheless includes unrelated capabilities such as `images:generate` and `music:generate`. It also includes `tasks:cancel` as a standing capability rather than acquiring or authorizing cancellation only when needed. The command-line client compounds this excessive scope by accepting an arbitrary tool name through the `call` subcommand and forwarding it through `tools/call` with the shar ...[truncated 1742 chars]
Remediation
## Remediation Suggestions 1. Reduce the authorization scope to capabilities required by the declared workflow. 2. Remove `images:generate` and `music:generate` unless those capabilities become explicit, user-visible features. 3. Use incremental or operation-specific authorization for task cancellation and other infrequent sensitive operations where supported. 4. Restrict `mcp_client.py call` to a package-specific allowlist, including only required model, asset, voice, speech, video, task, and wallet operations. 5. Reject unknown tool names locally before sending authenticated requests. 6. Prefer separate package-scoped credentials over one full-scope token shared by unrelated Skills. 7. Enforce equivalent authorization boundaries server-side so a modified local client cannot bypass the package allowlist. 8. Preserve the existing POSIX credential protections, including owner checks, directory mode `0700`, file mode `0600`, regular-file validation, and `O_NOFOLLOW`.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares no permissions while its documented behavior clearly includes sensitive capabilities: shell execution, filesystem access, network access, environment use, and automatic update/install actions. This creates a trust and review gap because users and policy systems cannot accurately assess what the skill can do before activation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The stated purpose is course-video generation, but the skill also documents broader operational behavior including OAuth login, bearer-token storage, generic remote tool invocation, local file upload, telemetry/registration, uninstall-time credential revocation, and self-updating package management. That mismatch can hide materially different security consequences from users, increasing the risk of overbroad trust, credential exposure, and unexpected remote actions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that a bundled client silently checks for updates and installs newer releases without separate confirmation. Even though integrity checks are described, silent auto-install materially changes the local executable behavior over time and expands supply-chain risk, especially because the skill also uses shell, filesystem, network, and credentialed operations.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The document explicitly states that the client performs silent automatic update checks and installs higher versions automatically without separate confirmation. Even though the text describes integrity checks and rollback protections, auto-replacing installed files by default without clear user opt-in or prominent warning reduces user control and can create supply-chain risk if the trusted update source or signing pipeline is ever compromised.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The document states that the bundled client automatically performs a registration call and writes a local cache file on first use, but it does not clearly warn users that network transmission and filesystem modification will occur. Even though the data is described as non-billable and non-secret, silent telemetry-like behavior can violate user expectations, privacy requirements, or enterprise controls, especially in restricted environments.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The client performs silent automatic self-updates during normal command execution, fetching remote content and replacing installed package files without a contemporaneous user prompt. Although the implementation includes several integrity and path-safety checks, this still expands the trusted computing base and creates a supply-chain risk channel where a compromised publisher, discovery endpoint, or signing process could alter code on disk automatically.

Self-Modification

High
Category
Rogue Agent
Content
)
    update = subparsers.add_parser(
        "update",
        help="Check, install, or configure Beatra package self-updates",
    )
    update.add_argument(
        "--check",
Confidence
89% confidence
Finding
This codebase includes a self-update mechanism that can replace the installed package's own files, which is inherently risky because it enables remote code changes on the local system. Even with checksum, manifest, and path validation, self-modifying application behavior materially increases supply-chain and persistence risk if the upstream distribution infrastructure or release process is compromised.

Static analysis

No suspicious patterns detected.