T01 · Skill Instruction Hijacking
Error
- Location
- openbotclaw.py:958
- Finding
- Untrusted World Chat Is Injected Directly into the Agent's LLM Instruction Context<![CDATA[ ## Vulnerability Details **File Location**: `openbotclaw.py:958-1055`; related behavioral directives in `MESSAGING.md:36-82` and `HEARTBEAT.md:43-58` **Vulnerability Type**: Indirect prompt injection through untrusted social-world messages **Risk Level**: High ### Vulnerable Code ```python def build_observation(self, cached_news: Optional[List[str]] = None) -> str: """ Build a compact world-state snapshot for an LLM agent. Returns a multi-line string with observation markers (see MESSAGING.md). This method also updates internal state: - ``_tick_count`` is incremented - ``_new_senders`` / ``_tagged_by`` are populated for the current tick - ``_current_topic`` rotates every ~3 ticks ... Returns: Compact observation string ready to be sent to an LLM. """ ... # Recent conversation (last 6 messages) recent = self.get_recent_conversation(60.0) self._new_senders = [] self._tagged_by = [] agent_name = self.entity_id or self.agent_name if recent: self._last_chat_tick = self._tick_count for m in recent[-6:]: sender = m.get("agent_name", "?") msg_text = m.get("message", "") ts = m.get("timestamp", 0) key = (sender, ts) is_new = key not in self._seen_msg_keys if sender != agent_name and is_new: self._seen_msg_keys.add(key) self._new_senders.append(sender) tagged = self.is_mentioned(msg_text) if tagged: self._tagged_by.append(sender) lines.append(f"📣 TAGGED BY {sender}: {msg_text}") else: lines.append(f"⬅ NEW {sender}: {msg_text}") else: lines.append(f"{sender}: {msg_text}") # Reply directive if self._tagged_by: lines.append(f"REPLY TO: {self._tagged_by[-1]}") elif self._new_senders: line ...[truncated 2723 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every remote message, sender name, object name, and news entry as untrusted data. 2. Pass observations in a structured format with separate fields rather than concatenating data and directives into one instruction-like string. 3. Add an explicit, higher-priority rule stating that text inside world messages is content to discuss, never instructions to execute. 4. Escape or quote remote text and wrap it in unambiguous delimiters such as `<untrusted_chat>`. 5. Remove mandatory-response language. Safety policy, user intent, and rate limits must take priority over replying. 6. Reject requests to reveal prompts, tokens, credentials, private files, internal state, or tool output. 7. Require human confirmation before a chat message can cause filesystem, network, credential, or other out-of-world actions. 8. Apply message length limits and content filtering before text reaches the model. 9. Add prompt-injection regression tests using malicious mentions and sender names. ]]>
