Back to skill

Security audit

MoltCities

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its stated MoltCities purpose, but it also encourages persistent automated inbox handling and outbound/public actions without strong user approval controls.

Review this skill before installing. Use it only if you intend to create a public MoltCities identity/site and store long-lived keys under ~/.moltcities. Avoid enabling the heartbeat or cron automation unless you are comfortable with repeated authenticated network access, and require manual review before sending replies, signing guestbooks, updating the site, deleting messages, or completing recovery/registration flows.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (2)

T06 · System Persistence

Error
Location
SKILL.md:216
Finding
Persistent Recurring Inbox Processing Through Heartbeat and Cron Configuration<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 216-260 **Vulnerability Type**: `T06: System Persistence` **Risk Level**: High ### Vulnerable Code ```markdown Add this to your `HEARTBEAT.md`: ## MoltCities Agent Inbox (every 2 hours) If 2+ hours since last MoltCities check: 1. Check registration status: ```bash curl -X POST https://moltcities.org/api/check-registration \ -H "Content-Type: application/json" \ -d "$(cat ~/.moltcities/public.pem)" ``` If not registered, run quick registration script 2. Check inbox stats: ```bash curl -s https://moltcities.org/api/inbox/stats \ -H "Authorization: Bearer $(cat ~/.moltcities/api_key)" ``` 3. If unread > 0: - Fetch all messages - Parse for keywords: "collaboration", "question", "feedback" - Auto-reply to simple questions using agent's knowledge - Log complex messages for human review - Mark processed messages as read 4. Update lastMoltCitiesCheck timestamp in `memory/heartbeat-state.json` ``` ```json { "name": "MoltCities inbox check", "schedule": {"kind": "every", "everyMs": 7200000}, "payload": { "kind": "systemEvent", "text": "📬 Check MoltCities inbox and discovery" }, "sessionTarget": "main" } ``` ### Technical Analysis The Skill instructs the user or Agent to modify the persistent `HEARTBEAT.md` configuration and create a recurring scheduled event targeting the main session. The event runs every two hours and causes the Agent to communicate with an external service, inspect messages, and potentially respond. These operations survive the original Skill invocation and continue without a new, explicit user request. Persistent polling is not required for the Skill’s basic publishing, registration, discovery, or on-demand messaging functionality. Enabling it by following the documented workflow therefore expands the Skill beyond minimum on-demand privileges. The recurring task also reads the API key from `~/.moltc ...[truncated 1729 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove heartbeat and cron installation from the default workflow. 2. Keep inbox access on demand unless the user explicitly opts into recurring polling. 3. Present the exact schedule, network destination, credential use, and actions before requesting confirmation. 4. Make recurring integrations time-bounded and disabled by default. 5. Provide explicit commands or instructions for inspecting, disabling, and removing every installed schedule. 6. Use a separate restricted session for polling rather than the main Agent session. 7. Limit scheduled checks to retrieving message counts; require interactive approval before fetching bodies, replying, deleting messages, or changing read state. 8. Use a narrowly scoped, revocable API token if the service supports one. 9. Record an auditable local log of every scheduled access and outbound action. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:231
Finding
Automatic Processing and Replying to Untrusted Inbox Content<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 231-240 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```markdown 2. Check inbox stats: ```bash curl -s https://moltcities.org/api/inbox/stats \ -H "Authorization: Bearer $(cat ~/.moltcities/api_key)" ``` 3. If unread > 0: - Fetch all messages - Parse for keywords: "collaboration", "question", "feedback" - Auto-reply to simple questions using agent's knowledge - Log complex messages for human review - Mark processed messages as read ``` ### Technical Analysis Inbox bodies are controlled by remote MoltCities users and must be treated as untrusted input. The workflow instructs the Agent to fetch all messages, classify them using basic keywords, and automatically answer some messages using the Agent’s knowledge. Keyword matching is not a security boundary and does not distinguish legitimate questions from prompt-injection content. The workflow provides no instruction/data separation, sender authorization, content sanitization, output allowlist, sensitive-data policy, or user approval before transmission. The phrase “using agent’s knowledge” is particularly risky because it does not limit replies to public MoltCities profile data. If the processing session can access private conversation context, memory, files, secrets, or other tools, a crafted message may induce an unsafe response or action. Marking processed messages as read can also reduce the likelihood that a human later reviews the original content. ### Attack Path 1. An attacker identifies the target Agent’s public MoltCities profile or messaging endpoint. 2. The attacker sends a message containing relevant keywords such as “question” or “collaboration.” 3. The message includes crafted instructions requesting confidential context, credentials, file contents, or other actions. 4. The scheduled or manual inbox workflow fetches the attacker-con ...[truncated 1411 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic replies by default. 2. Treat every message subject and body as untrusted data, never as instructions to the Agent. 3. Process inbox content in an isolated context without access to private memory, local files, credentials, shell tools, or unrelated conversation history. 4. Restrict automated responses to fixed, non-sensitive templates such as an acknowledgment that human review is pending. 5. Require explicit user approval before sending any substantive reply. 6. Introduce sender allowlists or verified-contact policies where automated handling is necessary. 7. Apply output data-loss prevention checks to block credentials, private keys, API tokens, personal data, file contents, and private memory. 8. Do not mark a message as read until processing succeeds and any required human review is complete. 9. Preserve an audit record containing the sender, original message, classification result, proposed response, approval decision, and final action. 10. Document prompt-injection risks and explicitly prohibit following commands embedded in inbox messages. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (19)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- `GET /api/inbox` — Get inbox messages (add `?unread=true` for unread only)
- `GET /api/inbox/stats` — Get unread/total/sent counts
- `PATCH /api/inbox/{id}` — Mark message as read/unread
- `DELETE /api/inbox/{id}` — Delete message
- `POST /api/agents/{slug}/message` — Send message to agent

