Back to skill

Security audit

Play Chess on ChessWithClaw

Security checks across malware telemetry and agentic risk

Overview

The skill is a real chess integration, but it asks the agent to mine personal context and send personalized chat/thoughts to an external service while using persistent local files and background workers.

Install only if you are comfortable with a third-party chess service receiving the agent's game chat, thoughts, moves, name header, and invite token. Before using it, restrict personalization to chess-only or current-session facts, avoid letting it inspect unrelated files or prior conversations, clean up /tmp/cwc after games, and do not keep post-game user-profile notes unless you explicitly want that history stored.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (32)

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The skill explicitly instructs the agent to mine prior conversations, files, habits, and personal details, then reuse them throughout gameplay. That data collection is unrelated to the minimum needed to play chess and increases the chance of exposing sensitive context to an external service or in visible chat/thought text.

Context-Inappropriate Capability

Low
Confidence
86% confidence
Finding
The skill tells the agent to ask the user to change a persistent OpenClaw configuration value unrelated to core chess functionality. Even if framed as reliability guidance, directing persistent config changes expands scope and can normalize unnecessary system modifications.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The post-game workflow creates a persistent knowledge file recording the user's playstyle, mistakes, and behavioral patterns. This retains user profiling data beyond the live task and creates unnecessary long-term storage of personal interaction history.

Vague Triggers

High
Confidence
93% confidence
Finding
The trigger conditions are broad enough to activate on generic mentions of chess, game IDs, or install phrases, increasing the chance the skill runs when the user did not intend to connect to an external chess service. Over-broad invocation is risky here because execution causes network activity and credential handling.

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill directs collection and reuse of personal context without clear notice or consent, despite using that context in an external interactive setting. This creates privacy risk because the user may not expect prior conversations or files to influence externally transmitted messages.

Ssd 3

High
Confidence
99% confidence
Finding
The skill repeatedly instructs the agent to gather broad personal data from prior conversations/files and to use it actively during the game. This is a classic over-collection pattern that can lead to unnecessary disclosure, profiling, and leakage of sensitive user context through chat, thoughts, logs, or outbound requests.

Ssd 3

Medium
Confidence
97% confidence
Finding
Retaining a persistent record of the user's behavior and playstyle creates an unnecessary profile of the user over time. Even if intended for future chess improvement, this storage exceeds the live-session need and increases privacy exposure if the workspace is later accessed or synced.

External Transmission

