Back to skill

Security audit

YouTube Insurance Caption Talking

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it should be reviewed because it stores a broad Beatra token and can silently update its own local code.

Install only if you are comfortable giving this Beatra package a shared broad Beatra account token, allowing billable media operations through Beatra, uploading selected local media files to Beatra, and accepting default silent package updates. Security-sensitive users should disable automatic updates and prefer a future version with package-scoped authorization and a local tool allowlist.

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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:31
Finding
Over-Privileged Device Token and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:31-35`; `scripts/mcp_client.py:1452-1469` **Vulnerability Type**: Excessive OAuth scope and missing 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" ) ``` ```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 authorization helper requests a shared bearer token with broad capabilities, including wallet spending, task cancellation, music generation, image generation, voice creation, and general MCP tool access. Some of these permissions are unrelated to the declared caption-to-talking-video workflow. The command dispatcher then accepts an arbitrary `tool_name` and forwards it to `tools/call`. It does not enforce a package-specific allowlist. Consequently, the effective boundary is the broad server-issued token rather than the Skill’s declared functionality. This violates least privilege. Even if the broad token is intentionally shared by multiple Beatra packages, this Skill can use that credential to invoke operations beyond its own legitimate requirements. ### Attac ...[truncated 1064 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope credential with a package-specific token carrying only the permissions required by this Skill. 2. Remove unrelated permissions such as music generation and any other capabilities not used by the declared workflow. 3. Implement a strict local allowlist for permitted tool names, including only the required model, caption, upload, voice, speech, video, task, wallet-read, and installation-registration operations. 4. Enforce the same allowlist server-side so bypassing the bundled client does not restore excessive access. 5. Separate read-only wallet access from wallet spending privileges. 6. Require explicit, operation-specific user confirmation for task cancellation and billable operations. 7. Avoid sharing one broadly privileged token across packages with materially different functionality. 8. Add automated tests proving that unknown or unrelated MCP tool names are rejected before any network request is made. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/mcp_client.py:979
Finding
Default Silent Retrieval and Replacement of Executable Skill Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:979-1020`; update application logic at `scripts/mcp_client.py:875-909` **Vulnerability Type**: Mutable remote code update channel **Risk Level**: Medium ### Vulnerable Code ```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"]: return False _ensure_owned_baseline( install_root=resolved_root, update_home=update_home, get_bytes=get_bytes, ) discovery = checked["discovery"] manifest, new_files = download_update(discovery, get_bytes=get_bytes) _apply_update( install_ ...[truncated 3200 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default and require informed user approval before replacing executable files. 2. Separate update checking from update installation. 3. Sign release manifests using an offline-protected signing key and embed or securely pin the corresponding verification key in the client. 4. Verify a signature over the package identity, channel, version, archive digest, and complete file manifest. 5. Implement signed rollback protection so a compromised discovery service cannot select an older trusted but vulnerable release. 6. Display the source version, destination version, changed files, and requested replacement before installation. 7. Preserve the existing URL, redirect, archive, file-ownership, transaction, and rollback controls. 8. Encourage security-sensitive deployments to run: ```text python3 scripts/mcp_client.py update --auto off ``` until signed and consent-based updates are available. ]]>

other

