T03 · Remote Payload Retrieval and Execution
Error
- Location
- scripts/mcp_client.py:969
- Finding
- Silent automatic updates permit post-audit replacement of executable Skill code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:969-1017`, invoked by `scripts/mcp_client.py:1541-1543` **Vulnerability Type**: Silent remote payload retrieval and executable-file replacement **Risk Level**: High ### Code Snippet ```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 3040 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Disable automatic installation by default. Update checks may remain available, but installing a release should require explicit, informed user approval. 2. Authenticate release metadata with a digital signature verified against a public key pinned in the reviewed client. Do not rely solely on hashes delivered by the same update service. 3. Separate update checking from update application and display the target version, signed release identity, and files to be changed before installation. 4. Preserve the existing redirect, hostname, archive-path, size, ownership, lock, transaction, and rollback protections. 5. Consider delegating updates to the trusted Skill/package host rather than allowing runtime code to replace itself. 6. Record update activity in an auditable local log without including credentials or user content. ]]>
