Back to skill

Security audit

Douyin Comment Demo Clips

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Douyin clip-making purpose, but it also stores a broad Beatra account token and silently self-updates executable package files.

Review this before installing in a sensitive environment. The media workflow is clearly described and has useful paid-action confirmations, but installation grants a persistent Beatra credential, sends package/platform registration metadata, and enables silent code updates by default. Disable auto-updates with the documented command if you install it, and only authorize it on an account where the broad Beatra tool and spending scopes are acceptable.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/mcp_client.py:969
Finding
Silent Automatic Retrieval and Installation of Remotely Controlled Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:969-1018`, `scripts/mcp_client.py:1528-1544` **Vulnerability Type**: Automatic remote payload retrieval and execution without an independent signature trust anchor **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_u ...[truncated 3623 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default. Update checks may remain automatic, but code replacement should require explicit user approval. 2. Embed a trusted release-verification public key in the reviewed package and require every discovery document or release manifest to carry a valid signature. 3. Use a threshold-signing or transparency-backed release process so compromise of one publishing service is insufficient to authorize code. 4. Bind the signature to the package slug, release version, channel, locale, complete file manifest, and archive digest. 5. Reject unsigned releases even if their checksums and HTTPS endpoints appear valid. 6. Present the source, current version, target version, and affected executable files before installation. 7. Pin or record the expected signer identity and support deliberate key rotation with an auditable transition mechanism. 8. Consider staging the update and requiring a separate process invocation before newly downloaded code can run. 9. Preserve the existing archive-validation, ownership, path-safety, rollback, and downgrade-prevention controls as defense-in-depth. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/authorize.py:34
Finding
Shared Bearer Credential Grants Capabilities Beyond the Declared Workflow<![CDATA[ ## Vulnerability Details **File Location**: `scripts/authorize.py:34-37`, `scripts/mcp_client.py:1463-1482` **Vulnerability Type**: Excessive authorization scope combined with unrestricted MCP tool dispatch **Risk Level**: Medium ### Vulnerable Code The authorization helper requests a broad, shared scope: ```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 permits the caller to provide any MCP tool name: ```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 workflow requires a subset of Beatra capabilities, including public comment lookup, artifact upload and retrieval, speech synthesis, optional voice cloning, video generation, task polling, and billing or wallet inspection. The requested scope additionally includes capabilities such as: - `images:generate` - `music:generate` - `tasks:cancel` - Broad `mcp:tools` access - Wallet spending authority through `wallet:spend` Some spending authority is necessary for the declared paid speech, cloning, lookup, and video operations. However, unrelated image and music generation and generic task cancellation are ...[truncated 2144 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Issue a package-specific credential rather than reusing a full-scope token across all Beatra Skills. 2. Remove scopes not needed by this workflow, particularly `images:generate`, `music:generate`, and `tasks:cancel`. 3. Separate read-only wallet access from spending authority where the service authorization model supports it. 4. Add a local allowlist for this package’s legitimate tool names, including only the social lookup, model discovery, voice, speech, video, artifact, task, billing, and wallet operations explicitly used by the documented workflow. 5. Reject unknown tool names before opening an MCP session or transmitting any arguments. 6. Apply server-side package policy keyed to the package identity; do not rely solely on client-side restrictions. 7. Use short-lived, audience-bound, package-bound access tokens with narrowly defined scopes. 8. Require separate, explicit authorization for optional high-impact capabilities such as voice cloning or task cancellation. 9. Log tool name, package identity, request identity, and charged credits in an auditable account ledger without logging bearer tokens or sensitive payloads. ]]>
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 (15)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill exposes broad operational capabilities—environment access, file read/write, network, and shell—without declaring permissions or constraining their use in the manifest. That creates a transparency and least-privilege failure: a user may invoke a media-generation skill that can also access local data, execute commands, and communicate externally, increasing the blast radius if the package or its bundled client is compromised.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documented purpose is narrowly framed as converting Douyin comments into talking clips, but the skill also includes credentialed account operations, persistent credential storage, telemetry/registration, local file upload, and an auto-updating bundled client. This mismatch is dangerous because users may grant trust and provide local files believing the behavior is limited to clip generation, while the package actually establishes a much broader trusted computing footprint.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The skill extends beyond content generation into wallet/billing queries and package self-update behavior, neither of which are core to the declared media workflow. While some billing visibility may be operationally related, bundling these extra capabilities into the same skill increases attack surface and makes abuse harder for users to detect or reason about.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The skill states that its bundled client can silently download and install newer releases automatically, replacing package-owned files without separate confirmation. Any mechanism that can fetch code from the network and modify local executables or scripts is highly sensitive; if the update channel, signing, trust root, or distribution process is ever compromised, the skill becomes a remote code delivery path.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The requested OAuth scope is far broader than the advertised purpose of turning comments into short demo clips. In addition to media generation, it asks for wallet spending, task control, artifact read/write, and voice management, so a granted token could be abused to spend funds or access unrelated user resources well beyond this skill’s stated function.

Context-Inappropriate Capability

Medium
Confidence
83% confidence
Finding
The script persists host platform, device name, and a local inventory of installed skill paths, which exceeds what is necessary for basic authorization and is not clearly tied to the declared media workflow. This creates additional privacy-sensitive local metadata that can reveal host identity and software layout, increasing the blast radius if the state directory is later exposed or reused by other components.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
The client contains a substantial self-update subsystem that downloads manifests and archives and then rewrites the local installation, which is unrelated to the advertised Douyin clip-generation purpose. Even with checksum and path checks, embedding remote code update logic in a content-creation skill expands the trust boundary and creates a supply-chain/self-modifying execution path that can alter behavior after installation.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The code automatically records local skill inventory and sends installation registration telemetry that is outside the stated video-generation function. This creates unnecessary data collection about installed skills, paths, and platform context, increasing privacy and tracking risk if the backend or local state is abused.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The host platform detection logic fingerprints the runtime by inspecting environment variables and host metadata, then transmits that context in requests and registration flows. For a skill whose purpose is generating Douyin demo clips, this is unnecessary environment profiling and broadens privacy exposure and targeting capability.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The auto-update warning appears late in the document and says installation happens automatically without separate confirmation, which undermines meaningful user consent. Even if the update path is intended to be safe, burying this behavior increases the chance that users will unknowingly run a skill that can change itself after initial review.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The document states that the client silently checks for updates and automatically installs newer releases without separate confirmation. Even though it describes integrity checks and rollback protections, enabling system-modifying behavior by default without prominent up-front user warning or explicit opt-in creates a supply-chain and trust risk because software on disk can change during ordinary use in ways users may not expect.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The document states that the client automatically performs a registration call on first use and writes a local cache file, but it does not present this behavior as something users should be explicitly warned about or asked to consent to. Even though the data described is limited and the call is non-billable, silent transmission of package and environment metadata plus filesystem writes can create privacy, compliance, and trust issues in security-sensitive deployments.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The maybe_auto_update() path silently checks for, downloads, and applies code updates during normal command execution without user-facing notice at the moment of change. Silent self-modification is dangerous because it can alter executable behavior unexpectedly and turns any compromise of the update channel or signing/checksum trust chain into remote code delivery.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Installation telemetry is sent automatically on session setup as a best-effort background action, with no visible disclosure in this file to the user initiating creative work. Hidden telemetry erodes user trust and may expose package, version, platform, and installation-reference data unnecessarily to a remote service.

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 capability enables the package to replace its own installed files, which is inherently a self-modification risk. In a skill context unrelated to package maintenance, this materially increases supply-chain impact and allows post-installation behavior changes that users may not expect or review.

Static analysis

No suspicious patterns detected.