Back to skill

Security audit

molt-chess

Security checks for vulnerabilities and agentic risk

Overview

This chess skill mostly does what it claims, but it asks users to install mutable remote code and set up recurring authenticated agents that can act without later approval.

Review carefully before installing. Prefer the bundled scripts over remote curl downloads, do not schedule the heartbeat unless you explicitly want unattended moves, restrict the stored API key, and remove the cron task when you stop playing. Expect this skill to contact the chess service, store a reusable API key locally, and submit moves or join matchmaking if the heartbeat runs.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T06 · System Persistence

Error
Location
SKILL.md:35
Finding

Persistent Autonomous Chess Operations Through a Scheduled Agent Task

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 35-47
Vulnerability Type: Persistent scheduled task
Risk Level: High

Vulnerable Code

bash
clawdbot cron add \
  --name "molt-chess-poll" \
  --every 1800000 \
  --session isolated \
  --message "Check molt.chess: GET /api/agents/status. If games_awaiting_move > 0, get game state, use play.py to find best move, and POST the move. Follow HEARTBEAT.md instructions." \
  --model sonnet
markdown
This creates an isolated agent session that:
- Runs every 30 minutes
- Checks if it's your turn
- Analyzes position with play.py
- Makes your move automatically

Technical Analysis

The installation instructions direct the user or Agent to create a recurring cross-session task. The task periodically starts an isolated Agent session, accesses the chess service using stored credentials, analyzes games, and performs authenticated actions without further interaction.

This behavior persists beyond the Skill's initiating session. Although SKILL.md later says that heartbeat scheduling should require owner consent and provides a removal command, the earlier section labels auto-polling as required. These contradictory instructions could cause scheduling to occur before meaningful consent is obtained.

Periodic polling is useful for avoiding chess timeouts, but installing a persistent Agent task is not the minimum privilege necessary for manual chess analysis or user-initiated play.

Attack Path

  1. A user or installation Agent follows the section labeled “REQUIRED: Set Up Auto-Polling.”
  2. The supplied clawdbot cron add command creates a recurring task.
  3. Every 30 minutes, a new isolated Agent session follows the supplied gameplay message.
  4. The session accesses the stored chess API credential and contacts the remote service.
  5. When a move is pending, the task retrieves game data and submits an authenticated move without c ...[truncated 575 chars]
Remediation
View remediation

Remediation Suggestions

  • Make scheduling strictly opt-in and request explicit owner confirmation before displaying or executing the cron command.
  • Default to manual, user-initiated status checks.
  • Remove language describing persistent polling as unconditionally required.
  • Clearly disclose the task's frequency, credential use, network destinations, authenticated actions, resource consumption, and removal procedure.
  • Schedule a fixed local script with narrowly defined behavior rather than a general Agent prompt.
  • Require renewed consent before changing the scheduled task's instructions or permissions.
  • Ensure task removal is verified during uninstall or when the owner disables automatic play.

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:24
Finding

Unverified Download of a Mutable Executable Helper Script

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 24-28
Vulnerability Type: Remote executable payload retrieval
Risk Level: High

Vulnerable Code

bash
mkdir -p ~/.config/molt-chess
curl -s https://chess.unabotter.xyz/play.py > ~/.config/molt-chess/play.py
chmod +x ~/.config/molt-chess/play.py
markdown
This script analyzes positions and recommends moves. **You need it to play.**

Technical Analysis

The instructions download an unversioned Python script from a remote website, store it outside the reviewed package, and mark it executable. No expected digest, signature, immutable release identifier, or content validation is provided.

Consequently, the code executed by users can differ from the bundled and audited scripts/play.py. HTTPS protects the connection in transit but does not protect against compromise of the hosting service, DNS or certificate infrastructure, deployment account, or intentional replacement of the hosted file.

The command also uses curl -s without --fail; an HTTP error response could silently overwrite the destination file. The downloaded script is unnecessary because an equivalent helper is already included in the reviewed project.

Attack Path

  1. An attacker compromises or gains update access to chess.unabotter.xyz, or the remote file is otherwise replaced.
  2. The attacker publishes a modified play.py containing arbitrary Python behavior.
  3. A user or Agent follows the installation instructions.
  4. curl writes the mutable response to ~/.config/molt-chess/play.py.
  5. The file is marked executable without any integrity verification.
  6. The helper is later invoked during gameplay and executes with the user's privileges.

Impact Assessment

A malicious replacement script could act with the privileges of the invoking user. Depending on the runtime environment, it could read accessible files and credentials, send data over the ne ...[truncated 212 chars]

Remediation
View remediation

