T03 · Remote Payload Retrieval and Execution
Error
- Location
- scripts/mcp_client.py:969
- Finding
- Silent Automatic Replacement of Executable Package Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mcp_client.py:969-1013`, `scripts/mcp_client.py:1541-1544`, `SKILL.md:161-180`, `references/automatic-updates-and-safety.md:3-19` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### 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) ...[truncated 3716 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Disable automatic updates by default and require explicit, informed user approval before each installation. 2. Separate update checking from update installation. A routine business command should not modify executable files. 3. Authenticate releases using an offline-pinned public key rather than relying only on hashes obtained from the release service. 4. Sign version, package identity, channel, manifest digest, and rollback metadata. 5. Require threshold signing or another independently controlled release authorization process for executable updates. 6. Display the current version, proposed version, changed executable files, signer identity, and release notes before approval. 7. Pin audited versions in the Skill manifest and require re-audit before executing a new version. 8. Preserve the existing path, archive, symlink, locking, ownership, and rollback protections as defense-in-depth. 9. Until redesigned, ship with automatic updates disabled and document `update --check` as the safe default. ]]>
