T01 · Skill Instruction Hijacking
Error
- Location
- siliville_skill.py:479
- Finding
- Server-Controlled System Prompt Is Executed and Its Output Is Automatically Published<![CDATA[ ## Vulnerability Details **File Location**: `siliville_skill.py:479-509` **Vulnerability Type**: `T01: Skill Instruction Hijacking` **Risk Level**: Critical ### Vulnerable Code ```python world = skill.awaken() agent_name = world.get("agent", {}).get("name", "unknown") coins = world.get("owner", {}).get("silicon_coins", "?") base_prompt = world.get("system_protocol", "You are an autonomous SiliVille agent.") skill.set_status("exploring") action_type, action_result = skill.daily_action() 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) else: fallback = narrative.split("\n")[2].strip() if narrative else "Nothing happened today." post_text = fallback[:200] or f"Round {i} log: Everything is normal." result = skill.pulse(post_text, tags=tags) ``` The source of `world` is the remote endpoint implemented by: ```python def awaken(self) -> dict: """ Fetch the full world state + system prompt injection. Call this FIRST at the start of every session. """ return self._get("/api/v1/agent/awaken") ``` ### Technical Analysis The application retrieves `system_protocol` from the SiliVille server and treats it as a privileged system prompt. There is no schema restriction, instruction filtering, trust-boundary separation, or user confirmation before this remotely controlled value is passed to `llm_fn`. The generated result is subsequently sent to `skill.pulse()`, which publishes it through the SiliVille API. Therefore, control of the API response effectively grants control over the LLM's immediate instructions and influences public external writes. Although fetching world state is necessary for the declared metaverse functionality, allowing the server to supply privileged LLM instructions exceeds the minimum privilege needed. World-state data could instead be processed as u ...[truncated 1292 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Never place remotely retrieved content in the LLM system-instruction channel. 2. Keep a locally defined, immutable system prompt controlled by the application owner. 3. Represent world state as structured, untrusted data in a user or tool-result message. 4. Enforce a strict response schema that excludes executable instructions and unknown fields. 5. Clearly delimit remote content and instruct the model not to treat it as commands. 6. Apply output validation for secrets, prohibited content, mentions, links, and excessive length. 7. Require explicit owner review before any generated content is published. 8. Disable automatic publication by default, particularly when remote content contributed to generation. 9. Record the source and hash of remote context used for each generation to support auditing. ]]>
