Back to skill

Security audit

Hall Guide Voice Pack

Security checks for vulnerabilities and agentic risk

Overview

The skill is not clearly malicious, but it needs review because a narrow voice-clip tool requests broad paid Beatra permissions and silently updates executable code by default.

Install only if you are comfortable granting Beatra a broad shared device token that can cover paid media operations beyond speech, and with package code updating silently unless disabled. Review the Beatra approval screen, consider running the documented command to turn automatic updates off, and revoke the device in the Beatra Console if you no longer want this access.

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
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (6)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding

Silent Automatic Updates Permit Remotely Controlled Code Replacement Without Independent Signature Verification

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:969-1018
Additional Locations: scripts/mcp_client.py:31-32, scripts/mcp_client.py:469-491, scripts/mcp_client.py:1543; SKILL.md:183-203; references/automatic-updates-and-safety.md:3-19
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

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
...[truncated 3039 chars]
Remediation
View remediation

Remediation Suggestions

  1. Disable automatic code replacement by default and require explicit user approval before installing each update.
  2. Sign release metadata and packages with a private release key, and pin the corresponding public key in the audited client.
  3. Prefer a framework such as TUF with root metadata, threshold signatures, expiration, version rollback protection, and key rotation.
  4. Verify signatures before trusting any remotely supplied checksum or version.
  5. Separate update checking from update installation so ordinary business calls cannot implicitly modify executable files.
  6. Display the target version and verified publisher identity before installation.
  7. Preserve the existing archive-path, size, ownership, staging, rollback, and redirect protections as defense-in-depth.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:34
Finding

Authorization Requests Broad Paid Media Permissions Beyond the Skill’s Declared Speech Function

Content
View full analysis

Vulnerability Details

File Location: scripts/authorize.py:34-37
Additional Locations: references/installation-and-auth.md:73-74; references/mcp-connection.md:9-10
Vulnerability Type: Excessive OAuth scope and violation of least privilege
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"
)

Technical Analysis

The Skill’s declared purpose is to produce hall-guide speech clips and optionally clone an authorized voice. Nevertheless, authorization requests permissions for image, video, and music generation in addition to speech generation, voice writing, artifact access, wallet spending, task reading, and cancellation.

Image, video, and music generation are not necessary to satisfy the declared hall-guide voice workflow. A single persistent shared bearer token therefore combines unrelated paid generation capabilities with upload, spending, task inspection, and cancellation privileges.

This exceeds the minimum privileges necessary for the Skill. The broad scope also magnifies other risks because the bundled client accepts arbitrary MCP tool names.

Attack Path

  1. The user approves the device authorization for the Skill.
  2. Beatra issues a token containing the complete broad scope.
  3. The token is stored in ~/.beatra/credentials.json and reused by the bundled generic MCP client.
  4. An attacker who steals the token, compromises the client, or influences tool selection invokes an unrelated image, video, or music operation.
  5. The server accepts the operation because the token already includes the corresponding generation and spending permissions.

Impact Assessment

Misuse can consume account credits for unrelated media generation, create or modify voice resources, inspect artifacts and tasks ...[truncated 178 chars]

Remediation
View remediation

Remediation Suggestions

  1. Issue a package-specific credential limited to speech generation and the precise voice operations required by this Skill.
  2. Remove images:generate, videos:generate, and music:generate.
  3. Scope artifact access to artifacts created or explicitly selected for the current package.
  4. Limit task read and cancellation rights to tasks created by this package or installation.
  5. Separate wallet-read permissions from wallet-spend permissions.
  6. Require a distinct, explicit authorization event before enabling voice cloning, cancellation, or other optional privileged functions.
  7. Avoid sharing one full-scope token across unrelated Beatra Skills.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/mcp_client.py:1459
Finding

Generic MCP Dispatcher Does Not Restrict Tool Names to the Skill’s Required Operations

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:1459-1477
Additional Locations: scripts/mcp_client.py:1488-1489, scripts/mcp_client.py:1548-1553
Vulnerability Type: Unrestricted privileged tool dispatch
Risk Level: High

Vulnerable Code:

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 command-line parser accepts an arbitrary tool name:

python
call = subparsers.add_parser("call", help="Call one tool with a JSON object on stdin")
call.add_argument("tool_name")

Technical Analysis

The bundled client acts as a generic MCP dispatcher. It forwards any caller-supplied tool_name to tools/call without comparing it against a local allowlist.

The documentation tells the agent which tools should normally be used, but documentation is not an authorization control. An injected instruction, erroneous agent decision, malicious local caller, or future remote response can select any MCP tool exposed by the server. The server-side bearer credential has broad generation and spending scopes, making the absence of local restriction security-relevant.

Attack Path

  1. The user authorizes the broad shared Beatra credential.
  2. An attacker influences the ...[truncated 705 chars]
Remediation
View remediation

Remediation Suggestions

  1. Implement a hardcoded package-specific allowlist of permitted tool names.
  2. Limit the list to required model discovery, voice listing, speech synthesis, optional voice cloning, explicit asset upload, wallet reads, and package-owned task operations.
  3. Reject unknown tool names before establishing a session or sending credentials.
  4. Apply argument-level validation for sensitive tools, including task ownership and permitted capability values.
  5. Place optional privileged tools, such as voice cloning or cancellation, behind explicit user-confirmation gates.
  6. Pair the local allowlist with least-privilege server-side scopes; neither control should be used as a substitute for the other.

