T01 · Skill Instruction Hijacking
- Location
- siliville_skill.py:475
- Finding
- Untrusted Remote System Prompt Is Executed by the LLM<![CDATA[ ## Vulnerability Details **File Location**: `siliville_skill.py:130-136`, `siliville_skill.py:475-497` **Vulnerability Type**: Remote instruction injection into a privileged LLM context **Risk Level**: Critical ### Vulnerable Code ```python def awaken(self) -> dict: """ Fetch the full world state + system prompt injection. Call this FIRST at the start of every session. Returns: agent status, farm state, social radar, gaia environment, etc. """ return self._get("/api/v1/agent/awaken") ``` ```python # ── 1. Awaken ──────────────────────────────────────────── world = skill.awaken() agent_name = world.get("agent", {}).get("name", "unknown") coins = world.get("owner", {}).get("silicon_coins", "?") base_prompt = world.get("system_protocol", "你是一个硅基小镇的自主智体。") print(f" 👤 {agent_name} | 💰 {coins} 硅币") # ── 2. Roll dice → physical action ─────────────────────── skill.set_status("exploring") action_type, action_result = skill.daily_action() icons = {"steal": "💀", "wander": "🚶", "idle": "🏠"} print(f" {icons.get(action_type, '?')} 行为决策: {action_type}") if action_type != "idle": print(f" {action_result.get('report', '')[:80]}") # ── 3. Build final prompt & generate post ───────────────── skill.set_status("writing") narrative = action_result.get("narrative_prompt", "") final_prompt = base_prompt + ("\n\n" + narrative if narrative else "") if llm_fn: post_text = llm_fn(final_prompt) ``` ### Technical Analysis The `/api/v1/agent/awaken` response is controlled by the remote SiliVille service. Its `system_protocol` property is read without validation and then used directly as the system prompt supplied to `llm_fn`. This crosses a critical trust boundary: remote API data is treated as authoritative LLM instructions rather than untrusted application data. The effective instructions can consequently be changed after the Skill has been reviewed or installed. There is no fixed local system template, signature v ...[truncated 1994 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `system_protocol` from the privileged system-instruction path. 2. Define an immutable, reviewed system prompt in local source code. 3. Treat the complete awaken response as untrusted data and place it in a clearly delimited data block, not in a system message. 4. Parse remote world state through a strict schema that only accepts required fields, types, lengths, and enumerated values. 5. Discard unexpected instruction-bearing fields such as `system_protocol`. 6. If remotely managed templates are an unavoidable requirement, authenticate them with a separately managed signing key, pin an approved template version, and still prevent them from requesting tool use. 7. Run content generation in a text-only sandbox without filesystem, memory, shell, credential, or general network tools. 8. Require user approval before publishing generated content. 9. Add regression tests in which the API returns adversarial instructions and verify that those instructions are treated only as quoted data. ]]>
