Back to skill

Security audit

voice-clone-series-studio

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real voice-cloning workflow, but it grants broader Beatra account powers and silently updates local package code, so it should be reviewed before installation.

Install only if you are comfortable granting this package a shared Beatra device credential that covers more than voice generation, allowing the bundled client to call Beatra tools with that credential, sending limited device/installation metadata, and accepting default silent package self-updates. Consider disabling automatic updates with the documented --auto off command and reviewing Beatra account permissions/credit use before authorizing.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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 Shared Device Credential and Unrestricted MCP Tool Invocation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:31-34`; `scripts/mcp_client.py:1472-1487` **Vulnerability Type**: Excessive authorization scope and unrestricted remote tool selection **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" ) ``` The client also accepts an arbitrary MCP tool name: ```python call = subparsers.add_parser("call", help="Call one tool with a JSON object on stdin") call.add_argument("tool_name") ``` The supplied name is passed directly to the remote MCP service: ```python return session.request( 2, "tools/call", {"name": tool_name, "arguments": arguments}, ) ``` ### Technical Analysis The declared purpose of this Skill is voice cloning and recurring speech synthesis. Its legitimate operations require access to voice cloning, speech generation, artifact upload, model discovery, task management, and relevant billing operations. The authorization request also obtains unrelated capabilities, including: - `images:generate` - `videos:generate` - `music:generate` In addition, the generic `call` command accepts any MCP tool name instead of restricting calls to the tools required by this Skill. The combination of a broadly scoped bearer token and unrestricted tool selection violates least-privilege principles. The excessive scopes are disclosed in the documentation as part of a shared full-scope credential, so this is not covert credential acquisition. Nevertheless, disclosure does not eliminate the security impact of granting permissions beyond the task’s legitimate needs. ### Attack Path 1. The user runs `scripts/authorize.py` to authorize the voice-cloning Skill. 2. The authorization server issues a bearer token containing voice, image, video, music, wallet, artifact, and task permissions. 3. The bearer to ...[truncated 1540 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope authorization with a package-specific, least-privilege token. 2. Remove unrelated scopes such as `images:generate`, `videos:generate`, and `music:generate`. 3. Limit the token to the exact operations required for this Skill, such as: - Artifact upload and read access needed for voice samples. - Voice read and clone/write operations. - Speech generation. - Model discovery. - Task read and user-confirmed cancellation. - The minimum wallet permissions required for estimates, spending, balances, and ledgers. 4. Introduce a local allowlist of permitted MCP tool names. Reject any tool outside the voice-cloning workflow before making a network request. 5. Separate credentials by Skill or capability group rather than sharing one full-scope token across unrelated packages. 6. Require explicit user confirmation immediately before invoking any billable tool, even if called through the generic client interface. 7. Add server-side policy enforcement binding the credential to the package slug and permitted tool set. Client-side allowlisting should supplement, not replace, server-side authorization. 8. Record auditable tool invocation metadata without storing prompts, tokens, or sensitive voice content. ]]>

other