Note
Location
scripts/authorize.py:342
Finding
Hostname, Agent Platform, and Stable Installation Metadata Are Transmitted During Authorization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:342-369`; transmission at `scripts/authorize.py:467-480` **Vulnerability Type**: Device telemetry and privacy exposure **Risk Level**: Low ### Vulnerable Code ```python def detect_host_platform(explicit: str | None = None) -> str: """The agent environment this process runs inside (docs/device-model.md). Order: explicit agent self-report > environment signatures > unknown. Detection reads the process environment only — nothing else runs, nothing reaches the network. """ if explicit: candidate = explicit.strip().lower().replace(" ", "-") if _PLATFORM_VALUE.fullmatch(candidate): return candidate env = os.environ if env.get("CLAUDECODE") == "1" or "CLAUDE_CODE_ENTRYPOINT" in env: return "claude-code" if any(key.startswith("CODEX_") for key in env): return "codex" ai_agent = env.get("AI_AGENT", "").lower() matched = re.match(r"([a-z0-9-]+)_", ai_agent) if matched and _PLATFORM_VALUE.fullmatch(matched.group(1)): return matched.group(1) return "unknown" def device_display_name() -> str | None: """A hostname the user will recognise in the console device list.""" try: name = socket.gethostname().strip() except OSError: return None if not name or not name.isprintable(): return None return name[:120] ``` The collected values are added to the authorization request: ```python external_reference = _installation_reference(state_dir) form: dict[str, str] = { "client_id": CLIENT_ID, "resource": MCP_URL, "scope": SCOPE, "platform": host_platform, "client_name": PACKAGE_DISPLAY_NAME, "external_installation_ref": external_reference, "package_version": PACKAGE_VERSION, "package_slug": PACKAGE_SLUG, } if device_name: form["device_name"] = device_name status, created = post_form(DEVICE_AUTHORIZATION_URL, form) ``` ### Te ...[truncated 1740 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make hostname collection opt-in rather than automatic. 2. Use a random or user-selected display label by default. 3. Show the exact metadata fields that will be transmitted before starting authorization. 4. Permit users to omit `device_name`, platform attribution, or the stable installation reference where they are not operationally required. 5. Define and disclose retention, deletion, and account-correlation policies for installation telemetry. 6. Continue limiting platform detection to explicit signatures and avoid expanding it into general environment enumeration. 7. Ensure telemetry is not required for core creative operations and does not affect authorization or billing decisions. ]]>
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 (16)

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill exposes broad operational capabilities—environment access, file read/write, network, and shell—without declaring permissions or clearly constraining their use. In this context, those capabilities are sufficient to access local data, invoke external services, modify files, and execute commands, which materially expands the trust boundary beyond a caption-to-video workflow.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented behavior goes well beyond the advertised purpose: it performs authentication, stores bearer credentials in the user's home directory, uploads local files, contacts remote services, registers the installation, self-updates, and may revoke auth or delete local state on uninstall. This mismatch undermines informed consent and can expose sensitive files, tokens, and host integrity in ways a user would not reasonably expect from a caption-processing skill.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill includes a bundled client that can download and install newer releases automatically, which is effectively a software installation and code-replacement mechanism embedded inside a content-production skill. Even with stated verification, auto-update introduces supply-chain risk and lets future code changes gain execution and file-write privileges without task-specific re-approval.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
An automatic software update capability is not necessary for the stated job of turning captions into short talking clips, so it unnecessarily enlarges the attack surface. Any mechanism that downloads and replaces package-owned files creates a persistent path for unintended or compromised code changes on the host.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The OAuth scope string requests a very broad set of capabilities, including artifacts, images, videos, music, speech, voices, task control, and wallet spending, while the skill is described only as turning YouTube insurance captions into talking clips. This violates least privilege and means that if the skill, its dependencies, or its stored token are abused, an attacker gains much more access than is needed for the advertised workflow.

Context-Inappropriate Capability

Critical
Confidence
98% confidence
Finding
The scope includes unrelated capabilities such as music generation, voice management, broad artifact access, task read/cancel, and write privileges that do not align with a simple caption-to-talking-clip pipeline. Excess account-management and generation privileges expand blast radius and allow misuse of the token for unrelated operations if the skill or credential store is abused.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The scope includes unrelated capabilities such as music generation, voice management, broad artifact access, task read/cancel, and write privileges that do not align with a simple caption-to-talking-clip pipeline. Excess account-management and generation privileges expand blast radius and allow misuse of the token for unrelated operations if the skill or credential store is abused.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The client implements broad remote capability beyond the advertised caption-to-talking-clip purpose: generic MCP tool invocation, package self-update, upload support, and installation telemetry. This mismatch expands trust and attack surface significantly, because a media skill can act as a general remote command client to a backend and modify its own installed code.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The code fingerprints the host environment and injects source_package_slug and source_platform into every tools/call request. This creates persistent cross-call attribution and environment disclosure unrelated to the stated media task, increasing privacy risk and enabling backend profiling of user environments.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The skill persistently records local skill inventory and registration telemetry under ~/.beatra and sends installation registration data to a remote service. That behavior is unrelated to turning captions into clips and creates unnecessary local tracking plus outbound telemetry about installed software and usage.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation says updates can install automatically without separate confirmation, yet it does not prominently warn users that the process performs network downloads and modifies local files. This weakens informed consent and makes it easier for a user to unknowingly permit code changes on their system.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The document states that the client silently checks for and automatically installs updates by default before normal commands, without explicit opt-in or prominent warning about network activity, code changes, and possible operational impact. Even though integrity controls are described, silent auto-update behavior can surprise users, affect reproducibility, and create privacy and change-management risk on systems where unprompted outbound connections or software modification are sensitive.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The documentation states that the bundled client automatically performs an installation registration call and writes a local cache file, but it does not clearly warn users about this outbound telemetry and persistence behavior before first use. While the data described is limited and non-secret, undisclosed network transmission and local state creation can violate user expectations, privacy requirements, or organizational policies in restricted environments.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The workflow explicitly instructs uploading a local file through a client to an external service but does not require any explicit user consent, disclosure, or confirmation that local content will leave the local environment. In a skill that may process user-provided media, this creates a real risk of unintended exfiltration of sensitive local files, especially if operators assume 'local file' handling remains local.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
maybe_auto_update() performs silent network checks, downloads, and local file replacement on normal execution paths without contemporaneous user confirmation. Even with integrity checks, silent code replacement increases supply-chain risk and makes a content-processing skill more dangerous because its behavior can change outside the user's immediate awareness.

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 package includes a built-in self-update mechanism that can overwrite local installation files, i.e., self-modification of executable code. In a skill whose stated function is media generation, this materially increases risk because future behavior can change through network-delivered code, making review and trust decisions time-variant.

Static analysis

No suspicious patterns detected.