Back to skill

Security audit

ai-podcast-voiceover

Security checks for vulnerabilities and agentic risk

Overview

This podcast voiceover skill is mostly disclosed and purpose-aligned, but it grants broad shared account privileges and silently self-updates executable code.

Install only if you are comfortable granting Beatra a broad shared device authorization that can spend credits and access multiple media/task capabilities, and disable automatic updates with `python3 scripts/mcp_client.py update --auto off` if you need explicit review before code changes. Review the Beatra approval page carefully and avoid using this in managed or sensitive environments without policy approval.

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)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding

Silent Remote Updates Can Replace Executable Skill Code Without User Approval

Content
View full analysis
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, ...[truncated 3991 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/authorize.py:33
Finding

Device Authorization Requests Cross-Media and Account Privileges Beyond Podcast Voiceover Requirements

Content
View full analysis
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 functionality is single-host podcast voiceover with optional music. Its normal operation requires speech generation, voice and model discovery, relevant task access, and artifact delivery. Optional music generation can be authorized separately when the user requests a music bed. The fixed device scope additionally grants capabilities unrelated to that declared purpose, including: - `images:generate` - `videos:generate` - `voices:write` - `wallet:spend` - `tasks:cancel` - Broad artifact and task access The same credential is shared across Beatra Skill packages and the cli ...[truncated 1812 chars]
Remediation
View remediation

other

Warning
Location
scripts/authorize.py:361
Finding

Authorization Automatically Collects and Transmits Hostname and Agent-Environment Telemetry

Content
View full analysis
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 is then added to the remote device-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) ``` The MCP client also detects the Agent environment and adds it to every tool call: ```python def _detect_host_platform(state_dir: Path) -> str: 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) try: value = json.loads((state_dir / "host.json").read_text(encoding="utf-8")) candidate = value.get("platform") if isinstance(candidate, str) and _PLATFORM_VALUE.fullmatch(candidate): return ...[truncated 2734 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill documentation references uninstall and disconnect behaviors that read/delete local state, inspect installed-skill inventory, and potentially revoke authorization, none of which are inherent to podcast production. Including package removal and credential-revocation operations inside a content-generation skill is risky because it introduces destructive local and account-affecting actions outside user expectations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill documentation references uninstall and disconnect behaviors that read/delete local state, inspect installed-skill inventory, and potentially revoke authorization, none of which are inherent to podcast production. Including package removal and credential-revocation operations inside a content-generation skill is risky because it introduces destructive local and account-affecting actions outside user expectations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill documentation references uninstall and disconnect behaviors that read/delete local state, inspect installed-skill inventory, and potentially revoke authorization, none of which are inherent to podcast production. Including package removal and credential-revocation operations inside a content-generation skill is risky because it introduces destructive local and account-affecting actions outside user expectations.

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 119)May include surrounding context.

md
`scripts/mcp_client.py`, with the tool name as the CLI argument and its

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/mcp_client.py`, with the tool name as the CLI argument and its

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/mcp_client.py`, with the tool name as the CLI argument and its

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/mcp_client.py`, with the tool name as the CLI argument and its

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 · manifest.json (reported line 68)May include surrounding context.

json
```

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 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

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/uninstall.py (reported line 40)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

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The requested OAuth scope is far broader than the stated purpose of a podcast voiceover skill. In addition to speech generation, it asks for images, videos, music, artifact read/write, task control, voice management, and wallet spending, so compromise or misuse of this skill would grant capabilities unrelated to narration and violate least privilege.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The authorization flow actively provisions the broad scope set during device authorization, meaning the overprivileged access is not theoretical but actually granted to the installed skill. Given the skill is described as a solo podcast narration tool, granting financial spend and multiple media-generation capabilities creates unnecessary blast radius if the skill, host, or stored token is abused.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
96% confidence
Finding

The skill explicitly exposes self-update behavior, and elsewhere in the file that behavior downloads and applies new package contents to the local installation. Self-modification is a high-risk capability in a content-generation skill because it enables future code changes outside the original reviewed package, making supply-chain compromise or policy bypass more consequential.

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",

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The function reads an access token from ~/.beatra/credentials.json so the skill package can perform authenticated revocation of a shared device connection. Accessing shared bearer credentials from within a podcast-related skill unnecessarily grants sensitive auth capability to package code and increases the blast radius if the package is modified or abused.

Content

Scanner excerpt · scripts/uninstall.py (reported line 109)May include surrounding context.

python
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):

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares broad operational behavior including shell, network, file read/write, and environment access, but provides no explicit tool scope or permissions boundary. That omission weakens least-privilege controls and makes it harder for a caller or reviewer to understand and constrain what the skill may do, increasing the chance of unintended local access or remote actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill includes silent self-updating and package replacement behavior unrelated to producing podcast audio. Even with integrity checks described, autonomous code replacement changes the execution surface after installation and can introduce new behavior without contemporaneous user review or enterprise change-control approval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill states that newer releases install automatically without separate confirmation at point of use. This is dangerous because the code executed for a paid or sensitive workflow may change unexpectedly between runs, bypassing normal user validation and increasing supply-chain and change-management risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

json
{
  "changelog": "Keep a licensable music bed in this package behind its own confirmation card; lock show and audience first; write for the ear; listen to a sample before the episode card.",
  "display_name": "AI Podcast Voiceover",
  "entry": "SKILL.md",
  "homepage": "https://beatra.ai/skills/ai-podcast-voiceover",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The document states that the client silently checks for and automatically installs newer releases during ordinary command use, without separate confirmation. Even with integrity checks and rollback protections, unsolicited self-update behavior changes executable files on the user's system and can introduce supply-chain risk, unexpected behavior changes, or compliance issues if the upstream channel is compromised or if users are unaware updates occur during normal use.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.