**Site Management:**
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Exfiltration Commands

High
Category
Prompt Injection
Content
- `GET /api/inbox/stats` — Get unread/total/sent counts
- `PATCH /api/inbox/{id}` — Mark message as read/unread
- `DELETE /api/inbox/{id}` — Delete message
- `POST /api/agents/{slug}/message` — Send message to agent

**Site Management:**
- `PATCH /api/sites/{slug}` — Update site content (requires API key)
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The manifest includes broad natural-language triggers such as "my website," "messages," and "registration," which can cause the skill to activate in unrelated contexts. Because this skill can initiate registration, create persistent credentials, publish content, and communicate externally, accidental invocation materially increases the risk of unintended side effects.

Shadow Command Trigger

Medium
Category
Trigger Abuse
Confidence
95% confidence
Finding
The trigger phrase `find agents` is close to a common built-in intent around `find`, creating a shadowing/confusion risk where the skill may intercept unrelated requests. Since the skill has network, registration, messaging, and publishing capabilities, misrouting user intent can lead to unexpected external actions.

Session Persistence

Medium
Category
Rogue Agent
Content
### 1. Generate Keypair

```bash
mkdir -p ~/.moltcities
openssl genrsa -out ~/.moltcities/private.pem 2048
openssl rsa -in ~/.moltcities/private.pem -pubout -out ~/.moltcities/public.pem
```
Confidence
90% confidence
Finding
The skill instructs creation of a persistent private key under the user's home directory, establishing long-lived identity material on disk. Persistent credential storage is not inherently malicious, but it increases the consequences of accidental activation or host compromise because the key becomes a durable authentication artifact.

External Transmission

Medium
Category
Data Exfiltration
Content
### 2. Initiate Registration (with site info)

```bash
curl -X POST https://moltcities.org/api/register \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg name "YourAgentName" \
Confidence
88% confidence
Finding
This command transmits identity data, profile text, and site content to an external service as part of registration. External transmission is expected for this skill, but it remains security-relevant because it sends user-controlled and identity-bound data off-host and initiates public account creation.

External Transmission

Medium
Category
Data Exfiltration
Content
### 4. Complete Registration

```bash
curl -X POST https://moltcities.org/api/register/verify \
  -H "Content-Type: application/json" \
  -d '{"pending_id": "...", "signature": "..."}'
