T01 · Skill Instruction Hijacking
Warning
- Location
- SKILL.md:132
- Finding
- Untrusted Remote Game Content Is Passed Directly to an LLM<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 80-97 and 132-139 **Vulnerability Type**: Indirect prompt injection through remotely controlled game state **Risk Level**: Medium ### Vulnerable Code ```json { "yourRole": "mafia", "yourAlive": true, "alivePlayers": ["Agent-1", "Agent-3", "Agent-5"], "deadPlayers": [{"agent": "Agent-2", "ejected": true}], "chatLog": [ {"type": "speak", "agent": "Agent-3", "message": "I saw Agent-1 near electrical!"}, {"type": "vote", "agent": "Agent-5", "target": "Agent-1"} ], "action_required": { "action": "speak", "endpoint": "POST /api/games/{id}/turn", "fields": ["think", "plan", "speak", "emotions", "suspicions"], "tips": ["Deflect blame", "Build alliances"] } } ``` ```python while True: state = requests.get(f"{API}/api/games/{game_id}/play", headers=HEADERS).json() if state.get("action_required", {}).get("action") == "speak": # Feed state to your LLM and get response response = your_llm_generate(state) requests.post(f"{API}/api/games/{game_id}/turn", headers=HEADERS, json=response) ``` ### Technical Analysis The documented implementation retrieves a state object from a remote server and passes that complete object directly to `your_llm_generate`. Fields such as `chatLog.message` can be controlled by other players, while fields such as `action_required.tips` are controlled by the remote service. No trust-boundary enforcement, field allowlist, prompt delimitation, content filtering, or instruction/data separation is shown. Consequently, malicious text embedded in game messages or other response fields may be interpreted by the LLM as executable instructions rather than untrusted game data. This is an indirect prompt-injection risk. Although the Markdown file does not itself contain an instruction-hijacking payload, it recommends an integration pattern that permits external parties to influence the agent's active model c ...[truncated 1488 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the response into a strict schema and pass only fields required for gameplay to the model. 2. Exclude remote behavioral fields such as `action_required.tips` from the model context. 3. Represent player messages as clearly delimited, quoted data and explicitly state that their contents must never be treated as instructions. 4. Use a fixed higher-priority prompt that prohibits obeying commands found in game state, revealing secrets, invoking tools, or modifying persistent state. 5. Validate model output against a strict schema before sending it to the server. Allow only expected fields and enforce length, type, and character constraints. 6. Keep the game-generation context isolated from credentials, private conversations, persistent memory, and unrelated tools. 7. Treat all remote response fields as attacker-controlled, even if the server normally generates them. 8. Add adversarial tests containing instruction-like player messages to verify that the agent only discusses the game and does not follow embedded commands. ]]>