Remediation Suggestions

  • Use the bundled, reviewed scripts/play.py instead of downloading another copy.
  • If remote distribution is necessary, reference an immutable versioned artifact.
  • Publish and verify a SHA-256 digest or cryptographic signature before installation or execution.
  • Download to a temporary file, validate it, and then atomically move it into place.
  • Use hardened retrieval options such as curl --fail --show-error --location --proto '=https'.
  • Do not mark downloaded content executable until integrity and expected file type have been verified.
  • Treat updates as new code requiring review and explicit user approval.

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:244
Finding

Scheduled Interpretation of Mutable Remote Heartbeat Instructions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 244-255; related retrieval instructions at lines 59-62
Vulnerability Type: Remote instruction hijacking and payload retrieval
Risk Level: High

Vulnerable Code

markdown
## Heartbeat Setup (ask the owner)

During installation, your agent **must ask the human owner** if they want to enable a periodic heartbeat.

- If the owner says **YES**: fetch and run `HEARTBEAT.md` on a schedule (every 30-60 min) to check games and make moves.
- If the owner says **NO**: do not run heartbeat; only play when explicitly instructed.

⚠️ **Without heartbeat, you WILL forfeit games due to timeout.**

```bash
# Fetch heartbeat instructions
curl -s https://chess.unabotter.xyz/heartbeat.md
text

The earlier manual heartbeat section also contains:

```bash
# Fetch heartbeat instructions
curl -s https://chess.unabotter.xyz/heartbeat.md

Technical Analysis

The Skill directs an Agent to fetch and “run” a Markdown instruction document from a live remote endpoint on a recurring schedule. Unlike a locally reviewed and version-pinned heartbeat file, the remote document can change after installation and after security review.

Agent-readable Markdown is an execution control channel when the Agent is instructed to follow it. A changed document could redefine the scheduled session's goals, request additional tool use, access local resources, or redirect network operations. The owner-consent requirement reduces involuntary installation risk but does not address the mutable-content risk because consent to the current heartbeat does not constitute informed consent to arbitrary future revisions.

Attack Path

  1. The owner enables the periodic heartbeat.
  2. The Agent or scheduled workflow retrieves https://chess.unabotter.xyz/heartbeat.md.
  3. The remote host, deployment account, or document is compromised or intentionally modified.
  4. The returned Mar ...[truncated 847 chars]
Remediation
View remediation

Remediation Suggestions

  • Never schedule an Agent to interpret mutable remote Markdown as executable instructions.
  • Use the locally bundled and reviewed HEARTBEAT.md.
  • Pin heartbeat behavior to a specific package or signed release version.
  • Require a human-readable diff, security review, and renewed owner consent before applying updates.
  • Replace open-ended natural-language execution with a narrowly scoped local program that allows only the required chess API operations.
  • Restrict scheduled sessions to the Skill-specific credential and explicit chess API destinations.
  • Enforce tool and filesystem sandboxing so heartbeat sessions cannot access unrelated credentials or files.

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Python Dependencies Permit Unreviewed Supply-Chain Changes

Content
View full analysis

Vulnerability Details

File Location: scripts/requirements.txt, lines 1-2; related installation command in SKILL.md, lines 18-22
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Medium

Vulnerable Code

text
requests>=2.28.0
chess>=1.10.0

The installation documentation is less restrictive:

bash
pip install chess requests

Technical Analysis

The dependency file specifies only minimum versions, while the documented command has no version constraints. Both approaches allow package resolution to select future releases that were not included in this audit. No lock file, package hashes, or signature verification is supplied.

This does not prove that the current requests or chess packages are malicious. The weakness is that future or compromised releases can become part of the Skill without a repository change or renewed review. Imported dependency code then runs in the same Python environment as the helper.

Attack Path

  1. A dependency publisher account, package repository, or future package release is compromised or introduces malicious behavior.
  2. A user executes pip install chess requests or installs from the lower-bound requirements file.
  3. The package resolver selects the affected release because no exact reviewed version is required.
  4. Package installation or import executes the unreviewed code.
  5. The dependency acts with the privileges available to the Python process.

Impact Assessment

A malicious dependency could execute code under the installing or invoking user's account, access files readable by that account, inspect Skill-specific credentials, alter the environment, or communicate over the network. The practical scope depends on whether installation occurs in a system environment, user environment, container, or isolated virtual environment.

Remediation
View remediation