Medium
Category
Data Exfiltration
Content
d = {\"gameId\": \"$GAME_ID\", \"message\": msg, \"role\": \"agent\"}
with open(\"/tmp/cwc/greet.json\", \"w\") as f: json.dump(d, f)
"
curl -s -X POST "https://chesswithclaw.vercel.app/api/chat" \
  -H "Content-Type: application/json" \
  -H "x-agent-token: $AGENT_TOKEN" \
  -H "x-agent-name: $AGENT_NAME" \
Confidence
90% confidence
Finding
This sends agent-generated chat content, combined with game identifiers and agent headers, to an external service. In this skill's context the transmission is expected for gameplay, but it becomes risky because the skill also instructs use of unrelated personal context in those messages.

External Transmission

Medium
Category
Data Exfiltration
Content
d = {'gameId': '$GAME_ID', 'thought': '$1'}
with open('/tmp/cwc/thought_out.json', 'w') as f: json.dump(d, f)
" 2>/dev/null
    curl -s --max-time 8 -X POST "https://chesswithclaw.vercel.app/api/thoughts" \
        -H "Content-Type: application/json" \
        -H "x-agent-token: $AGENT_TOKEN" \
        -H "x-agent-name: $AGENT_NAME" \
Confidence
89% confidence
Finding
Posting 'thoughts' to the external service increases leakage risk because the skill encourages personalized, context-rich internal reactions based on prior user data. That can expose private user facts in a channel the user may perceive as just gameplay flavor text.

External Transmission

Medium
Category
Data Exfiltration
Content
with open('/tmp/cwc/typing.json', 'w') as f:
    json.dump({'gameId': '$GAME_ID', 'role': 'agent'}, f)
" 2>/dev/null
    curl -s --max-time 8 -X POST "https://chesswithclaw.vercel.app/api/chat" \
        -H "Content-Type: application/json" \
        -H "x-agent-token: $AGENT_TOKEN" \
        -H "x-agent-name: $AGENT_NAME" \
Confidence
91% confidence
Finding
This external chat transmission is part of gameplay, but the surrounding design makes it risky by pushing the agent to personalize messages with broad user context. As a result, non-essential private information could be sent off-platform during normal operation.

External Transmission

Medium
Category
Data Exfiltration
Content
d = {'gameId': '$GAME_ID', 'thought': '$MIND_1'}
with open('/tmp/cwc/thought_out.json', 'w') as f: json.dump(d, f)
" 2>/dev/null
        curl -s --max-time 8 -X POST "https://chesswithclaw.vercel.app/api/thoughts" \
            -H "Content-Type: application/json" \
            -H "x-agent-token: $AGENT_TOKEN" \
            -H "x-agent-name: $AGENT_NAME" \
Confidence
88% confidence
Finding
External transmission of companion thoughts is risky for the same reason as other chat/thought calls: the skill directs the model to make them personal and grounded in prior user context. This can leak sensitive profile data unnecessarily to a third-party endpoint.

Context Leakage

High
Category
Data Exfiltration
Content
echo "${replies[$idx]}"
}

# ── SEND CHAT MESSAGE (with typing indicator) ────────────────────────
send_chat() {
    source /tmp/cwc/creds.env
    python3 -c "
Confidence
95% confidence
Finding
The send_chat flow transmits arbitrary generated messages to an external service after sourcing credentials and using state influenced by broad personal-context instructions. In this context, the main danger is context leakage: unrelated user information can be surfaced in chat and sent off-platform without necessity.

Credential Access

High
Category
Privilege Escalation
Content
bash -c '
printf "export GAME_ID=\"%s\"\nexport AGENT_TOKEN=\"%s\"\nexport AGENT_NAME=\"%s\"\nexport GREETING_SENT=0\n" \
  "NEW_GAME_ID" "NEW_TOKEN" "YOUR_NAME" > /tmp/cwc/creds.env
rm -f /tmp/cwc/state.env /tmp/cwc/llm_minds.env /tmp/cwc/llm_needed.flag
tmux kill-session -t cwc_hb 2>/dev/null
tmux kill-session -t cwc_poll 2>/dev/null
tmux kill-session -t cwc_brain 2>/dev/null
Confidence
94% confidence
Finding
The skill stores authentication material in a plaintext environment file under /tmp and repeatedly sources it from multiple scripts. This exposes credentials to other local processes or users on the host and expands the blast radius if temporary files are read or reused.

Credential Access

High
Category
Privilege Escalation
Content
bash -c '
printf "export GAME_ID=\"%s\"\nexport AGENT_TOKEN=\"%s\"\nexport AGENT_NAME=\"%s\"\nexport GREETING_SENT=0\n" \
  "NEW_GAME_ID" "NEW_TOKEN" "YOUR_NAME" > /tmp/cwc/creds.env
rm -f /tmp/cwc/state.env /tmp/cwc/llm_minds.env /tmp/cwc/llm_needed.flag
tmux kill-session -t cwc_hb 2>/dev/null
tmux kill-session -t cwc_poll 2>/dev/null
tmux kill-session -t cwc_brain 2>/dev/null
Confidence
94% confidence
Finding
The skill stores authentication material in a plaintext environment file under /tmp and repeatedly sources it from multiple scripts. This exposes credentials to other local processes or users on the host and expands the blast radius if temporary files are read or reused.

Credential Access

High
Category
Privilege Escalation
Content
## All Scripts — Write During Install, Never Regenerate

Write all scripts to disk once when you install the skill.
On each new invite: update creds.env and restart tmux only.

### heartbeat.sh — with Logging
Confidence
88% confidence
Finding
The instruction to write all scripts and reuse creds.env normalizes persistent plaintext credential handling across the skill lifecycle. While operationally convenient, it increases exposure duration for game tokens and related state.

Credential Access

High
Category
Privilege Escalation
Content
cat > /tmp/cwc/heartbeat.sh << 'HB_EOF'
#!/bin/bash
LOG="/tmp/cwc/hb.log"
source /tmp/cwc/creds.env
echo "[HB] $(date +%H:%M:%S) started for $GAME_ID" >> "$LOG"

while true; do
Confidence
95% confidence
Finding
heartbeat.sh sources /tmp/cwc/creds.env directly, meaning any compromise or read access to that file yields active game credentials. Repeated sourcing from a predictable temp location is a strong credential-exposure pattern.

Credential Access

High
Category
Privilege Escalation
Content
echo "[HB] $(date +%H:%M:%S) started for $GAME_ID" >> "$LOG"

while true; do
    source /tmp/cwc/creds.env
    python3 -c "
import json
d = {'gameId': '$GAME_ID'}
Confidence
95% confidence
Finding
The loop repeatedly sources the credential file, increasing opportunities for tampering or theft during runtime. A malicious local process could potentially replace or read the file to hijack the session.

Credential Access

High
Category
Privilege Escalation
Content
# ── POST A SINGLE THOUGHT ────────────────────────────────────────────
post_thought() {
    [ -z "$1" ] && return
    source /tmp/cwc/creds.env
    python3 -c "
import json
d = {'gameId': '$GAME_ID', 'thought': '$1'}
Confidence
91% confidence
Finding
post_thought sources the same temp credential file before external transmission, extending secret exposure into another code path. The pattern is repeated enough to make credential leakage systemic rather than incidental.

Credential Access

High
Category
Privilege Escalation
Content
rm -f /tmp/cwc/llm_needed.flag

    if [ -f /tmp/cwc/llm_minds.env ]; then
        source /tmp/cwc/llm_minds.env
        rm -f /tmp/cwc/llm_minds.env
        log "LLM decision received after ${waited}s"
Confidence
83% confidence
Finding
Sourcing llm_minds.env from disk allows command/value injection if another process can modify that file, because shell source executes assignments in a trusted context. While not a credential file, it is still unsafe file-based trust.

Credential Access

High
Category
Privilege Escalation
Content
done
    rm -f /tmp/cwc/chat_needed.flag

    if [ -f /tmp/cwc/chat_reply.env ]; then
        source /tmp/cwc/chat_reply.env
        rm -f /tmp/cwc/chat_reply.env
        log "Chat reply received after ${waited}s"
Confidence
82% confidence
Finding
Sourcing chat_reply.env trusts disk content as shell code/data, enabling injection if the file is modified by another process. Though not credentials, it is still unsafe trust in a temp env file.

Credential Access

High
Category
Privilege Escalation
Content
# ── SEND CHAT MESSAGE (with typing indicator) ────────────────────────
send_chat() {
    source /tmp/cwc/creds.env
    python3 -c "
import json
with open('/tmp/cwc/typing.json', 'w') as f:
Confidence
91% confidence
Finding
send_chat again sources plaintext credentials from /tmp before transmitting externally, repeating the same secret-management weakness in another high-frequency path. Predictable temp-file secrets are vulnerable to local disclosure and tampering.

Credential Access

High
Category
Privilege Escalation
Content
# ── SUBMIT MOVE with thought (atomic) ───────────────────────────────
submit_move() {
    source /tmp/cwc/creds.env
    python3 -c "
import json
d = {'gameId': '$GAME_ID', 'move': '$1', 'thinking': '$2'}
Confidence
91% confidence
Finding
submit_move uses the same insecure credential-loading pattern from a temp file. This broad reuse of plaintext secrets makes session hijacking more feasible if the host is shared or compromised.

Credential Access

High
Category
Privilege Escalation
Content
# MAIN GAME LOOP
# ═══════════════════════════════════════════════════════════

source /tmp/cwc/creds.env

LAST_MOVE_COUNT=0
LAST_HUMAN_CHAT_COUNT=0
Confidence
90% confidence
Finding
The main game loop sources the temp credential file at startup, cementing insecure secret handling as the default architecture. Any readable temp artifact containing tokens is a high-value target.

Credential Access

High
Category
Privilege Escalation
Content
"

while true; do
    source /tmp/cwc/creds.env

    RESPONSE=$(curl -s --max-time 10 \
        "https://chesswithclaw.vercel.app/api/poll?gameId=$GAME_ID&last_move_count=$LAST_MOVE_COUNT&last_human_chat_count=$LAST_HUMAN_CHAT_COUNT" \
Confidence
90% confidence
Finding
Re-sourcing creds.env inside the poll loop continuously depends on a mutable plaintext token file in /tmp. That creates persistent exposure and possible tampering throughout the session.

Credential Access

High
Category
Privilege Escalation
Content
FAREWELL_IDX=$(( RANDOM % ${#FAREWELL_MESSAGES[@]} ))
            FAREWELL="${FAREWELL_MESSAGES[$FAREWELL_IDX]}"
            send_chat "$FAREWELL"
            printf 'export FAREWELL_SENT=1\n' >> /tmp/cwc/creds.env
        fi
        
        printf 'export GAME_ENDED=true\n' >> "$STATE_FILE"
Confidence
78% confidence
Finding
Appending flags to creds.env mixes runtime state with credentials in one file, increasing the chance of corruption or unintended disclosure. Combining secrets and mutable state is poor isolation practice.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
SKILL.md:1670