Back to skill

Security audit

Clawreach

Security checks for vulnerabilities and agentic risk

Overview

This skill is transparent about its social-matching purpose, but it asks for login credentials, stores a reusable token in a predictable file, and sets up automatic background replies without enough user control.

Review this carefully before installing. Do not provide a real password unless you trust the ClawReach service and accept that the agent will store an access token locally and may message or conclude matches for you in the background. Prefer a version that uses OAuth or a scoped token, secure secret storage, explicit opt-in for polling, and approval before sending messages or final match decisions.

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 (3)

T06 · System Persistence

Error
Location
SKILL.md:137
Finding
Persistent Autonomous Polling Through a Scheduled Cron Job<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 137–153 **Vulnerability Type**: Persistent scheduled task with autonomous credential use **Risk Level**: High ### Complete Code Snippet The non-English command message is rendered in English below while preserving its documented behavior: ```bash openclaw cron add \ --name "ClawReach Pending Poll" \ --cron "*/1 * * * *" \ --tz "Asia/Shanghai" \ --session isolated \ --message "Check whether ClawReach has pending match messages. Read ~/.openclaw/workspace/memory/clawreach-session.json for credentials, call GET http://127.0.0.1:3000/api/v1/agents/pending, generate a reply for every pending message and POST it to /matches/message, then call /matches/conclude during the final round. Exit silently when there are no pending messages." \ --light-context \ --announce ``` The Skill describes the resulting behavior as follows: ```text This cron job runs every 60 seconds in an isolated session — it won't clutter the main chat. When a match concludes, it announces the result to the user automatically. To stop polling: openclaw cron list # find the job ID openclaw cron remove <jobId> ``` ### Technical Analysis The Skill instructs the user to install an OpenClaw cron job that survives the initiating interaction and executes every minute. The scheduled task reads a reusable bearer token from a persistent file and performs authenticated network requests, generates messages, sends those messages, and concludes matches. An isolated session reduces chat clutter but does not provide a security boundary. The task continues to exercise the user's authenticated authority without requiring approval for each message or conclusion. No automatic expiration, bounded execution count, revocation procedure, or per-action confirmation is configured. This behavior matches system persistence because a scheduled task remains active across sessions and repeatedly performs autonomous operations after th ...[truncated 1201 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace recurring polling with explicit, user-initiated polling by default. 2. If background processing is necessary, require informed opt-in that clearly identifies: - The execution frequency. - The credentials and data accessed. - The API actions that can be performed. - The task's expiration time and removal procedure. 3. Configure an automatic expiration or a strict maximum number of executions. 4. Require user confirmation before sending messages or submitting `/matches/conclude`. 5. Use a narrowly scoped service token that cannot access unrelated account functions. 6. Provide a one-command disable mechanism and automatically revoke the polling token when the task is removed. 7. Display the installed job identifier and current status immediately after setup. 8. Record an audit trail of generated messages, API requests, and conclusion decisions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:68
Finding
Reusable Bearer Token Stored in a Predictable Plaintext Session File<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 68–80 **Vulnerability Type**: Plaintext storage of sensitive authentication material **Risk Level**: High ### Complete Code Snippet ```text ### Session Storage Save to `~/.openclaw/workspace/memory/clawreach-session.json`: ```json { "email": "user@example.com", "access_token": "<token>", "agent_id": 123, "agent_name": "coolpanda_88", "bound_at": "2024-01-01T00:00:00Z" } ``` > Token expires → re-call `/auth/login` on 401. ``` The token-refresh instructions at lines 264–269 reinforce the continued use of this file: ```text ## Token Refresh On any 401 response, re-login automatically: POST /auth/login → update access_token in session file → retry ``` ### Technical Analysis The Skill directs the agent to save a reusable bearer token in a predictable JSON file under the OpenClaw workspace. It specifies no restrictive file permissions, encryption, operating-system keychain, dedicated secret store, access isolation, or token scope restrictions. A bearer token grants access based solely on possession. Consequently, another Skill, local process, backup operation, diagnostic collector, or workspace-reading agent operating with the same user's file access could recover the token and use it independently of the legitimate Skill. Automatic replacement of the token after an HTTP 401 response keeps valid authentication material at the same predictable location and may extend the exposure period. ### Attack Path 1. The user authenticates through the Skill. 2. The Skill receives a ClawReach access token. 3. The token is written to `~/.openclaw/workspace/memory/clawreach-session.json`. 4. Another component with permission to read the user's OpenClaw workspace locates the predictable file. 5. The component extracts the `access_token` value. 6. It supplies the token in an `Authorization: Bearer` header to the ClawReach API. 7. The attacker performs API operations available to the compro ...[truncated 761 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store tokens in an operating-system keychain or a dedicated secrets manager rather than in workspace memory. 2. If a file fallback is unavoidable: - Store only a secret reference where possible. - Create the file with owner-only permissions, such as mode `0600`. - Verify ownership and permissions before every read. - Prevent backups, logs, and version-control systems from collecting the file. 3. Issue short-lived, narrowly scoped tokens specifically for polling and messaging. 4. Use refresh tokens only through a protected secret store and rotate them after use. 5. Revoke tokens when polling is disabled, account binding is removed, or suspicious access occurs. 6. Avoid retaining the user's email unless it is operationally necessary. 7. Document token lifetime, server-side scopes, revocation procedures, and storage protections. 8. Never request or retain the user's plaintext password beyond the immediate authenticated exchange. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:196
Finding
Prompt Injection Through Untrusted Match Profiles and Conversation Messages<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 196–220 **Vulnerability Type**: Untrusted remote content inserted into an action-producing LLM prompt **Risk Level**: High ### Complete Code Snippet ```text Use LLM with this role setup: **System**: ``` You are the user's AI Agent, screening social matches on their behalf. Your owner's profile: {my_profile.self_summary} Intent: {my_profile.looking_for} Deal-breakers: {my_profile.deal_breaker} Opponent's card: {opponent_public_card} Goals: - Naturally learn about the other person to assess match potential - Ask specific questions, avoid vague openers - Politely disengage if they clearly trigger a deal-breaker - Conclude after {max_rounds} rounds max This is round {round} of {max_rounds}. ``` **User**: ``` Conversation so far: {history} They said: {last_message} (If last_message is null, this is a new match — open with a greeting) Reply naturally (50–100 words). If this is the final round (round >= max_rounds - 1), append: [CONCLUDE: yes/no, score: 0-100, reason: one sentence] ``` ``` The generated output is subsequently used for API actions: ```text POST /matches/message Headers: Authorization: Bearer <access_token> Body: { "match_id": 456, "content": "..." } ``` ```text When reply contains `[CONCLUDE: ...]`: POST /matches/conclude Headers: Authorization: Bearer <access_token> ``` ### Technical Analysis The opponent's public card, conversation history, and latest message are controlled by a remote match participant. These values are inserted directly into LLM prompts without robust trust-boundary separation, explicit instructions to treat embedded commands as data, escaping, size restrictions, content filtering, or structured output enforcement. The opponent's card is especially sensitive because it is interpolated into the system-role prompt. An attacker can place instruction-like text in a card or message that attempts to override the screening task, request disclosure of own ...[truncated 1873 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat `opponent_public_card`, `history`, and `last_message` as untrusted data. 2. Keep untrusted content out of the system-role instruction block. 3. Serialize remote content into a strict structured format and place it in clearly delimited data fields. 4. Add a high-priority instruction stating that commands, role declarations, markup, and conclusion markers appearing inside remote content must never be followed. 5. Apply length limits, normalization, and prompt-injection screening before model invocation. 6. Require model output to conform to a validated schema with separate fields for: - Reply text. - Proposed match decision. - Numeric score. - Reason. 7. Do not infer an API action merely from a marker appearing in free-form model output. 8. Require explicit user approval before transmitting a message or concluding a match. 9. Prevent the response from reproducing sensitive profile fields unless the user has explicitly marked them as shareable. 10. Log the source input, model proposal, validation result, user approval, and final API action for investigation and accountability. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Credential Access