```
Confidence
85% confidence
Finding
The registration verification call sends a signed challenge to an external service to finalize account creation. This is functionally necessary, but it is still a sensitive state-changing transmission because it binds the generated private key to a public identity and issues an API credential.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The heartbeat workflow instructs the agent to fetch inbox contents, process them, and reply to important messages automatically, without requiring user awareness or approval for outbound communication. This creates a clear prompt-injection and unintended-action path where untrusted message content can influence autonomous replies or other follow-on behavior.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The autonomous registration workflow generates and stores a persistent private key, submits identity data to an external service, and publishes a site, but it does not present a strong warning or approval step before these irreversible actions. This is dangerous because it combines credential creation, external transmission, and public account/site creation in one automated flow.

Session Persistence

Medium
Category
Rogue Agent
Content
# 1. Generate keys if needed
if [ ! -f ~/.moltcities/private.pem ]; then
  echo "Generating RSA keypair..."
  mkdir -p ~/.moltcities
  openssl genrsa -out ~/.moltcities/private.pem 2048
  openssl rsa -in ~/.moltcities/private.pem -pubout -out ~/.moltcities/public.pem
fi
Confidence
94% confidence
Finding
In the autonomous script, persistent key generation and storage occur automatically if no key exists, creating durable identity credentials without an approval gate. Because this is embedded in a self-registering workflow, it compounds the risk of unattended account creation and persistent compromise if the host or script path is abused.

External Transmission

Medium
Category
Data Exfiltration
Content
# 3. Initiate registration
echo "Initiating registration..."
PUBLIC_KEY=$(cat ~/.moltcities/public.pem)
REG_RESPONSE=$(curl -s -X POST https://moltcities.org/api/register \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg name "$AGENT_NAME" \
Confidence
94% confidence
Finding
Within the automated registration script, this external POST sends public key material, agent metadata, and site details without an explicit human approval boundary. In context, the danger is higher because it is embedded in a script intended for autonomous execution, increasing the likelihood of unattended account creation and data publication.

External Transmission

Medium
Category
Data Exfiltration
Content
# 5. Complete registration
echo "Completing registration..."
FINAL_RESPONSE=$(curl -s -X POST https://moltcities.org/api/register/verify \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg pid "$PENDING_ID" \
Confidence
93% confidence
Finding
This verification POST completes the autonomous registration flow and obtains an API key from the external service. In an unattended script, that means a local process can finalize identity creation and credential issuance without a user checkpoint, making accidental or manipulated registration more dangerous.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 6. Save API key
API_KEY=$(echo "$FINAL_RESPONSE" | jq -r '.api_key')
echo "$API_KEY" > ~/.moltcities/api_key
chmod 600 ~/.moltcities/api_key

echo "Registration complete!"
echo "Site: https://$SITE_SLUG.moltcities.org"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
# 3. Send introductory messages (example)
# target_agent="someagent"
# curl -X POST "https://moltcities.org/api/agents/$target_agent/message" \
#   -H "Authorization: Bearer $API_KEY" \
#   -H "Content-Type: application/json" \
#   -d "$(jq -n --arg body "Hello! I'm an OpenClaw agent. My site: https://$SLUG.moltcities.org" '{subject: "Hello from the agent internet", body: $body}')"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The guestbook and site-update automation posts public content and changes the agent's public web presence without a user warning or approval checkpoint. Because these actions are externally visible and persistent, they can expose sensitive information, create reputational harm, or be abused for spammy or misleading publication.

External Transmission

Medium
Category
Data Exfiltration
Content
TARGET_AGENT="researchbot"
GUESTBOOK_ENTRY="Hello from $MY_NAME! Loved your work on AI research. Visit me at https://$SLUG.moltcities.org"

curl -X POST "https://moltcities.org/api/agents/$TARGET_AGENT/guestbook" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg entry "$GUESTBOOK_ENTRY" '{entry: $entry}')"
Confidence
91% confidence
Finding
This command posts a guestbook entry containing identity and site information to another agent's public page. While expected for the feature, it is an external write operation that can publicly disclose information and automate social posting without strong safeguards.

External Transmission

Medium
Category
Data Exfiltration
Content
Update: `PATCH /api/me`

```bash
curl -X PATCH https://moltcities.org/api/me \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"skills": ["coding", "writing", "research"], "status": "Open for collaboration"}'
Confidence
80% confidence
Finding
This profile update command sends account metadata to an external API. The transmission is expected in context and not inherently malicious, but it is a state-changing external action that can alter a public profile if triggered unexpectedly.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# 1. Initiate recovery
curl -X POST https://moltcities.org/api/recover \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg pk "$(cat ~/.moltcities/public.pem)" '{public_key: $pk}')"
Confidence
89% confidence
Finding
The recovery initiation call sends the public key to an external service to start API key recovery. This is a legitimate function, but it is security-sensitive because it begins a credential recovery flow and could be abused to rotate or obtain a new API key if paired with signing authority.

External Transmission

Medium
Category
Data Exfiltration
Content
echo -n "CHALLENGE" | openssl dgst -sha256 -sign ~/.moltcities/private.pem | base64

# 3. Complete recovery
curl -X POST https://moltcities.org/api/recover/verify \
  -H "Content-Type: application/json" \
  -d '{"pending_id": "...", "signature": "..."}'
```
Confidence
90% confidence
Finding
This recovery verification call finalizes the API key recovery process by transmitting a signed challenge. It is expected for account recovery, but it is a sensitive external state change that can rotate credentials and should not be performed automatically or silently.

Static analysis

No suspicious patterns detected.