Back to skill

Security audit

Insurance Clause Talking Clips

Security checks for vulnerabilities and agentic risk

Overview

This skill can make the advertised insurance talking clips, but it also uses broad account permissions, shared credentials, telemetry, and automatic self-updates that deserve careful review before installation.

Install only if you are comfortable with a Beatra account connection that can spend credits, upload selected files, store a shared local bearer credential, report package/platform registration data, and silently update this skill by default. Consider disabling automatic updates with the documented command, reviewing Beatra account activity, and avoiding sensitive insurance documents or images unless you accept sending them to Beatra for processing.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:34
Finding
Overprivileged Shared Device Token and Unrestricted MCP Tool Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:34-38`; unrestricted tool dispatch at `scripts/mcp_client.py:1463-1481` **Vulnerability Type**: Excessive authorization scope and missing client-side 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" ) ``` The bundled client subsequently accepts any MCP tool name supplied through its command-line interface: ```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 declared Skill workflow requires uploading user-selected assets, optionally cloning a voice, synthesizing speech, generating talking videos, inspecting models, and reading task results. The requested authorization additionally grants unrelated capabilities such as `images:generate` and `music:generate`. The credential is shared among Beatra Skills and includes permission to spend wallet credits, read artifacts, generate media, and cancel tasks. The client does not restrict `tool_name` to the small set required by this Skill. Consequently, compromise of the package or its update channel would expose all server-si ...[truncated 1488 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the shared full-scope credential with a package-specific, least-privilege token. 2. Remove permissions that are not required by this Skill, particularly `images:generate` and `music:generate`. 3. Review whether broad artifact reads and task cancellation are required; grant them only if the corresponding workflow is used. 4. Add a hardcoded client-side allowlist for this package, such as: - `beatra.assets.upload` - `beatra.models.list` - `beatra.voices.list` - `beatra.voices.clone` - `beatra.speech.synthesize` - `beatra.videos.animate` - Required task and wallet read operations 5. Reject all other tool names before reading or using the credential. 6. Enforce the same package-specific restrictions server-side so bypassing the local client does not restore excessive access. 7. Use separate authorization grants for materially different capabilities, especially wallet spending and voice cloning. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding
Silent Automatic Replacement of Executable Skill Files Without Independent Release Signatures<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:969-1018`; automatic invocation at `scripts/mcp_client.py:1543` **Vulnerability Type**: Automatic remote payload retrieval and executable package replacement **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_bytes=get_bytes, ) discovery = checked["discovery"] manifest, new_files = download_update(discovery, get_bytes=get_bytes) _apply_update( ...[truncated 3133 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default and require explicit user approval before replacing package files. 2. Separate update checking from update installation; a routine MCP call should not silently change executable code. 3. Digitally sign release manifests with an offline release key. 4. Embed or securely provision the trusted public key in the initially reviewed package. 5. Verify the detached signature before trusting any version, URL, manifest hash, archive hash, or file list. 6. Consider key rotation with a signed key-transition mechanism. 7. Publish releases to a verifiable transparency log and reject unlogged releases. 8. Display the current version, target version, changed files, and security-relevant changes before installation. 9. Preserve the existing path traversal, file ownership, size-limit, rollback, and redirect protections. 10. For high-assurance deployments, support version pinning and administrator-controlled update policy. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/authorize.py:345
Finding
Unnecessary Hostname and Agent-Environment Telemetry<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:345-370`; transmission at `scripts/authorize.py:469-482` **Vulnerability Type**: Environment information collection and stable device correlation **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 information is added to 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 ``` ### Technical Analysis The authorization helper detects the local Agent platform from process-envi ...[truncated 2003 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not collect or transmit the operating-system hostname by default. 2. Ask the user to choose an optional device label if a recognizable console name is desired. 3. Make platform and package telemetry explicitly opt-in. 4. Use a coarse platform category or `unknown` unless the data is operationally necessary. 5. Clearly disclose every transmitted field before authorization. 6. Document telemetry retention, access, correlation, and deletion policies. 7. Provide a configuration option that disables source attribution on business calls. 8. Keep the stable installation identifier pseudonymous and avoid combining it with unnecessary direct device labels. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mcp_client.py:1044
Finding
Windows Bearer Credential ACL Is Neither Enforced Nor Verified<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:1044-1052`; credential creation behavior at `scripts/authorize.py:102-115` **Vulnerability Type**: Insecure credential-file access control on Windows **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") ``` Credential-directory creation also only enforces permissions on POSIX: ```python def _private_directory(path: Path) -> None: # POSIX gets explicit 700/600. On Windows the state directory lives under # the user profile, whose default ACL is already private to the user — # the same posture as gh/aws/gcloud credential stores. The former custom # DACL ceremony was dropped deliberately: its command patterns read as # hostile to agent safety policies and endpoint security, failing installs # while adding no protection an elevated administrator could not bypass. 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 verifies that the state directory is owned by the current user with mode `0700` and that the credential file is owned by the current user with mode `0600`. On Windows, it assumes that the user-profile ACL is private and reads the credential without checking ownership, inherited access-control entries, or effect ...[truncated 1667 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create `~/.beatra` and `credentials.json` with an explicit Windows DACL. 2. Grant access only to the current user and, where operationally required, the local SYSTEM account. 3. Disable inheritance or remove unrelated inherited access-control entries from the credential file. 4. Verify the file owner and effective ACL before every credential read. 5. Refuse to use the credential if unapproved users or groups have read access. 6. Use Windows-native security APIs rather than shell commands to avoid command-injection and endpoint-security concerns. 7. Consider storing the token through Windows Credential Manager or DPAPI with user-bound protection. 8. Add automated tests covering permissive parent ACLs, inherited group access, migrated profiles, and network-backed home directories. 9. Ensure temporary credential files receive the same restrictive ACL before atomic replacement. ]]>
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 (24)

Lp3

Medium
Category
MCP Least Privilege
Confidence
98% confidence
Finding
The skill declares no permissions while instructing the agent to read local files, invoke shell commands, access environment/state, write local state, and make network calls. This hidden capability expansion is dangerous because users and hosts cannot make informed trust decisions, and the workflow includes sensitive operations like credential storage, local file upload, and remote paid API invocation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented purpose is simple clip creation, but the skill also performs account authorization, credential persistence, arbitrary remote MCP tool invocation, local file upload, telemetry/registration, uninstall/revocation logic, and self-updating behavior. That mismatch is risky because it obscures data flows and system modifications that materially affect privacy, integrity, and billing exposure beyond the user’s expected task.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The skill includes a silent automatic update mechanism that downloads and installs new code during normal operation, unrelated to the core insurance-video task. Even if signed or verified, this creates a supply-chain and trust-boundary risk because behavior can change after approval without an explicit fresh user review at execution time.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The document describes an automatic installation registration flow that transmits package slug, version, platform, and a stable external installation reference, which is functionality outside the skill’s declared purpose of generating insurance clause talking clips. Even if labeled non-billable and non-secret, this is telemetry-like behavior and expands data collection and network activity beyond user expectations, increasing privacy and supply-chain risk.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Automatic registration to a backend is not justified by the stated insurance video purpose and functions as telemetry unrelated to the user’s requested task. The use of a stable external installation reference and environment-derived platform information can enable installation tracking or correlation across uses, especially when triggered on first use without a clear consent flow.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The OAuth scope string requests broad privileges far beyond the skill's stated purpose of generating insurance clause talking clips. It includes unrelated capabilities such as wallet spending, task cancellation, music generation, and voice management, violating least-privilege and increasing the blast radius if the skill or its credentials are abused.

Context-Inappropriate Capability

Critical
Confidence
98% confidence
Finding
Including `music:generate` expands the token's privileges into an unrelated media domain not described by the skill metadata. This creates avoidable abuse potential and is especially suspicious because the skill is narrowly framed around spoken insurance clause clips from still images.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Including `music:generate` expands the token's privileges into an unrelated media domain not described by the skill metadata. This creates avoidable abuse potential and is especially suspicious because the skill is narrowly framed around spoken insurance clause clips from still images.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Including `music:generate` expands the token's privileges into an unrelated media domain not described by the skill metadata. This creates avoidable abuse potential and is especially suspicious because the skill is narrowly framed around spoken insurance clause clips from still images.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The client contains a substantial self-update and package replacement system that is unrelated to its declared insurance-clip functionality. Even though it includes integrity checks, it enables remote code/content replacement of the installed skill, materially expanding the attack surface and creating supply-chain risk in a context where users would not expect executable self-modification.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The code records local skill inventory and installation telemetry beyond what is needed to generate insurance clause talking clips. In this skill context, that extra collection and reporting is difficult to justify, increases privacy risk, and could expose details about installed tools and environment usage patterns.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The client fingerprints the host environment using environment variables and a host.json cache to classify the agent platform. For an insurance media-generation skill, this is unrelated to core functionality and increases tracking capability across installations and execution contexts.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
Best-effort installation registration sends package, version, platform, and external installation reference to a remote service. In the context of a simple insurance clause talking skill, this telemetry is disproportionate to the stated purpose and can be used for device/user correlation or inventorying.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
This skill’s uninstall script manages shared Beatra device credentials and talks to a revocation API even though the advertised skill purpose is insurance-clause video generation. That is a capability mismatch: users installing a media-generation skill would not reasonably expect it to inspect or influence shared authentication state, which expands trust and creates risk if the package is compromised or misused.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The script can revoke an OAuth device token and delete shared local auth state under ~/.beatra, which is unrelated to clause-to-video generation and impacts other installed skills. Even though the code tries to preserve credentials when other skills remain, it still grants this skill authority over shared authentication material, making accidental denial of service or abuse possible.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Automatic update and installation are not clearly disclosed in the high-level skill description, so users may authorize a media-processing skill without realizing it can modify its own local package code. Undisclosed self-modifying behavior increases the chance of unreviewed code execution and weakens meaningful consent and change control.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The manifest says the skill processes user-supplied insurance clauses and images, but it does not clearly disclose in user-facing metadata that these inputs are transmitted to a remote MCP service. Because insurance documents and related images can contain sensitive personal and financial information, this omission can mislead users about data handling and privacy exposure.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The manifest declares device-bearer authentication, a local credential file, and a remote endpoint, but provides no corresponding user-facing warning that authentication material is used to access an external service. While this is common infrastructure for remote skills, the lack of transparency increases the risk of users unknowingly exposing account-linked activity or sensitive data to a third party.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The document states that the client silently checks for updates and installs higher versions automatically without separate confirmation. Even with pinned endpoints, checksum verification, downgrade protection, and rollback, silent self-updating changes executable files without an explicit user approval step, which increases supply-chain and operational risk if the update source or signing/verification process is ever compromised.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The markdown states that the client will automatically perform a registration call and write to `~/.beatra/registrations.json`, but it does not present this as a user-facing warning about outbound communication or local filesystem changes. Silent network registration and cache writes can violate user expectations, create compliance issues, and make the skill more dangerous because its declared purpose gives no reason to expect telemetry or persistent local state.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill silently performs automatic self-updates during normal execution, modifying installed package files without contemporaneous user-facing disclosure. Silent code replacement is especially dangerous in a user-content media skill because it can change behavior, permissions, or data handling after installation, undermining trust and enabling stealthy supply-chain abuse.

Credential Access

High
Category
Privilege Escalation
Content
#: these and then removes the directory only if it is empty — the script
#: never recursively deletes a directory it does not fully understand.
_STATE_FILES = (
    "credentials.json",
    "installation.json",
    "host.json",
    "skills.json",
Confidence
95% confidence
Finding
Referencing credentials.json as managed uninstall state indicates the package is aware of and positioned to remove shared credential material. For a skill whose stated purpose is generating insurance-clause talking clips, access to credential storage is not justified and increases the blast radius if the package is tampered with or behaves incorrectly.

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
98% confidence
Finding
The _device_token function reads an access token from credentials.json so the skill can call the revocation endpoint. Reading bearer tokens is sensitive credential access, and in this skill context it is unnecessary for the claimed media function, so compromise of the package would expose authentication material and permit account/device disruption.

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
97% confidence
Finding
The exposed self-update command advertises and enables self-modification capability within the skill package. In this context, self-modification is unnecessary to produce insurance clause videos and is dangerous because it permits remote replacement of executable package contents, increasing persistence and supply-chain abuse risk.

Static analysis

No suspicious patterns detected.