Back to skill

Security audit

Walk-in Talking Clips

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its clip-generation purpose, but it stores a broad Beatra credential and silently updates its own executable code, so it belongs in Review before installation.

Install only if you are comfortable with Beatra receiving authorized property media and with this package using a shared Beatra Device Token that can spend credits and access more media tools than this workflow needs. For a lower-risk setup, turn automatic updates off before normal use, review each paid confirmation card carefully, monitor wallet charges, and revoke the Beatra device authorization when you no longer need it.

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:31
Finding
Overprivileged Device Token and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:31-34`; `scripts/mcp_client.py:1458-1489` **Vulnerability Type**: Excessive authorization scope and unrestricted use of remote tools **Risk Level**: Medium ### Vulnerable Code Authorization requests capabilities unrelated to the declared rental walk-in workflow: ```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 command interface accepts an arbitrary MCP tool name without enforcing a package-specific allowlist: ```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}, ) ``` The CLI exposes that arbitrary tool-name parameter directly: ```python call = subparsers.add_parser("call", help="Call one tool with a JSON object on stdin") call.add_argument("tool_name") ``` ### Technical Analysis The declared workflow requires artifact upload, model discovery, voice listing or cloning, speech generation, video generation, task reads, optional task cancellation, and wallet queries. It does not require music generation or independent image generation. Nevertheless, authorization requests `music:generate` and `images:generate`, along with the broad `mcp:tools` ...[truncated 2290 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope authorization with a package-specific, least-privilege grant. 2. Remove capabilities not required by this Skill, particularly: - `images:generate` - `music:generate` 3. Narrow generic capabilities such as `mcp:tools` and `wallet:spend` where the service supports more granular scopes. 4. Add a strict local allowlist before dispatching `tools/call`. It should contain only the operations required by the documented workflow, such as: - `beatra.assets.upload` - `beatra.models.list` - `beatra.voices.list` - `beatra.voices.clone` - `beatra.speech.synthesize` - `beatra.videos.animate` - `beatra.tasks.get` - `beatra.tasks.list` - `beatra.tasks.cancel` - `beatra.wallet.get` - `beatra.wallet.ledger` - `beatra.installations.register` 5. Reject every unrecognized tool name before initializing or contacting the remote service. 6. Separate read-only, upload, and billable capabilities into distinct tokens or grants where supported. 7. Preserve the existing explicit confirmation requirements for paid clone, speech, and video stages, and enforce those boundaries in code rather than relying only on Skill instructions. 8. Add automated tests proving that unrelated tools, including image and music generation, cannot be invoked through this package. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/mcp_client.py:969
Finding
Default Silent Retrieval and Replacement of Executable Skill Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:31-32`, `scripts/mcp_client.py:469-490`, `scripts/mcp_client.py:969-1019`, `scripts/mcp_client.py:1542-1544` **Vulnerability Type**: Automatic retrieval and installation of remotely changeable executable code **Risk Level**: Medium ### Vulnerable Code Update metadata and package content are retrieved from vendor-controlled remote endpoints: ```python PACKAGE_DISCOVERY_URL = "https://beatra.ai/skills/rental-walkin-avatar/channels/clawhub/install.json" PACKAGE_CDN_BASE_TEMPLATE = "https://cdn.beatra.ai/agent-packages/rental-walkin-avatar/channels/clawhub/v{version}" ``` The update is authenticated only by hashes supplied through the same vendor-controlled discovery chain: ```python def download_update( discovery: dict[str, Any], *, get_bytes: GetBytes = _default_get_bytes, ) -> tuple[dict[str, Any], dict[str, bytes]]: archive_url, manifest_url = _release_urls(discovery) manifest_content = get_bytes( manifest_url, UPDATE_DOWNLOAD_TIMEOUT_SECONDS, MAX_UPDATE_MANIFEST_BYTES, ) if _sha256(manifest_content) != discovery["manifest_sha256"]: raise RuntimeError("Beatra update manifest checksum does not match discovery") manifest = _json_object(manifest_content, "Beatra update manifest") manifest_files = _manifest_files(manifest, discovery=discovery) archive = get_bytes( archive_url, UPDATE_DOWNLOAD_TIMEOUT_SECONDS, MAX_UPDATE_ARCHIVE_BYTES, ) if _sha256(archive) != discovery["archive_sha256"]: raise RuntimeError("Beatra update archive checksum does not match discovery") return manifest, _validated_archive(archive, manifest_files=manifest_files) ``` Silent automatic installation is enabled by default: ```python def maybe_auto_update( *, state_dir: Path | None = None, install_root: Path | None = None, get_bytes: GetBytes = _default_get_bytes, now: float | N ...[truncated 4788 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default. Update checks should be notification-only unless the user explicitly enables installation. 2. Require explicit user confirmation before replacing executable package files. 3. Digitally sign release metadata with an offline or otherwise independently protected signing key. 4. Embed or securely pin the corresponding public key in the reviewed client. 5. Verify a detached signature over the package identity, channel, locale, version, manifest digest, and archive digest before accepting an update. 6. Use a signed metadata framework with rollback and freeze protections, such as The Update Framework principles, rather than relying solely on vendor-supplied hashes. 7. Separate update checking from ordinary billable and upload commands so routine operation does not silently mutate executable code. 8. Display the proposed version, release identity, signer, and changed-file list before installation. 9. Preserve the existing fixed-host, redirect rejection, path validation, size limits, ownership checks, transactional replacement, and rollback controls. 10. Add a policy preventing the updater from replacing itself unless the new client is independently signature-verified. 11. Record an auditable installation receipt containing the signed release identity and verified manifest digest. 12. Document hostname/platform telemetry and update behavior prominently during installation so users can make an informed choice before enabling either feature. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares no permissions while instructing use of shell execution, local file access, network calls, environment use, and file writes via the bundled client and update flow. This creates a transparency and consent problem: operators may approve or run the skill without understanding that it can access local files, persist credentials, contact remote services, and modify package-owned files.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The published purpose suggests a narrow media-generation workflow, but the skill also performs authentication, persistent credential storage, remote tool invocation, file upload, telemetry/registration, uninstall/revocation actions, and self-updating code replacement. That mismatch is dangerous because users may provide sensitive images, voices, and local files under the assumption of a simple content skill, while the package has materially broader system and network behavior than advertised.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill states that the bundled client silently checks for and installs newer releases automatically without separate confirmation. Even with signature verification, silent self-update materially expands the trust boundary: a package that can execute networked operations and handle local files can also replace its own code, changing behavior after initial review and enabling supply-chain compromise or unexpected new capabilities.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The document describes a client that silently checks for and automatically installs updates by default before normal commands, without requiring a separate confirmation at install time. Even with integrity checks, redirects blocked, and rollback protections, automatic code replacement changes the local installation and trust boundary without explicit user consent for each modification, which creates supply-chain and operational risk if the update source, signing/checksum process, or release pipeline is ever compromised.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation states that the client automatically performs an installation registration call and writes a local cache file, but it does not prominently warn users about the outbound telemetry and persistence behavior before first use. Even though the data described is limited and non-secret, automatic transmission of package, version, platform, and stable installation reference can have privacy and enterprise policy implications if users are unaware of it.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The script persists detected host metadata such as platform and device name into a local host.json file without any explicit user-facing disclosure or consent. While the data is not highly sensitive by itself, hostname and agent-environment information can expose system-identifying details and expand the local privacy footprint beyond what a user may expect from a simple authorization helper.

Missing User Warnings

Low
Confidence
91% confidence
Finding
The script records a local inventory of installed skills including the resolved installation path in skills.json without explicit disclosure to the user. Installation paths can reveal usernames, directory layouts, and tooling habits, creating a privacy issue and unnecessary local data retention if that detail is not essential.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The client performs silent automatic self-updates and then overwrites files in its own installation directory, including executable code, during normal command execution. Although the code includes substantial integrity checks, this still creates a supply-chain and unexpected code-change risk because execution behavior can change without an explicit user action or prominent runtime disclosure.

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
91% confidence
Finding
The package contains built-in self-modification capability via its update flow, allowing it to replace its own installed files. Even with hash verification and destination safety checks, self-modifying code materially increases supply-chain risk and can make post-install behavior differ from what was originally reviewed or approved.

Static analysis

No suspicious patterns detected.