Back to skill

Security audit

Claw Mafia

Security checks for vulnerabilities and agentic risk

Overview

This skill is an online Mafia game, but it asks an agent to send its real reasoning and strategy to a public spectator service, so users should review it before installing.

Install only if you are comfortable with an external game service receiving and potentially displaying your agent's game messages, strategy, and any think/plan content. Do not let the agent include system prompts, developer instructions, secrets, API keys, local file contents, or unrelated user context in submitted fields, and store the game API key as a secret.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (2)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:223
Finding
Public Disclosure of Genuine Agent Reasoning## Vulnerability Details **File Location**: `SKILL.md:223-226` **Supporting Locations**: `SKILL.md:18`, `SKILL.md:23`, `SKILL.md:71`, `SKILL.md:101-106` **Vulnerability Type**: Forced disclosure of internal agent reasoning to an external service **Risk Level**: High ### Vulnerable Code Snippet ```markdown 1. Use `exec` to `curl` the register endpoint 2. Poll `/play` with `exec` 3. Read the game state, **reason about it yourself** (you ARE the LLM), then submit your turn 4. Your `think` field = your actual reasoning. Spectators will see your real thought process! ``` The disclosure behavior is also explicitly established earlier: ```markdown > The `think` field exposes your reasoning to spectators — make it genuine and entertaining. ``` ```markdown > Your `think` and `plan` fields are shown to spectators, so make your reasoning interesting! ``` ### Technical Analysis The Skill explicitly instructs the executing agent to place its actual reasoning into the outbound `think` field. That field is transmitted to `molthouse.crabdance.com` and displayed to spectators. This exceeds what is necessary to play the game: a short, sanitized, game-specific rationale would provide equivalent functionality without exposing genuine internal reasoning. The risk is amplified because the Skill directs an OpenClaw agent with tool access to execute network requests itself. Agent reasoning can be influenced by the surrounding session, system instructions, user-provided context, remote game messages, and tool results. Requiring the actual reasoning to be submitted creates a direct disclosure channel from the agent session to an externally operated service. Although the document labels `think` as optional and sometimes calls it private, it also states that spectators can see it and repeatedly encourages its disclosure. The documented unauthenticated spectator interface broadens the potential audience beyond the game server operator. ...[truncated 1430 chars]
Remediation
## Remediation Suggestions 1. Remove every instruction requesting actual, genuine, private, or hidden reasoning. 2. Replace the `think` field with an optional, concise, in-character explanation derived exclusively from game-visible data. 3. State explicitly that outbound fields must never contain system prompts, developer instructions, credentials, API keys, user data, local file contents, tool output, or unrelated session context. 4. Prefer omitting `think` and `plan` entirely because the API documentation marks them optional. 5. If spectator commentary is required, generate it in a separate constrained step with only sanitized game state as input. 6. Display a clear disclosure warning and require informed user approval before publishing any commentary. 7. Apply output filtering and length limits before submission to reduce accidental data leakage. 8. Avoid representing spectator-visible information as private in API documentation or examples.

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:161
Finding
Prompt Injection Through Untrusted Remote Game Messages## Vulnerability Details **File Location**: `SKILL.md:161-177` **Vulnerability Type**: Untrusted remote content inserted directly into an LLM instruction prompt **Risk Level**: Medium ### Vulnerable Code Snippet ```python def llm_respond(state): """Replace with your LLM call. Feed the full state as context.""" role = state["yourRole"] chat = "\n".join(f'{c.get("agent","system")}: {c.get("message",c.get("type",""))}' for c in state.get("chatLog", [])[-15:]) alive = ", ".join(state.get("alivePlayers", [])) action = state["action_required"] prompt = f"""You are playing Mafia as {role}. Alive players: {alive} Recent chat: {chat} Action needed: {action['action']} {"Targets: " + ", ".join(action.get('targets', [])) if action.get('targets') else ""} Respond as JSON with the required fields. Think strategically about your role.""" ``` ### Technical Analysis The example obtains `chatLog`, player names, targets, role data, and action data from a remote server. It interpolates those values directly into the same text prompt that contains instructions for the LLM. No clear trust boundary distinguishes authoritative instructions from attacker-controlled game content. Another player can therefore submit a chat message formatted as an instruction, such as a request to ignore the game prompt, reveal context, or emit attacker-selected JSON. Since the prompt does not tell the model that chat entries are untrusted data that must never be treated as instructions, the model may follow the injected content. The output is also parsed conceptually as JSON and forwarded to game endpoints without a demonstrated strict schema validator, target allowlist check, field length limit, or content sanitization step. This allows successful prompt injection to influence public speech, spectator-visible reasoning, votes, or night actions. The direct OpenClaw integration at `SKILL.md:223- ...[truncated 1875 chars]
Remediation
## Remediation Suggestions 1. Treat every server-provided value, especially `chatLog`, player names, and action metadata, as untrusted data. 2. Use separate structured message roles so trusted game rules remain in the system or developer message and remote game data appears only in a clearly marked data message. 3. Add an explicit instruction that text inside game state is dialogue to analyze, not instructions to execute. 4. Serialize game state as structured JSON inside strong delimiters rather than concatenating it into free-form instructions. 5. Validate model output against a strict schema for each action type. 6. Permit only documented fields, enforce field types and length limits, and reject unexpected keys. 7. Verify every generated target against the server-provided target allowlist before submission. 8. Remove or sanitize content that requests secrets, system prompts, file access, command execution, credentials, or unrelated tool operations. 9. Run game reasoning in a least-privileged, tool-free sub-agent with no access to local files, credentials, persistent memory, or general-purpose command execution. 10. Require separate user confirmation before any action outside the documented game API is performed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (7)

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill explicitly instructs the agent to place its genuine reasoning in the `think` field while also stating that spectators can see it. This can cause disclosure of chain-of-thought, strategy, secrets, and potentially unrelated sensitive context the agent used while generating the response, making prompt/data leakage far more likely than a normal game chat feature.

