Back to skill

Security audit

Agents-Manager-and-IM

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real OpenClaw agent manager, but it exposes unsafe local management APIs, shell execution, deletion, persistent storage, and a hardcoded token in ways users should review carefully before installing.

Install only in a controlled local environment after removing the hardcoded token, adding authentication, binding the server to 127.0.0.1, replacing shell command construction and rm -rf with safer APIs, validating agent IDs and paths, and deciding whether browser chat/image history should be stored at all.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (7)

T09 · Insecure Skill Coding Practices

Error
Location
server.js:163
Finding
Unauthenticated Remote Shell Command Injection<![CDATA[ ## Vulnerability Details **File Location**: `server.js:163-200` and `server-gemini.js:93-115` **Vulnerability Type**: OS command injection through shell interpolation **Risk Level**: Critical ### Vulnerable Code ```javascript app.post('/api/agents/:id/chat', async (req, res) => { try { const { id } = req.params; const { message } = req.body; if (!message) { return res.status(400).json({ success: false, error: 'Message is required' }); } const agentConfigPath = path.join(CONFIG.agentsDir, id, 'config.json'); let agentConfig = null; try { agentConfig = await readJsonFile(agentConfigPath); } catch (e) {} const agentId = id.replace('agent-', ''); const workspace = agentConfig?.workspace || `workspace-${agentId}`; const workspacePath = path.join(CONFIG.workspaceDir, workspace); try { await fs.access(workspacePath); } catch (e) { return res.status(404).json({ success: false, error: `Agent workspace does not exist: ${workspacePath}` }); } const safeMessage = message.replace(/"/g, '\\"').replace(/\n/g, ' '); const { stdout } = await execCmd( `cd "${workspacePath}" && openclaw agent --agent ${agentId} --message "${safeMessage}" --json 2>&1` ); ``` The command execution helper explicitly enables a shell: ```javascript async function execCmd(cmd) { return new Promise((resolve, reject) => { exec(cmd, { shell: 'zsh' }, (error, stdout, stderr) => { if (error) reject(error); else resolve({ stdout, stderr }); }); }); } ``` ### Technical Analysis The request-controlled `message` is interpolated into a command executed by `zsh`. The attempted sanitization only escapes double quotes and replaces newline characters. It does not prevent shell expansion within double quotes, including: - Command substitution using `$(...)` - Command substitution using backticks - Parameter expansion - Other shell-specific substitutio ...[truncated 1448 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `child_process.exec()` with `execFile()` or `spawn()` using an argument array and `shell: false`: ```javascript const { execFile } = require('child_process'); execFile( 'openclaw', ['agent', '--agent', agentId, '--message', message, '--json'], { cwd: workspacePath }, callback ); ``` 2. Do not use `cd`, redirection, or other shell syntax. Use the child-process `cwd` option. 3. Validate Agent IDs with a strict allowlist such as `^agent-[a-z0-9-]+$`. 4. Add authentication and authorization to the chat endpoint. 5. Bind the service to `127.0.0.1` by default and explicitly allow only trusted CORS origins. 6. Apply request-size and execution-time limits, and run OpenClaw under a restricted operating-system account. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
server.js:232
Finding
Unauthenticated Path Traversal and Recursive Directory Deletion<![CDATA[ ## Vulnerability Details **File Location**: `server.js:232-257` and `server-gemini.js:142-162` **Vulnerability Type**: Path traversal leading to arbitrary recursive deletion **Risk Level**: High ### Vulnerable Code ```javascript app.delete('/api/agents/:id', async (req, res) => { try { const { id } = req.params; const agentDir = path.join(CONFIG.agentsDir, id); try { await fs.access(agentDir); } catch (e) { return res.status(404).json({ success: false, error: 'Agent does not exist' }); } await execCmd(`rm -rf "${agentDir}"`); const agentsConfigPath = path.join(CONFIG.workspaceDir, 'agents.json'); let allAgents = []; try { allAgents = await readJsonFile(agentsConfigPath); } catch (e) { return res.json({ success: true, message: 'Deleted' }); } allAgents = allAgents.filter(a => a.id !== id); await writeJsonFile(agentsConfigPath, allAgents); res.json({ success: true, message: `Agent "${id}" deleted` }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); ``` ### Technical Analysis The route parameter `id` is passed directly to `path.join()` without validating its syntax or checking that the resolved path remains inside `CONFIG.agentsDir`. Traversal sequences can cause the normalized path to point outside `~/.openclaw/agents`. After confirming that the target exists, the application executes `rm -rf` against the resulting path. Quoting the path does not prevent traversal because traversal has already been resolved at the filesystem path level. The operation requires no authentication or authorization. ### Attack Path 1. The attacker connects to the exposed Agent Manager API. 2. The attacker supplies an encoded traversal-bearing Agent ID to `DELETE /api/agents/:id`. Encoded path separators may be decoded into the route parameter by the framework. 3. `path.join(CONFIG.agentsDir, id)` normalizes the traver ...[truncated 820 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a strict Agent ID format: ```javascript if (!/^agent-[a-z0-9-]+$/.test(id)) { return res.status(400).json({ success: false, error: 'Invalid Agent ID' }); } ``` 2. Resolve and verify containment before any filesystem operation: ```javascript const base = path.resolve(CONFIG.agentsDir); const target = path.resolve(base, id); if (!target.startsWith(base + path.sep)) { return res.status(400).json({ success: false, error: 'Invalid path' }); } ``` 3. Use `fs.rm(target, { recursive: true, force: false })` instead of invoking `rm` through a shell. 4. Require authentication and explicit authorization for destructive actions. 5. Add confirmation, audit logging, and preferably a recoverable quarantine or soft-delete mechanism. 6. Apply equivalent validation to Agent creation and every other path derived from request data. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.js:25
Finding
Unauthenticated OpenClaw Agent Management Interface<![CDATA[ ## Vulnerability Details **File Location**: `server.js:25-273` and `server-gemini.js:21-162,338-340` **Vulnerability Type**: Missing authentication and authorization on privileged APIs **Risk Level**: High ### Vulnerable Code ```javascript const app = express(); const PORT = process.env.PORT || 3000; app.use(cors()); app.use(express.json()); app.get('/api/agents', async (req, res) => { // Enumerates registered and running Agents }); app.post('/api/agents', async (req, res) => { // Creates directories and persistent Agent configuration }); app.post('/api/agents/:id/chat', async (req, res) => { // Invokes a local OpenClaw Agent }); app.delete('/api/agents/:id', async (req, res) => { // Recursively deletes an Agent directory }); app.listen(PORT, () => { console.log(`Agent Manager is running at http://localhost:${PORT}`); }); ``` ### Technical Analysis None of the management routes verifies the caller's identity or authorization. The application enables CORS with the default permissive configuration, allowing arbitrary web origins to read API responses and issue supported cross-origin requests. Calling `app.listen(PORT)` without a host normally binds to all available interfaces, not exclusively to loopback. The console message stating `localhost` does not enforce a loopback-only binding. The APIs expose privileged local operations: - Enumeration of registered and running Agents - Creation of persistent files under `~/.openclaw` - Invocation of local OpenClaw Agents - Recursive deletion of Agent directories - Health information about the local gateway ### Attack Path 1. The attacker discovers port 3000 through local-network access, host exposure, container port publishing, or another network path. 2. The attacker calls `GET /api/agents` to enumerate Agent IDs and metadata. 3. The attacker calls `POST /api/agents` to create persistent Agent records and files. 4. The attacker invokes Agents using `POST /api/agents/:id/chat`, consumi ...[truncated 696 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require authenticated sessions or bearer tokens for every `/api` route. 2. Implement explicit authorization checks for enumeration, creation, chat, and deletion operations. 3. Bind to loopback by default: ```javascript app.listen(PORT, '127.0.0.1', callback); ``` 4. If remote use is required, place the service behind TLS and a hardened authenticated reverse proxy. 5. Replace unrestricted CORS with a strict allowlist of trusted origins and allowed methods. 6. Add CSRF protection when cookie-based authentication is used. 7. Rate-limit Agent invocation and destructive routes. 8. Record security audit logs for Agent creation, invocation, and deletion. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
server.js:18
Finding
Hardcoded OpenClaw Operator Token in Distributed Files<![CDATA[ ## Vulnerability Details **File Location**: `server.js:18-22`, `config.json:1-6`, and `README.md:42-47` **Vulnerability Type**: Hardcoded sensitive credential **Risk Level**: High ### Vulnerable Code ```javascript const CONFIG = { openclawGateway: 'http://127.0.0.1:18789', openclawToken: 'ZZitPPb3LZmDH2c_jYl9Xbub2NO1CrqntpGgF-LBEGM', agentsDir: path.join(process.env.HOME, '.openclaw/agents'), workspaceDir: path.join(process.env.HOME, '.openclaw') }; ``` The same value is present in the distributed configuration: ```json { "openclawGateway": "http://127.0.0.1:18789", "openclawToken": "ZZitPPb3LZmDH2c_jYl9Xbub2NO1CrqntpGgF-LBEGM", "port": 3000, "agentsDir": "~/.openclaw/agents" } ``` It is also presented as the configured token in `README.md`. ### Technical Analysis An operator token is embedded directly in source code, configuration, and documentation. Any user who downloads the package—or anyone with access to repository history, build artifacts, logs, or backups—can recover the value. The audited server does not currently use the token in its requests. Nevertheless, distributing a token identified as an OpenClaw operator credential is unsafe because its validity, reuse, and deployment scope cannot be controlled after publication. ### Attack Path 1. The attacker downloads or otherwise obtains the project files. 2. The attacker extracts the token from `server.js`, `config.json`, or `README.md`. 3. The attacker identifies a reachable OpenClaw gateway associated with the credential. 4. If the token remains valid or has been reused, the attacker presents it to the gateway. 5. The attacker obtains whatever operator capabilities the gateway grants to that token. ### Impact Assessment If valid, the credential may grant unauthorized operator-level access to the corresponding OpenClaw environment. The exact privileges depend on gateway configuration, but potential effects include Agent management, session access, command invocation ...[truncated 176 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed token immediately. 2. Search repository history, releases, archives, logs, and published packages for the same credential. 3. Replace committed values with obvious non-secret placeholders. 4. Load the token from a protected environment variable or secret manager: ```javascript const token = process.env.OPENCLAW_TOKEN; if (!token) throw new Error('OPENCLAW_TOKEN is required'); ``` 5. Restrict secret-file permissions and prevent secrets from being returned to browsers or logs. 6. Add automated secret scanning to commits and CI. 7. Use narrowly scoped, short-lived credentials where supported. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
index.html:287
Finding
Persistent DOM Cross-Site Scripting Through Agent Metadata<![CDATA[ ## Vulnerability Details **File Location**: `index.html:287-314` and `index.html:351-371` **Vulnerability Type**: Stored DOM-based cross-site scripting **Risk Level**: High ### Vulnerable Code ```javascript async function loadAgents() { try { const response = await fetch(API_BASE + '/agents'); const data = await response.json(); agents = data.registered || []; const listEl = document.getElementById('agentList'); let html = ''; for (let i = 0; i < agents.length; i++) { const agent = agents[i]; const key = agent.id.replace('agent-', ''); const emoji = agentEmojis[key] || '🤖'; const active = agent.id === currentAgentId ? 'active' : ''; html += '<div class="agent-item ' + active + '" onclick="selectAgent(\'' + agent.id + '\')">'; html += '<div class="agent-name">'; html += '<span class="agent-emoji">' + emoji + '</span>' + agent.name; html += '</div>'; html += '<div class="agent-desc">' + (agent.description || '') + '</div>'; html += '</div>'; } listEl.innerHTML = html; } catch (error) { document.getElementById('agentList').innerHTML = '<div style="padding:20px;color:#f44336">Load failed: ' + error.message + '</div>'; } } ``` Additional unsafe rendering occurs when an Agent is selected: ```javascript if (history.length === 0) { chatMessages.innerHTML = '<div class="empty-state">' + '<div class="empty-state-icon">' + emoji + '</div>' + '<div class="empty-state-text">Start a conversation with ' + agent.name + '</div>' + '</div>'; } ``` ### Technical Analysis The Agent creation API accepts attacker-controlled `name` and `description` values and persists them in `~/.openclaw/agents.json`. The frontend subsequently inserts those values into HTML strings assigned to `innerHTML`. The values are not HTML-escaped or sanitized. Agent IDs are also inserted into an inline `onclick` attribute, allowing attribute ...[truncated 1324 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not construct markup from Agent metadata. 2. Create elements using DOM APIs and assign untrusted values with `textContent`. 3. Replace inline `onclick` attributes with `addEventListener()` and keep the Agent ID in a closure or validated `data-*` attribute. 4. Validate Agent IDs using a strict allowlist and constrain the length and type of all metadata. 5. If HTML rendering is unavoidable, sanitize it with a maintained allowlist-based sanitizer. 6. Add a restrictive Content Security Policy that disallows inline scripts and event handlers. 7. Apply the same correction to `index.html`, the embedded frontend in `server-gemini.js`, and the frontend embedded in `server.js`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
cli.js:41
Finding
Local Shell Injection in CLI HTTP Request Construction<![CDATA[ ## Vulnerability Details **File Location**: `cli.js:41-54` and `register-existing.js:57-72` **Vulnerability Type**: Shell injection through dynamically constructed curl commands **Risk Level**: Medium ### Vulnerable Code ```javascript async function simpleFetch(endpoint, options = {}) { const { execSync } = require('child_process'); const url = API_BASE + endpoint; const method = options.method || 'GET'; let cmd = `curl -s -X ${method} "${url}"`; if (options.body) { cmd += ` -H "Content-Type: application/json" -d '${JSON.stringify(options.body)}'`; } try { const result = execSync(cmd, { encoding: 'utf-8', shell: 'zsh' }); return JSON.parse(result); } catch (error) { console.error('API call failed:', error.message); return { success: false, error: error.message }; } } ``` CLI arguments flow into the vulnerable body: ```javascript await simpleFetch('/agents', { method: 'POST', body: { name, description, model: model || 'bailian/qwen3.5-plus' } }); ``` ### Technical Analysis The application serializes request data to JSON and places it inside a single-quoted shell argument. JSON encoding does not escape single quotes for shell syntax. A user-provided single quote can terminate the argument and append shell operators or commands. `execSync()` then runs the generated string through `zsh`. Similar request construction appears in `register-existing.js`. The project already declares `node-fetch`, so invoking curl through a shell is unnecessary. ### Attack Path 1. A local user, automation process, or copied command supplies a crafted Agent name, description, Agent ID, or chat message. 2. The value includes a single quote that closes the `-d '...'` argument, followed by shell syntax. 3. `JSON.stringify()` preserves the single quote because it is not special to JSON. 4. The generated command is passed to `zsh`. 5. The shell executes the appended command with the privileges of t ...[truncated 427 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove shell-based curl invocation entirely. 2. Use Node's native `fetch`, the declared `node-fetch` package, or `http.request()`: ```javascript const response = await fetch(API_BASE + endpoint, { method: options.method || 'GET', headers: { 'Content-Type': 'application/json' }, body: options.body ? JSON.stringify(options.body) : undefined }); ``` 3. If an external process is unavoidable, use `execFile()` with a fixed executable and an argument array, never a shell command string. 4. Validate CLI Agent IDs and constrain argument lengths. 5. Apply the same remediation to both `cli.js` and `register-existing.js`. ]]>

T08 · Insecure Dependencies

Warning
Location
package-lock.json:19
Finding
Dependency Lockfile Uses a Non-Official Package Mirror<![CDATA[ ## Vulnerability Details **File Location**: `package-lock.json:19-902` **Vulnerability Type**: Expanded dependency supply-chain trust through third-party registry URLs **Risk Level**: Medium ### Vulnerable Configuration The lockfile resolves all audited dependencies through a non-official mirror. Representative entries include: ```json "node_modules/express": { "version": "4.22.1", "resolved": "https://registry.npmmirror.com/express/-/express-4.22.1.tgz" } ``` ```json "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz" } ``` ```json "node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz" } ``` ### Technical Analysis The documented `npm install` process follows the lockfile's `resolved` URLs and downloads packages from `registry.npmmirror.com` rather than the official npm registry. No malicious lifecycle script was identified in the audited lockfile, and the presence of the mirror alone does not prove package tampering. However, it expands the supply-chain trust boundary and makes installation dependent on the integrity and availability of a third-party distribution service. A compromised mirror, altered archive, or discrepancy between mirror and upstream content could introduce executable code into the application installation. ### Attack Path 1. A user follows the documented installation process and runs `npm install` or `npm ci`. 2. npm downloads dependency archives from the third-party mirror URLs recorded in the lockfile. 3. If a mirror-hosted archive is compromised and accepted during installation, the altered package becomes part of the application dependency tree. 4. The malicious code executes when imported by the server or, where applicable, during package lifecycle processing. 5. It inherits the filesystem and network privileges of the application or installation account. ### Impact Assessm ...[truncated 341 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Regenerate the lockfile using the official npm registry: ```bash npm config set registry https://registry.npmjs.org/ rm -rf node_modules package-lock.json npm install ``` 2. Review the regenerated dependency versions and integrity hashes before committing them. 3. Use `npm ci` in controlled builds to enforce lockfile consistency. 4. Run dependency vulnerability and provenance checks in CI. 5. Pin critical dependencies where appropriate and review lockfile changes. 6. If a mirror is operationally required, document the trust decision and use an internally controlled, authenticated, and monitored package proxy. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (51)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes child_process shell execution, rm -rf deletion, filesystem access to agent registries, local port probing, and a hardcoded OpenClaw token that is not disclosed in the description. Hardcoded credentials combined with privileged local operations materially increase the risk of unauthorized access, command misuse, and irreversible modification or deletion of local agent data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes child_process shell execution, rm -rf deletion, filesystem access to agent registries, local port probing, and a hardcoded OpenClaw token that is not disclosed in the description. Hardcoded credentials combined with privileged local operations materially increase the risk of unauthorized access, command misuse, and irreversible modification or deletion of local agent data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes child_process shell execution, rm -rf deletion, filesystem access to agent registries, local port probing, and a hardcoded OpenClaw token that is not disclosed in the description. Hardcoded credentials combined with privileged local operations materially increase the risk of unauthorized access, command misuse, and irreversible modification or deletion of local agent data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes child_process shell execution, rm -rf deletion, filesystem access to agent registries, local port probing, and a hardcoded OpenClaw token that is not disclosed in the description. Hardcoded credentials combined with privileged local operations materially increase the risk of unauthorized access, command misuse, and irreversible modification or deletion of local agent data.

Known Vulnerable Dependency: path-to-regexp==0.1.12 — 1 advisory(ies): CVE-2024-45296 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple r)

High
Category
Supply Chain
Confidence
99% confidence
Finding
path-to-regexp 0.1.12 is a transitive dependency of Express routing and is associated with a Regular Expression Denial of Service issue. In a network-facing multi-agent management platform, attacker-controlled request paths can hit route matching logic repeatedly, potentially causing excessive CPU consumption and service degradation or outage.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
The server exposes host-side shell execution through exec(), and that capability is later used on request-driven data in the chat flow. Even though the message escapes double quotes and newlines, invoking a shell for normal application logic greatly increases the attack surface and creates command-injection and privilege-boundary risk if any parameter handling is bypassed or extended later.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The delete endpoint performs filesystem deletion by invoking rm -rf through a shell, giving a web request destructive host-level power. If path handling or identifier validation is ever weakened, this can become arbitrary file deletion; even as written, it is an unnecessarily dangerous primitive for a web-facing management UI.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
});

/**
 * DELETE /api/agents/:id - 删除 Agent
 */
app.delete('/api/agents/:id', async (req, res) => {
  try {
Confidence
95% confidence
Finding
The DELETE endpoint accepts an untrusted path parameter and ultimately feeds the derived path into a shell command: `rm -rf "${agentDir}"`. Because `path.join` does not prevent traversal and quoted shell strings still permit command substitution such as `$(...)`, an attacker can supply a crafted `id` to delete arbitrary directories or potentially achieve command execution. In the context of an agent-management platform handling local workspaces, this is especially dangerous because it operates on sensitive directories under the user's home directory.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation explicitly shows how to extract an Operator Token from a local file, but does not warn that this token is a sensitive credential or instruct users on secure handling. In the context of an agent management platform that centralizes access to multiple agents, disclosure or careless reuse of this token could allow unauthorized control of the OpenClaw gateway and downstream agent actions.

Session Persistence

Medium
Category
Rogue Agent
Content
node cli.js list

# 创建新 Agent
node cli.js create Judy "营销外展专家" bailian/qwen3.5-plus

# 与 Agent 对话
node cli.js chat agent-judy
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This is a markdown file, so SQP-2 applies to missing user-facing warnings about behaviors that can affect user data or system integrity. The guide shows both CLI deletion and later API deletion usage, but does not disclose whether deleting an Agent also removes its directory, configuration, or registration data, which could surprise users.

External Transmission

Medium
Category
Data Exfiltration
Content
### 获取 Agent 列表
```bash
curl http://localhost:3000/api/agents
```

### 创建 Agent
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
90% confidence
Finding
The markdown includes a DELETE request for removing an Agent, which is a destructive operation affecting managed resources. There is no adjacent warning about consequences to user data, persistence, or reversibility, so users are not clearly informed before using the endpoint.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
For markdown files, SQP-2 covers omitted warnings about privacy-sensitive behaviors. The guide instructs users to place an operator token in config.json but does not warn them to keep the token secret, avoid committing it, or protect file permissions, which is important for credential safety.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The markdown file lists '删除/停用 Agent' as a feature, which includes a destructive action affecting user-managed agent data or configuration. There is no accompanying warning, confirmation note, or explanation of permanence anywhere in the README, so users are not alerted to the impact on their data or system state.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The DELETE `/api/agents/:id` endpoint is presented as a normal API action with no warning about what is removed, whether related workspace/pairing state is also deleted, or whether the action can be undone. For markdown files, omission of warnings about behaviors affecting user data or system integrity should be flagged.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The README includes a real-looking bearer token in plaintext configuration instructions, which creates a strong risk of credential leakage and accidental reuse. If the token is valid or copied by users into real deployments, an attacker could access the OpenClaw gateway or associated agent-management functions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises and appears to rely on capabilities such as shell, network, and environment access, but the manifest does not declare any tool scope or permissions. This creates a transparency and least-privilege problem: users and platforms cannot accurately assess or constrain what the skill may do before execution.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill states that chat history is auto-saved and data is stored locally in the browser, but it does not clearly warn that conversation contents and uploaded images may persist on the device. This can expose sensitive user data to other local users, browser compromise, or accidental retention beyond the user's expectations.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
Nearly all help text, prompts, and status messages are hard-coded in Chinese, which imposes a specific language on users without opt-in. This is a natural-language policy concern because the tool does not provide any language selection or justification for the locale restriction.

External Transmission

Medium
Category
Data Exfiltration
Content
const method = options.method || 'GET';
  const body = options.body ? JSON.stringify(options.body) : null;
  
  let cmd = `curl -s -X ${method} "${url}"`;
  if (body) {
    cmd += ` -H "Content-Type: application/json" -d '${body}'`;
  }
Confidence
95% confidence
Finding
The code builds a shell command string containing JSON body data and executes it with execSync. Because the JSON is wrapped in single quotes for the shell, attacker-controlled input containing a single quote can break out of the quoted argument and inject arbitrary shell commands, leading to local command execution when creating agents or sending chat messages.

External Transmission

Medium
Category
Data Exfiltration
Content
const url = API_BASE + endpoint;
  const method = options.method || 'GET';
  
  let cmd = `curl -s -X ${method} "${url}"`;
  if (options.body) {
    cmd += ` -H "Content-Type: application/json" -d '${JSON.stringify(options.body)}'`;
  }
Confidence
96% confidence
Finding
This second helper repeats the same unsafe pattern: it interpolates untrusted request body data into a shell command and runs it under zsh. In this CLI, user-supplied fields such as agent name, description, model, and chat message can be crafted to terminate the quoted -d payload and execute arbitrary commands on the host.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The delete command issues a DELETE request and removes an agent after only checking that an ID was provided. While it logs that deletion is happening, there is no confirmation prompt or warning to the user before the irreversible action executes.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
User chat content is sent over plain HTTP to localhost, which means message contents are unencrypted in transit. While localhost reduces remote interception risk, the skill context manages potentially sensitive multi-agent conversations, so local malware, hostile local proxies, container boundary crossings, or port forwarding could expose confidential prompts and responses.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The application persists chat history, including user messages and embedded image data URLs, in localStorage without any notice, consent, retention control, or sensitivity warning. In a multi-agent chat manager, users may share prompts, internal data, or screenshots, and localStorage is long-lived and readable by any script running in the same origin, increasing privacy and data exposure risk.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.install_untrusted_source

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
cli.js:13

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
register-existing.js:51

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
server-gemini.js:27

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
server.js:31

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
server-gemini.js:14

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
server.js:15

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
config.json:2