Note
Location
scripts/authorize.py:347
Finding
Unnecessary Hostname and Agent-Environment Telemetry Collection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:347-368`, `scripts/authorize.py:435-445`; `scripts/mcp_client.py:1147-1164`, `scripts/mcp_client.py:1218-1228` **Vulnerability Type**: Environment reconnaissance and device telemetry **Risk Level**: Low ### Vulnerable Code The authorization helper identifies the Agent environment from process environment variables: ```python 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" ``` It also collects the local hostname: ```python 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 hostname and platform are included in the authorization request: ```python 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) ``` Subsequent tool calls receive source-attribution metadata: ```python if method == "tools/call": arguments = params.get("arguments") if isinstance(arguments, dict): arguments.setdefault("source_package_slug", PACKAGE_SLUG) arguments.setdefault("source_platform", host_platform()) ``` ### Technical Analysis The Skill detects the local Agent p ...[truncated 2147 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not collect or transmit the operating-system hostname by default. 2. Use a generic device label, such as `Voice Clone Series Studio`, or ask the user to choose a device name explicitly. 3. Make hostname-based device naming opt-in and present the exact value before transmission. 4. Clearly disclose all transmitted metadata before authorization, including: - Hostname or device label. - Agent platform. - Stable installation reference. - Package slug and version. 5. Provide a persistent telemetry-disable setting that omits `device_name`, `source_platform`, and optional installation registration. 6. Ensure disabling telemetry does not prevent authorization or creative operations. 7. Minimize server-side retention and prohibit using this metadata for unrelated profiling. 8. Keep platform detection limited to the selected signatures; do not expand it to enumerate the full environment. 9. Consider rotating or scoping the installation reference if permanent cross-session correlation is unnecessary. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (21)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill invokes a bundled Python client for uploads, task polling, updates, and related operations, which implies shell, filesystem, network, and possibly environment access despite no declared permissions. This mismatch is dangerous because users and hosting platforms cannot accurately assess or constrain what the skill can do, increasing the chance of over-privileged execution and unnoticed sensitive-data access.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The public description frames the skill as a voice-cloning workflow, but the referenced behavior includes OAuth authorization, persistent credential storage, telemetry/registration, arbitrary Beatra tool access, file upload, uninstall logic, and automatic self-update. That gap undermines informed consent and creates a broad hidden attack surface, especially because a 'general MCP client' could be repurposed beyond the narrow voice-cloning task users believe they are enabling.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The skill contains a self-updating runtime that can replace package-owned files as part of ordinary command execution, even though updating is not intrinsic to the voice-cloning task itself. Any mechanism that downloads and installs code during routine use materially increases supply-chain risk, and a compromise of the update channel, signing process, or client logic could result in silent code execution changes on the host.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The requested OAuth scope is far broader than what a voice cloning/narration setup helper should need. In addition to speech and voice permissions, it asks for images, videos, music, wallet spending, task control, and broad artifact access, violating least privilege and creating a large blast radius if the credential is misused or the skill is compromised.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
In the context of a skill advertised for voice cloning and recurring narration, provisioning a shared credential with unrelated service permissions is especially dangerous because users would not reasonably expect account-wide non-audio capabilities to be granted. This mismatch increases the chance of deceptive over-authorization and enables misuse of the user's account beyond the stated purpose of the skill.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
This client implements full package self-update logic that downloads manifests and archives, validates them, and replaces local installation files, which is outside the expected scope of a voice-cloning/narration skill. Even with checksum and path validation, embedding a code-update channel in a skill materially expands trust boundaries and allows remote code changes on the user's machine through normal skill execution paths.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The code records installation telemetry and a persistent local skill inventory in ~/.beatra, which is unrelated to the stated purpose of generating consistent narration from a cloned voice. This creates additional privacy-sensitive state and outbound reporting that users would not reasonably expect from a voice studio skill, increasing the risk of tracking and misuse of local metadata.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The skill fingerprints its execution environment by inspecting environment variables and persisted host metadata to derive the platform. For a voice-cloning studio skill, this is unnecessary to core functionality and increases privacy exposure while enabling backend-side segmentation or differential behavior by host environment.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The uninstall script explicitly manages shared Beatra connection state, credential lifecycle, and cross-skill inventory, which exceeds the narrow voice-cloning purpose described in the skill metadata. Even if framed as cleanup logic, this gives the skill awareness of and influence over other installed skills, expanding its authority beyond what a user would reasonably expect from a voice-cloning package.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
This code can revoke the shared device token and delete shared local state under ~/.beatra when it concludes no other skills remain. If the inventory is stale, tampered with, or incomplete, uninstalling this voice-related skill could disconnect unrelated Beatra skills and remove their credentials, creating an unnecessary cross-skill denial-of-service and giving this skill destructive capability unrelated to voice cloning.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill states that newer releases install 'without separate confirmation' during ordinary use, but the user-facing description does not prominently warn that the skill can modify local code and behavior over time. Silent code changes reduce user control and review opportunities, making any future defect or compromise more dangerous because it can propagate under the guise of a normal narration command.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The manifest markets a voice-cloning capability using phrases like 'clone one voice you own' but provides no explicit safety, consent, or authorization warning in the manifest metadata. Because voice cloning is a high-abuse domain that can enable impersonation, fraud, and non-consensual synthesis, the lack of prominent consent/ownership safeguards increases misuse risk and weakens downstream policy enforcement.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The document explicitly states that the client silently checks for updates by default and automatically installs newer releases without separate confirmation. Even with integrity checks and fixed update sources, default-on silent self-update modifies local code without an explicit user opt-in at the time of install or use, which creates supply-chain and user-consent risk if the update infrastructure or signing/check process is ever compromised or misunderstood.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation states that the client writes a persistent local cache at `~/.beatra/registrations.json` containing registration state, but it does not explicitly warn users that a file will be created and that metadata is retained across runs. This can undermine user expectations around privacy and persistence, especially on shared systems or managed environments where local artifacts may be inspected or backed up.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The file documents a remote `beatra.installations.register` call that transmits package slug, version, platform, and a stable external installation reference, but it does not clearly present this as telemetry or warn about the privacy implications of sending installation metadata off-host. A stable identifier combined with platform and package/version data can enable tracking or correlation of a user's installations over time.

Missing User Warnings

Medium
Confidence
82% confidence
Finding
The script persists host platform and device name to disk without explicit user disclosure. While not an immediate code-execution issue, this collects and stores host-identifying metadata that may be privacy-sensitive, especially on shared systems or environments where local state is inspected by other software or administrators.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The script records the installed skill's local filesystem path in a persistent inventory file without explicit user notice. Installation paths can reveal usernames, workspace names, repository names, or other environmental details, making this an unnecessary privacy exposure if not clearly disclosed and justified.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
maybe_auto_update() performs silent background updates and file replacement during normal command execution, explicitly designed to avoid blocking or warning the user. Silent modification of installed code at runtime is dangerous because it changes the executable trust base without contemporaneous user awareness or approval, which is especially risky in a skill unrelated to software maintenance.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The skill writes local inventory data and performs registration telemetry as best-effort background behavior without clear user-facing disclosure. While less severe than code self-update, this still creates hidden persistence and reporting beyond the expected voice-processing task.

Credential Access

High
Category
Privilege Escalation
Content
def _device_token(state_dir: Path) -> str | None:
    path = state_dir / "credentials.json"
    try:
        value = json.loads(path.read_text(encoding="utf-8"))
    except (OSError, ValueError):
Confidence
87% confidence
Finding
The function reads an access token from ~/.beatra/credentials.json and uses it to perform a revocation request, meaning the skill has direct access to shared device credentials. Even without exfiltration, allowing a voice-cloning skill to read and act on shared bearer tokens violates least privilege and creates a path to disrupt or potentially misuse the broader Beatra account context if the skill code is modified or abused.

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
95% confidence
Finding
The skill exposes self-update capability that can replace its own installed files, constituting self-modification. In the context of a voice-cloning skill, this is an unjustified and high-risk capability because it permits remote-delivered behavior changes outside the user's primary expectation and enlarges the attack surface for supply-chain compromise.

Static analysis

No suspicious patterns detected.