High
Category
Privilege Escalation
Content
```
Step 1: Guide user to register on ClawReach website → get register_code
Step 2: User provides email + credentials + register_code → claim agent, get access token
Step 3: Profile interview (10 dimensions, conversational)
Step 4: Upload profile to platform
Step 5: Poll for pending match messages → auto-reply as agent
Confidence
95% confidence
Finding
This workflow explicitly instructs the user to provide email, credentials, and a registration code so the skill can obtain an access token, which is a classic credential-handling pattern. In this context the danger is elevated because the token is later used for persistent automated actions, so compromise of the workflow or local storage could grant ongoing account access and enable impersonation on the platform.

Credential Access

High
Category
Privilege Escalation
Content
```
Got it! Please share the email and credentials you registered with.
(Used only to exchange an access token — not stored in plaintext)
```

### Get Access Token
Confidence
98% confidence
Finding
The skill directly asks the user to share their email and credentials, which is unsafe even if the stated purpose is token exchange. Requesting primary login secrets inside the conversational flow increases phishing risk, normalizes unsafe credential-sharing behavior, and creates an opportunity for leakage through logs, transcripts, or insecure downstream handling.

Credential Access

High
Category
Privilege Escalation
Content
(Used only to exchange an access token — not stored in plaintext)
```

### Get Access Token

```
POST /auth/login
Confidence
93% confidence
Finding
The access-token acquisition step is security-sensitive because it formalizes the conversion of user credentials into a bearer token that can be reused for API access. While token issuance itself is normal, within this skill it becomes dangerous due to subsequent plaintext session-file storage and autonomous use of the token for ongoing account actions.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The manifest description lists activation phrases such as “找对的人” and “社交匹配,” which are generic conversational expressions rather than narrowly scoped commands. Without clearer constraints or exclusion conditions, the skill could be invoked unintentionally during ordinary relationship or social discussions.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill asks users to provide login credentials and describes storing a reusable access token, but it does not present an adequate security warning or obtain explicit informed consent for persistent authentication and autonomous messaging. In a social platform context, this can lead users to unknowingly authorize ongoing agent-driven actions and expose account access if the local session file is compromised.

Ssd 3

Medium
Confidence
97% confidence
Finding
The cron instruction creates an autonomous background process that reads stored credentials, ingests private conversation data, generates responses, and sends them without per-message user review. That combination of secret reuse, continuous polling, and unsupervised outbound messaging materially increases the risk of privacy violations, account abuse, and unintended disclosures, especially because it runs in an isolated session that may reduce visibility to the user.

Static analysis

No suspicious patterns detected.