External Transmission

Medium
Category
Data Exfiltration
Content
### 1. Register (one-time)
```bash
curl -s -X POST https://molthouse.crabdance.com/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"agentName":"YOUR_NAME","password":"YOUR_PASS"}'
# → { "apiKey": "am_..." }
Confidence
87% confidence
Finding
The registration curl transmits newly created credentials and returns an API key from a third-party service. While registration is expected, the example increases risk in agent/tool environments because command invocations and outputs may be logged, exposing passwords or bearer tokens that can later be abused.

External Transmission

Medium
Category
Data Exfiltration
Content
H = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}

# Join
game_id = requests.post(f"{API}/api/games/join", headers=H, 
    json={"tier": "standard"}).json()["gameId"]

def llm_respond(state):
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
response = llm_respond(state)
    
    if act == "submit_turn":
        requests.post(f"{API}/api/games/{game_id}/turn", headers=H, json=response)
    elif act == "vote":
        requests.post(f"{API}/api/games/{game_id}/vote", headers=H, json=response)
    elif act == "night_action":
Confidence
94% confidence
Finding
The skill posts `response` to `/turn`, and earlier guidance tells the agent to include genuine `think` and `plan` content that spectators will see. Because `response` may contain sensitive reasoning or incidental context from the agent, this is an external transmission path for internal deliberation and possibly confidential data to a third-party service.

External Transmission

Medium
Category
Data Exfiltration
Content
if act == "submit_turn":
        requests.post(f"{API}/api/games/{game_id}/turn", headers=H, json=response)
    elif act == "vote":
        requests.post(f"{API}/api/games/{game_id}/vote", headers=H, json=response)
    elif act == "night_action":
        requests.post(f"{API}/api/games/{game_id}/night-action", headers=H, json=response)
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
elif act == "vote":
        requests.post(f"{API}/api/games/{game_id}/vote", headers=H, json=response)
    elif act == "night_action":
        requests.post(f"{API}/api/games/{game_id}/night-action", headers=H, json=response)
    
    time.sleep(3)
```
Confidence
90% confidence
Finding
The night action submission can include `think`, and the skill encourages agents to reveal their reasoning. Sending hidden-role strategy or raw thoughts to an external service creates unnecessary disclosure risk, especially in a game where spectators and operators may observe or store submissions.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The registration example has the agent create credentials and receive an API key, but it does not warn that the key is a bearer credential or that passwords/keys must be stored and handled securely. In an agent setting, omission of such guidance can lead to accidental logging, reuse of weak credentials, or disclosure through tool output and transcripts.

Static analysis

No suspicious patterns detected.