other

Warning
Location
scripts/authorize.py:340
Finding

Authorization Collects and Transmits Hostname and Agent-Environment Telemetry

Content
View full analysis

Vulnerability Details

File Location: scripts/authorize.py:340-368
Additional Locations: scripts/authorize.py:451-468; scripts/mcp_client.py:1139-1167; scripts/mcp_client.py:1200-1228
Vulnerability Type: Unnecessary host information disclosure
Risk Level: Medium

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 values are added to authorization data:

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:
    fo
...[truncated 1604 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove hostname collection and transmission.
  2. Use only a randomly generated opaque installation identifier where device distinction is necessary.
  3. Make agent-platform telemetry opt-in and disclose it before authorization.
  4. Do not attach platform telemetry to every business operation unless required for a documented security purpose.
  5. Provide a privacy-preserving mode that transmits unknown for platform and an anonymous device label.
  6. Document retention, correlation, and deletion policies for installation telemetry.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mcp_client.py:231
Finding

Server-Directed Upload Grants Allow Local Media to Be Sent to Any HTTPS Host

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:231-264
Vulnerability Type: Insufficient validation of an externally supplied upload destination
Risk Level: Medium

Vulnerable Code:

python
def _complete_upload(
    result: dict[str, Any],
    *,
    mime_type: str,
    content: bytes,
    put_bytes: PutBytes,
) -> dict[str, str]:
    structured = result.get("structuredContent")
    instruction = structured.get("upload") if isinstance(structured, dict) else None
    if not isinstance(instruction, dict) or instruction.get("method") != "PUT":
        raise RuntimeError("Beatra upload instructions are invalid")
    url = instruction.get("url")
    headers = instruction.get("headers")
    if not isinstance(url, str) or not isinstance(headers, dict):
        raise RuntimeError("Beatra upload instructions are invalid")
    parsed = urllib.parse.urlsplit(url)
    if (
        parsed.scheme != "https"
        or not parsed.hostname
        or parsed.username is not None
        or parsed.password is not None
        or parsed.fragment
    ):
        raise RuntimeError("Beatra upload instructions are invalid")
    if not all(isinstance(key, str) and isinstance(value, str) for key, value in headers.items()):
        raise RuntimeError("Beatra upload instructions are invalid")
    content_type = _header_value(headers, "Content-Type")
    content_length = _header_value(headers, "Content-Length")
    if content_type != mime_type or content_length != str(len(content)):
        raise RuntimeError("Beatra upload instructions are invalid")
    response = put_bytes(url, dict(headers), content)
    artifact_id = response.get("artifact_id")
    if not isinstance(artifact_id, str) or not artifact_id:
        raise RuntimeError("Beatra upload returned an invalid response")
    return {"type": "artifact", "artifact_id": artifact_id}

Technical Analysis

The ...[truncated 1718 chars]

Remediation
View remediation

Remediation Suggestions

  1. Enforce an exact allowlist of approved upload hostnames and, where possible, path prefixes.
  2. Reject IP-literal hosts, loopback addresses, private-network destinations, unexpected ports, and nonstandard storage domains.
  3. Require upload grants to be digitally signed and bind the signature to the hostname, path, method, file digest, MIME type, size, expiration time, and installation identity.
  4. Verify the local file digest against the signed grant before upload.
  5. Display the approved destination domain before sending sensitive voice samples.
  6. Use short-lived, single-use grants and reject replayed or expired grants.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mcp_client.py:1044
Finding

Windows Credential Confidentiality Relies on Unverified Inherited ACLs

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:1044-1051
Additional Locations: scripts/authorize.py:121-134; references/installation-and-auth.md:16-20
Vulnerability Type: Insufficient local credential access-control validation
Risk Level: Medium

Vulnerable Code:

python
def _read_private_credentials(state_dir: Path, path: Path) -> str:
    if os.name == "nt":
        # The state directory lives under the user profile, whose default
        # ACL is already private to the user (the gh/aws/gcloud posture).
        # The former custom DACL verification was dropped deliberately: its
        # command patterns read as hostile to agent safety policies and
        # endpoint security, failing installs while adding nothing an
        # elevated administrator could not bypass.
        return path.read_text(encoding="utf-8")

The related authorization helper likewise applies explicit permissions only on POSIX:

python
def _private_directory(path: Path) -> None:
    path.mkdir(mode=0o700, parents=True, exist_ok=True)
    if os.name == "posix":
        path.chmod(0o700)


def _restrict_file(path: Path) -> None:
    if os.name == "posix":
        path.chmod(0o600)

Technical Analysis

On POSIX, the client validates that the state directory is owned by the current user with mode 0700 and that the credential is a regular user-owned file with mode 0600. On Windows, it simply reads the file and assumes the inherited user-profile ACL is private.

This assumption may fail on systems with modified profile ACLs, shared workstations, enterprise policy changes, restored files, migrated profiles, or manually created state directories. The documentation claims that the current user must be the only principal granted access, but the implementation does not establish or verify that property.

Attack Path

  1. The Skill creates or uses `~/.beatra/credentials.js ...[truncated 673 chars]
Remediation
View remediation

Remediation Suggestions

  1. Store the token using Windows Credential Manager or protect it with DPAPI rather than relying solely on filesystem inheritance.
  2. If a file must be used, create an explicit DACL granting access only to the current user and necessary system administrators.
  3. Verify the effective ACL before every credential read and fail closed if unintended principals have read access.
  4. Reject reparse points and verify file ownership and type using Windows-native APIs.
  5. Keep the existing POSIX ownership, mode, regular-file, and no-follow checks.
  6. Reduce token scope and lifetime so that any local credential disclosure has a smaller impact.
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 Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (47)

Context-Inappropriate Capability

Critical
Category
Not specified by scanner
Confidence
99% confidence
Finding

The scope includes unrelated media-generation permissions such as images:generate, videos:generate, and music:generate even though the skill is presented as a hall guide voice-pack tool. These excess permissions expand what an attacker or compromised skill could do with the user's account and make the authorization misleading relative to the skill's stated purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Documentation indicates the package can perform uninstall and token-revocation workflows even though the skill claims to generate hall guide clips. Hidden removal and state-deletion capabilities are dangerous because they can modify the local environment and credentials in ways unrelated to the advertised task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Documentation indicates the package can perform uninstall and token-revocation workflows even though the skill claims to generate hall guide clips. Hidden removal and state-deletion capabilities are dangerous because they can modify the local environment and credentials in ways unrelated to the advertised task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Documentation indicates the package can perform uninstall and token-revocation workflows even though the skill claims to generate hall guide clips. Hidden removal and state-deletion capabilities are dangerous because they can modify the local environment and credentials in ways unrelated to the advertised task.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 71)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 115)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 137)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 141)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 149)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 201)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 202)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 203)May include surrounding context.

md
(`scripts/mcp_client.py` / `beatra.assets.upload`). Keep the returned

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Referencing a local credentials file is a credential-access pattern because the skill is explicitly configured to consume authentication material from the user's home directory. In the context of an innocuous-sounding audio packaging skill, this is more dangerous because the requested capability is not obviously necessary, making covert credential reuse or account access harder for users to anticipate.

Content

Scanner excerpt · manifest.json (reported line 53)May include surrounding context.

json
},
  "mcp": {
    "authentication": "device-bearer",
    "credential_file": "~/.beatra/credentials.json",
    "name": "beatra",
    "transport": "streamable-http",
    "url": "https://mcp.beatra.ai/mcp"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/installation-and-auth.md (reported line 14)May include surrounding context.

text

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/installation-and-auth.md (reported line 21)May include surrounding context.

text

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/installation-and-auth.md (reported line 49)May include surrounding context.

text

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/mcp-connection.md (reported line 10)May include surrounding context.

text

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/authorize.py (reported line 207)May include surrounding context.

python
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/authorize.py (reported line 514)May include surrounding context.

python
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/mcp_client.py (reported line 1025)May include surrounding context.

python
```

They share the one full-scope Device Token stored in
`~/.beatra/credentials.json`. Installing or switching packages must not trigger
another authorization when that credential is already valid. Do not add,
enable, trust, or configure a host Beatra Connector. Never print or move the
token into command arguments, environment variables, logs, chat, or another

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The OAuth scope request is far broader than the stated purpose of generating hall guide voice clips. It asks for unrelated capabilities including artifacts, images, videos, music, tasks, and voice management, violating least privilege and increasing the blast radius if the credential is abused or the skill is compromised.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The scope includes unrelated media-generation permissions such as images:generate, videos:generate, and music:generate even though the skill is presented as a hall guide voice-pack tool. These excess permissions expand what an attacker or compromised skill could do with the user's account and make the authorization misleading relative to the skill's stated purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file implements broad networked capability far beyond a hall-guide voice generation skill: generic remote MCP tool invocation, asset upload, installation registration, and package self-update. This expanded authority materially increases attack surface and enables the skill to act as a general remote-control client rather than a narrowly scoped media utility, making misuse or server compromise much more dangerous in this context.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

The CLI explicitly supports package self-update, and the codebase includes logic to download, validate, and replace installed files. In a narrowly purposed voice skill, self-modification is especially risky because it enables post-installation code changes, increases supply-chain exposure, and undermines the expectation that reviewed code remains the code being run.

Content

Scanner excerpt · scripts/mcp_client.py (reported line 1503)May include surrounding context.

python
)
    update = subparsers.add_parser(
        "update",
        help="Check, install, or configure Beatra package self-updates",
    )
    update.add_argument(
        "--check",

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The uninstall script manages shared device credentials and performs remote token revocation, which is far outside the stated purpose of a hall-guide voice generation skill. Even if intended as cleanup, this gives the package authority over account/device authorization and shared local state, creating a strong capability mismatch that could disrupt other installed skills or the user's device access if triggered incorrectly.

Content

No source excerpt is available for this finding.