Back to skill

Security audit

legal-explainer-clip

Security checks for vulnerabilities and agentic risk

Overview

The skill’s main legal explainer workflow is disclosed, but it also grants broad Beatra account authority and silently self-updates installed code by default.

Review this carefully before installing in a sensitive environment. It will store a shared Beatra credential under ~/.beatra, use that credential for remote MCP calls, upload user-selected files when requested, send package registration metadata, and silently auto-update package code unless disabled with the documented update command.

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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/authorize.py:34
Finding
Overprivileged Device Token and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:34-37`; `scripts/mcp_client.py:1463-1481`; `scripts/mcp_client.py:1490` **Vulnerability Type**: Excessive authorization scope and missing tool allowlist **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}, ) ``` ```python call.add_argument("tool_name") ``` ### Technical Analysis The Skill's declared workflow needs image generation, speech synthesis, video generation, artifact access, model and voice discovery, wallet reads, and task management. The requested authorization scope also includes unrelated capabilities such as `music:generate` and `voices:write`. In addition, the command-line client accepts an arbitrary MCP tool name and forwards it using the shared bearer credential. It does not enforce an allowlist corresponding to the operations documented by this Skill. Server-side scope checks may limit some calls, but every capability present in the broad token remains available through this generic dispatch path. This violates least-privilege principles ...[truncated 1459 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope token with a package-specific, least-privilege credential. 2. Remove capabilities not required by this Skill, particularly `music:generate` and `voices:write`. 3. Define an explicit client-side allowlist containing only documented tools, such as: - `beatra.models.list` - `beatra.voices.list` - `beatra.images.generate` - `beatra.speech.synthesize` - `beatra.videos.animate` - Required artifact, wallet, installation, and task operations 4. Reject unknown tool names before initializing an authenticated session. 5. Separate read-only, spending, cancellation, and resource-modification permissions where supported. 6. Require explicit user confirmation immediately before wallet spending, task cancellation, or mutable account operations. 7. Avoid sharing one unrestricted token across unrelated Skills; use capability-bound or audience-bound tokens instead. 8. Enforce equivalent restrictions server-side because client-side allowlists alone can be bypassed by a modified client. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/mcp_client.py:969
Finding
Silent Automatic Retrieval and Replacement of Executable Skill Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:31-32`; `scripts/mcp_client.py:515-522`; `scripts/mcp_client.py:969-1018`; `scripts/mcp_client.py:1543` **Vulnerability Type**: Unattended remote code update channel **Risk Level**: Medium ### Vulnerable Code ```python PACKAGE_DISCOVERY_URL = "https://beatra.ai/skills/legal-explainer-clip/channels/clawhub/install.json" PACKAGE_CDN_BASE_TEMPLATE = "https://cdn.beatra.ai/agent-packages/legal-explainer-clip/channels/clawhub/v{version}" ``` ```python def _read_update_state(update_home: Path) -> dict[str, Any]: path = update_home / "state.json" try: value = json.loads(path.read_text(encoding="utf-8")) except (OSError, ValueError): return {"schema_version": 1, "auto_update": True} if not isinstance(value, dict) or value.get("schema_version") != 1: return {"schema_version": 1, "auto_update": True} return value ``` ```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 - floa ...[truncated 3425 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Default automatic installation to disabled. 2. Permit silent update checks, but require explicit user approval before downloading and replacing executable files. 3. Display the current version, proposed version, changed files, publisher identity, and release provenance before installation. 4. Sign release metadata and package manifests with a pinned offline public key whose trust is independent of the discovery endpoint and CDN. 5. Consider a transparency log or reproducible-build verification to make unauthorized releases detectable. 6. Support version pinning and rollback to a known, previously audited release. 7. Separate the updater from the authenticated MCP client so update code cannot directly access the bearer token. 8. Preserve the existing redirect rejection, archive safety checks, size limits, ownership enforcement, locking, journaling, and rollback protections. 9. Notify the user after any successful update and require a fresh review when permissions, endpoints, or executable scripts change. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares no permissions, yet its instructions clearly require shell execution, network access, local file handling, environment access, and package modification/update behavior through a bundled client. This is dangerous because it hides the real trust boundary from users and hosts, making powerful capabilities available without explicit consent or policy review.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The stated purpose is a narrow content-generation workflow, but the referenced behavior includes OAuth login, persistent credential storage, generic remote tool invocation, local file upload, telemetry/registration, uninstall cleanup, and self-updating code. That mismatch is dangerous because users may authorize a simple media skill while actually granting a much broader software agent with ongoing remote-control and system-modifying capabilities.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
This documentation introduces a built-in self-updating mechanism that is unrelated to the stated purpose of a legal explainer clip skill. Even though the text describes integrity checks, silent update logic expands the trust boundary and creates an unnecessary software modification pathway that could be abused or could mask unauthorized behavior inside a marketing/content-generation tool.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Silent downloading and replacement of package files is a high-risk capability for a skill whose purpose is legal explainer content generation. Default-on autonomous updates can alter code before ordinary commands run, giving the component persistent modification capability that users may not expect and that is disproportionate to the business function of the skill.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The OAuth scope set is materially broader than the skill’s stated purpose of producing a legal explainer clip. In addition to artifacts and image/video generation, it requests music generation, speech generation, voice read/write, task control, and wallet spending, creating an unnecessary high-value token that could be abused for unrelated content generation or billable actions if the credential is compromised or the backend misuses the granted access.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The code persists host platform, device name, installed skill slug, and resolved install path into local inventory/config files even though that telemetry is not clearly necessary to authorize a legal explainer clip skill. This expands collection of environment metadata and creates a local tracking surface that could reveal agent type, host identity, and filesystem layout to other local processes or future components that read these files.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The file implements a full self-update and package-management mechanism that can download, validate, and replace local package files, which materially exceeds the advertised purpose of generating legal explainer media. Even with checksum and path validation, this expands the trust boundary to remote update infrastructure and gives the skill code the ability to silently modify itself at runtime, making compromise of the update channel or publisher infrastructure highly impactful.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The code records local skill inventory and sends installation-registration telemetry unrelated to the skill's stated legal-explainer function. This creates unnecessary metadata collection about installed packages, paths, versions, and platform context, increasing privacy and tracking risk without clear user benefit.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The host_platform logic fingerprints the execution environment using environment variables and local state, then propagates that information in tool calls and telemetry. For a legal explainer content skill, this is not functionally justified and increases privacy risk while enabling environment-aware behavior that could differ across agent hosts.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that the bundled client can silently install newer releases automatically without separate confirmation. Even with signature verification claims, unattended code replacement materially increases supply-chain and trust risks because behavior can change after approval, potentially gaining new capabilities or altering execution without fresh review.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation states that the client installs higher versions automatically without separate confirmation. Modifying installed files without explicit approval reduces user control and transparency, and in this skill context it is especially suspicious because legal-video generation does not require silent software maintenance to fulfill user requests.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation states that the bundled client automatically performs a registration call on first use and writes a local cache file, but it does not present this behavior as something users should explicitly expect or consent to. Even though the transmitted data is described as non-secret and non-billable, silent network transmission and filesystem writes create a transparency and privacy risk, especially in enterprise or regulated environments where outbound calls and local persistence may require approval.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The maybe_auto_update path performs silent best-effort updates before normal commands without user-facing notice at runtime. In the context of a marketing-content skill, automatic self-modification is especially risky because users would not reasonably expect a legal explainer tool to rewrite installation files during ordinary use, and any compromise of update infrastructure would propagate silently.

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
96% confidence
Finding
The CLI exposes explicit self-update functionality, allowing the package to replace its own installed files. Self-modifying behavior is dangerous in a skill whose declared purpose is unrelated to package management because it increases supply-chain risk and gives a content-generation tool the capability to alter executable code on disk.

Static analysis

No suspicious patterns detected.