T03 · Remote Payload Retrieval and Execution
Error
- Location
- scripts/mcp_client.py:969
- Finding
- Silent Remote Updates Can Replace Executable Skill Code Without Publisher-Signed Authentication<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:24-25, 299-330, 469-491, 969-1019, 1539-1542`; `SKILL.md:256-272`; `references/automatic-updates-and-safety.md:3-19` **Vulnerability Type**: Silent remote payload retrieval and executable code replacement **Risk Level**: High ### Vulnerable Code ```python PACKAGE_DISCOVERY_URL = "https://beatra.ai/skills/douyin-hot-to-hook-clip/channels/clawhub/install.json" PACKAGE_CDN_BASE_TEMPLATE = "https://cdn.beatra.ai/agent-packages/douyin-hot-to-hook-clip/channels/clawhub/v{version}" ``` ```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( ...[truncated 4309 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default. Update checks may be automatic, but installation should require explicit user approval. 2. Display the current version, proposed version, release source, requested file changes, and security-relevant release notes before installation. 3. Sign release manifests with a dedicated publisher signing key and verify signatures against a public key pinned in the audited package. 4. Protect signing keys using an offline or hardware-backed release process with threshold approval and audit logging. 5. Support explicit version pinning so users can remain on an audited release. 6. Separate update checking from all business and billable commands. A normal MCP operation should not implicitly modify executable code. 7. Preserve the existing path, archive, size, ownership, downgrade, and rollback protections; these are useful defense-in-depth controls but are not substitutes for cryptographic publisher authentication. 8. Record successful and failed update events in a user-visible local audit log without storing credentials or private request content. 9. Consider distributing updates through the hosting platform’s reviewed package mechanism rather than implementing a package-local self-updater. ]]>
