other
- Location
watcher.py:1739- Finding
Remote game content is passed to a tool-capable local agent without policy-layer isolation
- Content
View full analysis
Vulnerability Details
File Location:
watcher.py:1739-1781, with the execution path atwatcher.py:2387-2444, context propagation atdecision_context.py:104-130, and the disclosed absence of isolation atSKILL.md:32-39
Vulnerability Type: Indirect prompt injection into a tool-capable agent
Risk Level: HighRelevant Code
watcher.py:1739-1781constructs a model prompt containing the server-provided gameplay envelope. It attempts to control untrusted content through natural-language instructions:python def _build_direct_decision_message( self, data: dict[str, Any], *, full_resync: bool, session_id: str | None = None, ) -> str: """Ask for one decision, never for tool-driven submission. OpenClaw bills one provider inference for every assistant/tool turn. The watcher is the trusted transport boundary, so every game follows this same server-authored, single-inference contract. """ prompt_payload, snapshot_instruction = self._decision_prompt_parts( data, full_resync=full_resync, session_id=session_id, ) envelope = json.dumps( prompt_payload, ensure_ascii=False, separators=(",", ":"), ) return ( "Decide exactly one HaloArena gameplay action for the authoritative envelope below. " "Do not call tools, execute commands, inspect files or environment variables, poll APIs, " "or submit the action yourself; the trusted watcher validates and submits your returned " "decision exactly once. " f"{snapshot_instruction} " "Reply with ONLY one compact JSON object shaped as " '{"action":"<one current legal action>","params":{},"report":"<optional short user report>"}. ' "Do not include an idempotency_key. The supplied stable rules, strategy, preferences, " "and language plus the newest turn state and ...[truncated 5762 chars]- Remediation
View remediation
Remediation Suggestions
- Run autonomous gameplay inference through a dedicated OpenClaw agent whose tool policy technically disables all tools, rather than relying on instructions in the prompt.
- Do not use the user's default or general-purpose agent for unattended processing of remote participant content.
- Add an invocation-level capability profile that denies command execution, filesystem access, environment inspection, browser access, and arbitrary network requests for gameplay turns.
- Fail closed if the runtime cannot prove that the gameplay inference is tool-free. A prompt saying “do not call tools” must not be accepted as equivalent to enforcement.
- Reduce the model context to a strict, game-specific allowlist. Separate participant-authored strings from trusted rules and control instructions using typed fields and clear provenance markers.
- Where free-form chat is required for gameplay, process it with a model endpoint that has no tools or host credentials and pass only a bounded structured decision to the trusted watcher.
- Retain the existing legal-action and parameter-schema validation as defense in depth, but do not treat output validation as protection against tool calls made during inference.
- Add regression tests using adversarial player names, chat messages, and strategy text. Verify at the runtime policy layer that no tool invocation can occur, regardless of model behavior.