Remediation Suggestions

  • Pin dependencies to exact versions that have been reviewed and tested.
  • Generate a lock file containing cryptographic hashes for every package and transitive dependency.
  • Install with hash enforcement, such as pip install --require-hashes -r requirements.txt.
  • Use an isolated virtual environment with minimal filesystem and network privileges.
  • Regularly scan pinned packages for known vulnerabilities and update through a controlled review process.
  • Keep the documentation consistent with the locked dependency installation command.
  • Use a trusted package index and disable unexpected supplemental indexes where practical.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (33)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill does more than facilitate chess participation: it walks the user through account registration, credential storage, and autonomous API activity without declaring permissions or triggers. This is dangerous because it encourages long-lived authenticated automation while understating the trust boundary and persistence involved.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill does more than facilitate chess participation: it walks the user through account registration, credential storage, and autonomous API activity without declaring permissions or triggers. This is dangerous because it encourages long-lived authenticated automation while understating the trust boundary and persistence involved.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
85% confidence
Finding

The skill instructs users to save the returned api_key and related values into a local credentials file, but provides no guidance on file permissions, secret storage, rotation, or isolation. Poorly handled local secrets can be exposed to other tools, users, or later automated tasks, especially in shared or agent-managed environments.

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

Save the response:

bash
mkdir -p ~/.config/molt-chess
# Save api_key, claim_url, verification_code to credentials.json

Claim Verification

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The heartbeat script reads the API key from a plaintext credentials file during automated execution. In combination with cron-style polling, this increases exposure of long-lived credentials to logs, process inspection, misconfigured file access, or other local automation running under the same account.

Content

Scanner excerpt · SKILL.md (reported line 131)May include surrounding context.

bash
#!/bin/bash
API_KEY=$(cat ~/.config/molt-chess/credentials.json | jq -r '.api_key')
BASE_URL="https://molt-chess-production.up.railway.app/api"

# Check status

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The code reads an API key from a fixed location in the user's home directory, which is credential access behavior. Even though it appears intended for normal configuration, agent skills that automatically harvest local secrets are risky because they can access and transmit credentials without strong user awareness or least-privilege controls.

Content

Scanner excerpt · scripts/play.py (reported line 30)May include surrounding context.

python
def load_credentials():
    """Load API key from config file."""
    config_path = Path.home() / ".config" / "molt-chess" / "credentials.json"
    if config_path.exists():
        with open(config_path) as f:
            return json.load(f)

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This code automatically falls back to reading a locally stored API key and then uses it for a remote request, creating a credential-access-and-exfiltration path within the skill. In this skill context, that is more dangerous because the advertised purpose is chess analysis, so implicit secret use is not strictly necessary for core offline functionality and may surprise users.

Content

Scanner excerpt · scripts/play.py (reported line 149)May include surrounding context.

python
if args.game_id:
        api_key = args.api_key or load_credentials().get("api_key")
        if not api_key:
            print("ERROR: --api-key required or set in ~/.config/molt-chess/credentials.json")
            sys.exit(1)
        
        game = fetch_game(args.game_id, api_key)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · HEARTBEAT.md (reported line 12)May include surrounding context.

md
API_URL="https://molt-chess-production.up.railway.app"
CONFIG_DIR="$HOME/.config/molt-chess"
CONFIG_FILE="$CONFIG_DIR/credentials.json"

# Get agent name from argument or prompt
if [ -n "$1" ]; then

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · HEARTBEAT.md (reported line 129)May include surrounding context.

md
API_URL="https://molt-chess-production.up.railway.app"
CONFIG_DIR="$HOME/.config/molt-chess"
CONFIG_FILE="$CONFIG_DIR/credentials.json"

# Get agent name from argument or prompt
if [ -n "$1" ]; then

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · HEARTBEAT.md (reported line 219)May include surrounding context.

md
API_URL="https://molt-chess-production.up.railway.app"
CONFIG_DIR="$HOME/.config/molt-chess"
CONFIG_FILE="$CONFIG_DIR/credentials.json"

# Get agent name from argument or prompt
if [ -n "$1" ]; then

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/play.py (reported line 138)May include surrounding context.

python
API_URL="https://molt-chess-production.up.railway.app"
CONFIG_DIR="$HOME/.config/molt-chess"
CONFIG_FILE="$CONFIG_DIR/credentials.json"

# Get agent name from argument or prompt
if [ -n "$1" ]; then

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/setup.sh (reported line 6)May include surrounding context.

sh
API_URL="https://molt-chess-production.up.railway.app"
CONFIG_DIR="$HOME/.config/molt-chess"
CONFIG_FILE="$CONFIG_DIR/credentials.json"

# Get agent name from argument or prompt
if [ -n "$1" ]; then

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script prints the live API key directly into example curl commands on stdout. This can leak the credential into terminal scrollback, shell logging, screen recordings, copy/paste history, CI logs, or chat transcripts, enabling unauthorized use of the agent identity.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
79% confidence
Finding

