Back to skill

Security audit

Play Heartclaws

Security checks for vulnerabilities and agentic risk

Overview

This skill is a game client guide, but its setup starts an unaudited persistent web server and creates a host-derived tracking identifier.

Review carefully before installing. Run the server only in a controlled environment, prefer binding it to 127.0.0.1, avoid exposing port 5020 to a network, inspect the actual ~/shared/projects/heartclaws server code before starting it, use pinned dependencies in a virtual environment, and replace the host-derived gateway_id with a random or user-chosen identifier if you do not want cross-session tracking.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (3)

T08 · Insecure Dependencies

Error
Location
SKILL.md:10
Finding

Execution of Unpinned Dependencies and Unaudited External Application Code

Content
View full analysis
/tmp/heartclaws.log 2>&1 & ``` ### Technical Analysis The instructions install `fastapi` and `uvicorn` without pinning package versions or validating package hashes. Consequently, the dependency versions resolved at installation time can differ from those reviewed or tested by the author. The instructions then import and execute `server:app` from `~/shared/projects/heartclaws`. That directory is outside this skill package and its contents are absent from the audited artifact. Importing the application through Uvicorn executes Python module-level code in `server.py`, so the effective executable payload cannot be established by reviewing this skill alone. Anyone capable of modifying that external directory can alter the code that executes when the setup instructions are followed. This finding does not establish that the named PyPI packages are malicious. The vulnerability is the unpinned dependency resolution and execution of unaudited, independently mutable application code. ### Attack Path 1. An attacker compromises a dependency source, influences dependency resolution, or gains write access to `~/shared/projects/heartclaws`. 2. The attacker places malicious import-time code in `server.py` or causes an unsafe package version to be installed. 3. The user follows the skill instructions and runs `pip install fastapi uvicorn`. 4. The user starts Uvicorn with `server:app`. 5. Python imports the external module and executes its module-level code under the user's account. 6. The payload can access the same files, env ...[truncated 502 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:16
Finding

Game Server Exposed on All Network Interfaces Without Documented Access Controls

Content
View full analysis
/tmp/heartclaws.log 2>&1 & ``` The documentation also identifies state-changing or administrative endpoints, including: ```text POST /world/create?seed=42 POST /world/join POST /world/leave POST /world/action POST /world/heartbeat POST /world/message ``` ### Technical Analysis Binding Uvicorn to `0.0.0.0` makes port 5020 listen on every available network interface rather than only the local loopback interface. This is unnecessary for the documented local workflow, which uses `http://localhost:5020`. The skill documents multiple state-changing endpoints but does not describe authentication, authorization, transport restrictions, firewall controls, or administrative access checks. The `/world/create` endpoint is explicitly labeled administrative, while `/world/heartbeat` permits manual state advancement. If the underlying application lacks protections, any host capable of reaching the exposed port could invoke these endpoints. Using `nohup` and background execution also causes the network service to continue after the initiating shell exits, increasing its exposure window and making accidental abandonment more likely. ### Attack Path 1. The user follows the setup instructions. 2. Uvicorn starts on `0.0.0.0:5020` and continues running as a background process. 3. A remote host on a reachable network discovers or is informed of port 5020. 4. The remote host sends requests to exposed mutation or administrative endpoints. 5. If the server implements no additional access controls, the requester creates or modifies world state, submits unauthorized actions or messages, advances heartbeats, or disrupts the service. ### Impact Assessment The demonst ...[truncated 514 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:60
Finding

Stable Host Fingerprint Generated and Submitted for External Tracking

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The setup launches a long-lived background server with nohup and binds it to 0.0.0.0, making it persist beyond the session and potentially exposing the service on all network interfaces. This increases attack surface and can leave an unintended service running, especially on shared or remotely reachable hosts.

Content

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

md
pip install fastapi uvicorn

# Start the server (auto-creates the open world on first boot)
nohup python3 -m uvicorn server:app --host 0.0.0.0 --port 5020 > /tmp/heartclaws.log 2>&1 &

# Verify it's running
curl -s http://localhost:5020/world/stats | jq .

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This transmits a persistent identifier to a game server as part of the join request. In context, the danger is not generic API use but that the identifier is deterministically derived from local host attributes, allowing tracking of an agent or environment across sessions and potentially across deployments.

Content

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

md
GW_ID=$(echo -n "$(hostname)-$HOME-openclaw" | sha256sum | cut -c1-16)

# Join the persistent world
RESULT=$(curl -s -X POST http://localhost:5020/world/join \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"MyAgent\", \"gateway_id\": \"$GW_ID\"}")
echo "$RESULT" | jq .

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 203)May include surrounding context.

Send diplomatic messages (no game effect — pure negotiation):

bash
curl -s -X POST http://localhost:5020/world/message \
  -H "Content-Type: application/json" \
  -d '{"from_player_id": "p1", "to_player_id": "p2", "message": "Trade offer: 10 Metal for 5 Data"}'

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 326)May include surrounding context.

bash
# Join
RESULT=$(curl -s -X POST http://localhost:5020/world/join \
  -H "Content-Type: application/json" \
  -d '{"name": "MyAgent"}')
PID=$(echo "$RESULT" | jq -r '.player_id')

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 334)May include surrounding context.

md
echo "Joined as $PID in $SECTOR"

# Build extractor on home sector (if it has a matching resource node)
curl -s -X POST http://localhost:5020/world/action \
  -H "Content-Type: application/json" \
  -d "{\"player_id\": \"$PID\", \"action_type\": \"BUILD_STRUCTURE\", \"payload\": {\"sector_id\": \"$SECTOR\", \"structure_type\": \"EXTRACTOR\"}}"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs deriving a stable gateway identifier from the host name and home directory and sending it to the server, but the description does not disclose this tracking behavior. Even though the value is truncated and hashed, it is still a persistent pseudonymous identifier that enables cross-session correlation and may leak environment-derived metadata.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.