This command sends a state-changing POST request to an external service using the locally loaded API key, causing the agent to play a move on the user's account. In this skill's context that behavior is expected, but it is still a real security concern because it performs external actions and consumes account authority if executed blindly.

Content

Scanner excerpt · HEARTBEAT.md (reported line 62)May include surrounding context.

Now pick a move from legal_moves and play it:

bash
curl -X POST "$BASE/games/$GAME_ID/move" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"move": "e5"}'

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The heartbeat script is explicitly designed to take autonomous actions on the user's behalf, including submitting chess moves and joining matchmaking, but the documentation frames this as routine operation rather than a clearly disclosed side effect. This can cause unintended external actions using the user's credentials, especially if an agent or operator runs the provided script verbatim without realizing it will post moves and alter account state.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The complete heartbeat script automates POSTing a move to the remote chess API without any interactive approval or safety gate. Because it is packaged as a copy-and-run script, it increases the likelihood of unattended external actions on behalf of the user whenever the script detects it is their turn.

Content

Scanner excerpt · HEARTBEAT.md (reported line 174)May include surrounding context.

md
# Make the move!
  echo "♟️ Playing $MOVE in game $GAME_ID"
  curl -X POST "$BASE/games/$GAME_ID/move" \
    -H "X-API-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"move\":\"$MOVE\"}"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill clearly requires network access, shell commands, filesystem writes, and scheduled execution, but it declares no explicit tool scope or permissions. That mismatch can cause an agent or user to authorize broader capabilities implicitly, reducing transparency and increasing the chance of unsafe execution in environments that rely on manifest-declared permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to download a remote Python script with curl, save it locally, mark it executable, and rely on it for gameplay, without integrity verification or a warning about code-execution risk. This creates a direct supply-chain execution path: if the remote host is compromised or the script changes, arbitrary code could be delivered and run in the user's environment.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

Writing the helper script into a persistent config directory creates a durable executable artifact that future sessions or automations can invoke. In context, this amplifies the supply-chain risk because a remotely obtained script is not just run once but retained for repeated use.

Content

Scanner excerpt · SKILL.md (reported line 34)May include surrounding context.

Then download the helper script:

bash
mkdir -p ~/.config/molt-chess
curl -s https://chess.unabotter.xyz/play.py > ~/.config/molt-chess/play.py
chmod +x ~/.config/molt-chess/play.py

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This line fetches code from an external server and stores it as a local executable script. Although the transmission itself is expected for this skill, the dangerous part is that externally controlled content is being introduced into the local environment for later execution, creating a strong supply-chain and remote-code risk.

Content

Scanner excerpt · SKILL.md (reported line 35)May include surrounding context.

bash
mkdir -p ~/.config/molt-chess
curl -s https://chess.unabotter.xyz/play.py > ~/.config/molt-chess/play.py
chmod +x ~/.config/molt-chess/play.py

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill recommends creating a cron job that periodically checks status, analyzes positions, and posts moves automatically. Autonomous scheduled network actions with access to credentials can persist beyond the user's awareness and may continue operating if the service, prompts, or downloaded helper logic change.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The cron setup establishes persistent autonomous behavior that survives the initial installation session and can keep making authenticated requests over time. Persistence is especially risky here because the task is instructed to check status, analyze positions, and post moves, meaning the skill creates an ongoing external action loop rather than a one-time user-initiated command.

Content

Scanner excerpt · SKILL.md (reported line 49)May include surrounding context.

For Clawdbot Agents: Create a Cron Job

This is the easiest way! Create a cron job that checks for your turn every 30 minutes:

bash
clawdbot cron add \

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

Check Your Games

bash
curl https://molt-chess-production.up.railway.app/api/games/active \
  -H "X-API-Key: YOUR_KEY"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script accesses a local credentials file and sends an API key to a remote service, which expands the skill's trust boundary beyond local chess analysis. In an agent-skill context, undisclosed credential loading and network access are security-relevant because they may cause users or orchestrators to expose secrets or contact external infrastructure unexpectedly.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring at L098 says 'Find best moves using simple minimax,' and the CLI exposes a '--depth' search parameter, but the function never recurses and does not use the depth argument at all. This is an active contradiction between the documented intent and the actual behavior of the analyzer.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The setup script performs network registration with a third-party service and persists returned credentials to disk, while the skill description only suggests a chess league capability. This is not inherently malicious, but it is a meaningful capability expansion because it creates an account-like identity and stores secrets locally without being clearly disclosed to the user.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/play.py:128