Back to skill

Security audit

Agents-Manager-and-IM

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it claims, but it exposes powerful local OpenClaw agent controls with weak boundaries and unsafe command handling.

Install only in a trusted local environment after reviewing the code. Do not expose the server to a network, rotate any real token resembling the README value, avoid pasting secrets into config or logs, and treat create/chat/delete endpoints as privileged admin actions until authentication, input validation, safe process spawning, deletion safeguards, and HTML escaping are fixed.

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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server-gemini.js:21
Finding
Unauthenticated Privileged Agent Management API<![CDATA[ ## Vulnerability Details **File Location**: `server-gemini.js:21-23, 45-163, 338-340`; equivalent endpoints in `server.js:25-26, 50-297, 1239-1242` **Vulnerability Type**: Missing authentication and authorization, unrestricted CORS, and network-accessible privileged API **Risk Level**: High ### Vulnerable Code ```javascript app.use(cors()); app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ extended: true, limit: '50mb' })); app.get('/api/agents', async (req, res) => { // Returns registered agents without authentication. }); app.post('/api/agents', async (req, res) => { // Creates persistent agents without authentication. }); app.post('/api/agents/:id/chat', async (req, res) => { // Invokes an OpenClaw agent without authentication. }); app.delete('/api/agents/:id', async (req, res) => { // Deletes an agent without authentication. }); app.listen(PORT, () => { console.log(`🚀 Agent Manager 运行在 http://localhost:${PORT}`); }); ``` ### Technical Analysis The application defines no authentication or authorization middleware for any management endpoint. Consequently, listing, creating, invoking, and deleting agents require no credentials. Calling `app.listen(PORT)` without specifying a host normally binds the Express service to all available interfaces, not exclusively to loopback. In addition, `cors()` with no restrictive configuration permits cross-origin browser requests from arbitrary origins. The affected operations modify files under `~/.openclaw`, invoke the local `openclaw` command, and delete agent directories. These are privileged management actions that should not be exposed as anonymous HTTP operations. ### Attack Path 1. An attacker identifies a host exposing TCP port 3000 or convinces a user to visit an attacker-controlled web page while the service is running. 2. The attacker sends `GET /api/agents` to enumerate registered agents. 3. The attacker sends an unauthenticated `POST /api/agents` request to c ...[truncated 732 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require authentication for every `/api` endpoint. 2. Apply operation-specific authorization so read, chat, create, and delete permissions are separately scoped. 3. Bind explicitly to loopback unless remote access is intentionally required: ```javascript app.listen(PORT, '127.0.0.1', () => { console.log(`Agent Manager listening on http://127.0.0.1:${PORT}`); }); ``` 4. Restrict CORS to an explicit allowlist: ```javascript app.use(cors({ origin: ['http://127.0.0.1:3000'], methods: ['GET', 'POST', 'DELETE'], credentials: true })); ``` 5. Add CSRF protection if cookie-based authentication is used. 6. Add rate limiting, request logging, and audit records for destructive operations. 7. Require confirmation or re-authentication before deletion. 8. Do not return internal filesystem paths or unnecessary agent metadata in error responses. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
server-gemini.js:24
Finding
Remote Shell Command Injection Through Chat Requests<![CDATA[ ## Vulnerability Details **File Location**: `server-gemini.js:24-31, 101-124`; equivalent implementation in `server.js:28-34, 167-204` **Vulnerability Type**: OS command injection through shell interpolation **Risk Level**: Critical ### Vulnerable Code ```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 }); }); }); } app.post('/api/agents/:id/chat', async (req, res) => { try { const { id } = req.params; const { message, imageData } = req.body; const agentId = id.replace('agent-', ''); const workspace = `workspace-${agentId}`; const workspacePath = path.join(CONFIG.workspaceDir, workspace); let taskMessage = message || '请分析这张图片'; if (imageData) { taskMessage = `${message || ''} [图片已上传]`.trim(); } const safeMessage = taskMessage.replace(/"/g, '\\"').replace(/\n/g, ' '); const { stdout } = await execCmd( `cd "${workspacePath}" && openclaw agent --agent ${agentId} --message "${safeMessage}" --json 2>&1` ); // Response handling omitted. } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); ``` ### Technical Analysis The endpoint interpolates attacker-controlled values into a command executed by `zsh`. Replacing double quotes and newlines is not sufficient shell escaping. The message remains inside double quotes, where shell command substitutions such as `$(command)` and backtick substitution are still evaluated. The `agentId` value is inserted without any shell quoting at all. The workspace path is also derived from that identifier before being embedded in the shell command. Because the endpoint is unauthenticated, this coding flaw is remotely reachable whenever the HTTP service is reachable. ### Attack Path 1. The attacker identifies an existing agent and workspace through ...[truncated 1022 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not use `exec()` for this operation. 2. Invoke OpenClaw with `execFile()` or `spawn()` and a fixed argument array: ```javascript const { execFile } = require('child_process'); function invokeAgent(agentId, message, workspacePath) { return new Promise((resolve, reject) => { execFile( 'openclaw', ['agent', '--agent', agentId, '--message', message, '--json'], { cwd: workspacePath, shell: false, maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => { if (error) return reject(error); resolve({ stdout, stderr }); } ); }); } ``` 3. Validate agent IDs against a strict allowlist pattern, such as `^[a-z0-9-]+$`. 4. Resolve the selected agent from a trusted server-side registry rather than deriving paths directly from route input. 5. Apply authentication and authorization before invoking any agent. 6. Run the server and OpenClaw process under a dedicated least-privileged operating-system account. 7. Add execution timeouts, output limits, and request rate limits. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server-gemini.js:143
Finding
Path Traversal and Unsafe Recursive Agent Deletion<![CDATA[ ## Vulnerability Details **File Location**: `server-gemini.js:143-151`; equivalent implementation in `server.js:265-279` **Vulnerability Type**: Unvalidated path construction combined with shell-based recursive deletion **Risk Level**: Critical ### 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 不存在' }); } 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: '已删除' }); } allAgents = allAgents.filter(a => a.id !== id); await writeJsonFile(agentsConfigPath, allAgents); res.json({ success: true, message: `Agent "${id}" 已删除` }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); ``` ### Technical Analysis The route parameter is joined directly to the trusted agents directory. The code does not: - Restrict the identifier to a safe character set. - Canonicalize the resulting path and verify that it remains below `CONFIG.agentsDir`. - Confirm that the target is a registered agent directory. - Reject symbolic links or traversal components. - Use a filesystem API for deletion. The path is subsequently interpolated into `rm -rf` and executed by a shell. The use of double quotes mitigates some metacharacters but does not prevent command substitution, and recursive shell deletion significantly increases the consequence of validation errors. ### Attack Path 1. The attacker calls the unauthenticated deletion endpoint with a crafted or encoded route identifier. 2. `path.join()` normalizes the input without enforcing containm ...[truncated 842 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate identifiers before using them: ```javascript if (!/^agent-[a-z0-9-]+$/.test(id)) { return res.status(400).json({ success: false, error: 'Invalid agent ID' }); } ``` 2. Resolve and enforce path containment: ```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 agent path' }); } ``` 3. Confirm that the identifier exists in the trusted agent registry. 4. Reject or safely handle symbolic-link targets. 5. Replace shell deletion with the native filesystem API: ```javascript await fs.rm(target, { recursive: true, force: false }); ``` 6. Require authenticated administrative authorization and explicit confirmation for deletion. 7. Consider moving deleted agents to a quarantine or trash directory before permanent removal. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
index.html:287
Finding
Persistent Cross-Site Scripting Through Agent Metadata<![CDATA[ ## Vulnerability Details **File Location**: `index.html:287-314, 338-378`; equivalent rendering in `server-gemini.js:321-323` and the embedded UI in `server.js` **Vulnerability Type**: Stored cross-site scripting caused by unescaped `innerHTML` construction **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) { // Error handling omitted. } } ``` The empty-state view also inserts an agent name without escaping: ```javascript chatMessages.innerHTML = '<div class="empty-state">' + '<div class="empty-state-icon">' + emoji + '</div>' + '<div class="empty-state-text">开始与 ' + agent.name + ' 对话</div>' + '</div>'; ``` ### Technical Analysis Agent names, descriptions, and IDs originate from the agent creation API and are persisted in `~/.openclaw/agents.json`. These values are later concatenated into HTML and assigned to `innerHTML`. Unlike message bodies, which are passed through `escapeHtml()`, agent metadata is rendered without encoding. The identifier is additionally embedded into an inline JavaScript event handler. An attacker can therefore store ma ...[truncated 1237 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not concatenate untrusted values into HTML. 2. Construct elements using DOM APIs and assign untrusted data through `textContent`: ```javascript const item = document.createElement('div'); item.className = `agent-item ${active}`; item.addEventListener('click', () => selectAgent(agent.id)); const name = document.createElement('div'); name.className = 'agent-name'; name.textContent = `${emoji} ${agent.name}`; const description = document.createElement('div'); description.className = 'agent-desc'; description.textContent = agent.description || ''; item.append(name, description); listEl.appendChild(item); ``` 3. Remove inline event handlers such as `onclick`. 4. Validate and length-limit names, descriptions, IDs, and models on the server. 5. Escape all untrusted values if HTML templates must be used. 6. Deploy a restrictive Content Security Policy that disallows inline scripts and event handlers. 7. Review and sanitize already persisted records before rendering them. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
cli.js:18
Finding
Local Shell Command Injection in CLI HTTP Helpers<![CDATA[ ## Vulnerability Details **File Location**: `cli.js:18-37, 41-58, 84-154` **Vulnerability Type**: Shell command injection through JSON data and endpoint interpolation **Risk Level**: High ### 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 调用失败:', error.message); return { success: false, error: error.message }; } } ``` User input reaches this helper directly: ```javascript async create(name, description, model) { const data = await simpleFetch('/agents', { method: 'POST', body: { name, description, model: model || 'bailian/qwen3.5-plus' } }); } async chat(agentId) { rl.question('你:', async (message) => { const data = await simpleFetch(`/agents/${agentId}/chat`, { method: 'POST', body: { message } }); }); } ``` ### Technical Analysis The helper serializes user-controlled input to JSON and places it inside a single-quoted shell argument. JSON encoding does not escape characters for a POSIX shell. A single quote in an agent name, description, model, or chat message terminates the shell string and allows additional shell syntax to be interpreted. The endpoint also contains an attacker-controlled agent ID and is interpolated into a shell command. Although it is placed inside double quotes, command substitution remains possible inside double-quoted shell strings. ### Attack Path 1. A user runs a CLI command using malicious or attacker-supplied input, or pastes a crafted chat message. 2. The input reaches `JSON.stringify(options.body)` or th ...[truncated 609 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove shell-based curl construction entirely. 2. Use the installed `node-fetch` package or the runtime's native `fetch()` implementation: ```javascript async function simpleFetch(endpoint, options = {}) { const response = await fetch(API_BASE + endpoint, { method: options.method || 'GET', headers: options.body ? { 'Content-Type': 'application/json' } : {}, body: options.body ? JSON.stringify(options.body) : undefined }); return response.json(); } ``` 3. Validate agent IDs with a strict allowlist before appending them to URLs. 4. Encode route components with `encodeURIComponent()`. 5. If an external binary is unavoidable, use `spawnSync()` with a fixed argument array and `shell: false`. 6. Add input length limits and reject control characters. 7. Apply the same fix to the similar helper in `register-existing.js:56-71`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
README.md:37
Finding
Operator Token-Like Credential Disclosed in Documentation<![CDATA[ ## Vulnerability Details **File Location**: `README.md:37-48` **Vulnerability Type**: Hardcoded secret or sensitive credential disclosure **Risk Level**: High ### Vulnerable Code ```markdown ## 配置 编辑 `config.json`: ```json { "openclawGateway": "http://127.0.0.1:18789", "openclawToken": "ZZitPPb3LZmDH2c_jYl9Xbub2NO1CrqntpGgF-LBEGM", "port": 3000 } ``` ``` Related documentation instructs users to retrieve an operator token: ```bash cat ~/.openclaw/devices/paired.json | jq '.[].tokens.operator.token' ``` This instruction appears in `SKILL.md:65-67` and `CLAWHUB.md:77-81`. ### Technical Analysis The README contains a distinct token-shaped value rather than the explicit placeholder used in `config.json`. It must therefore be treated as a potentially valid or formerly valid operator credential. Operator tokens are sensitive because they may authorize management actions against an OpenClaw gateway. Publishing such a value in a distributed package exposes it to every package recipient and to any repository or artifact indexing system. The reviewed servers do not load `config.json`, making the instructions to collect and place an operator token there unnecessary for the implemented behavior. This increases credential exposure without providing a corresponding functional benefit. ### Attack Path 1. An attacker obtains the distributed project, repository history, cached artifact, or generated documentation. 2. The attacker extracts the token-shaped value from `README.md`. 3. The attacker identifies the associated OpenClaw gateway through local access, configuration disclosure, or network discovery. 4. If the credential remains valid and is accepted by the gateway, the attacker authenticates with operator-level permissions. 5. The attacker performs actions permitted to that operator token. ### Impact Assessment If valid, the disclosed value may provide operator-level access to the associated OpenClaw environment. The precise impact depends on g ...[truncated 323 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the disclosed token-shaped value. 2. Replace it with an unmistakable placeholder: ```json { "openclawGateway": "http://127.0.0.1:18789", "openclawToken": "${OPENCLAW_TOKEN}", "port": 3000 } ``` 3. Remove the value from version-control history and previously published artifacts where feasible. 4. Store operational credentials in environment variables or a dedicated secret manager. 5. Ensure secret files are excluded through `.gitignore` and package publication controls. 6. Add automated secret scanning to CI and release processes. 7. Remove token-retrieval instructions unless the application actually requires that token. 8. If gateway authentication is implemented, document least-privileged token scopes rather than requesting a general operator token. ]]>

T08 · Insecure Dependencies

Warning
Location
package-lock.json:19
Finding
Dependencies Locked to a Third-Party Package Registry Mirror<![CDATA[ ## Vulnerability Details **File Location**: `package-lock.json:19-887` **Vulnerability Type**: Third-party dependency supply-chain exposure **Risk Level**: Medium ### Vulnerable Code Representative lockfile entries include: ```json { "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz" }, "node_modules/express": { "version": "4.22.1", "resolved": "https://registry.npmmirror.com/express/-/express-4.22.1.tgz" }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz" } } ``` The installation instructions require: ```bash npm install ``` ### Technical Analysis The lockfile resolves numerous dependencies from `registry.npmmirror.com` rather than the canonical npm registry. This introduces an additional supply-chain trust boundary: users must trust both the upstream package publisher and the mirror's infrastructure, synchronization process, and artifact integrity. The lockfile contains integrity metadata, which provides some protection when correctly verified by npm, but using an unnecessary third-party source still increases availability and provenance risk. No evidence in the reviewed files establishes that the mirror itself is malicious. The issue is the avoidable use of a noncanonical dependency source for executable application dependencies. ### Attack Path 1. A user follows the documented installation procedure. 2. The package manager reads the committed lockfile. 3. Dependency archives are requested from the third-party mirror. 4. If the mirror, DNS path, account, or synchronization process is compromised—and integrity validation is bypassed, incorrectly updated, or paired with a modified lockfile—altered dependency code may be installed. 5. The malicious dependency executes during application loading or through package lifecycle behavior. ### Impact Assessment A com ...[truncated 316 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Configure npm to use the canonical registry: ```bash npm config set registry https://registry.npmjs.org/ ``` 2. Regenerate the lockfile from a clean environment against the canonical registry. 3. Review the resulting dependency and integrity changes before committing them. 4. Use `npm ci` in deployment and CI to enforce the reviewed lockfile. 5. Retain and verify package integrity hashes. 6. Pin reviewed dependency versions where operationally appropriate. 7. Run dependency vulnerability and provenance checks during every release. 8. Disable unnecessary lifecycle scripts during high-assurance installation where compatible: ```bash npm ci --ignore-scripts ``` ]]>
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 (53)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The finding combines several risky hidden behaviors: local file creation/deletion, shell and OpenClaw CLI execution, gateway/port probing, and misleading claims about image-upload functionality. A skill that looks like a local chat UI but also probes services and manipulates host resources creates a substantial risk of unauthorized system interaction and user deception.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The finding combines several risky hidden behaviors: local file creation/deletion, shell and OpenClaw CLI execution, gateway/port probing, and misleading claims about image-upload functionality. A skill that looks like a local chat UI but also probes services and manipulates host resources creates a substantial risk of unauthorized system interaction and user deception.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The finding combines several risky hidden behaviors: local file creation/deletion, shell and OpenClaw CLI execution, gateway/port probing, and misleading claims about image-upload functionality. A skill that looks like a local chat UI but also probes services and manipulates host resources creates a substantial risk of unauthorized system interaction and user deception.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The finding combines several risky hidden behaviors: local file creation/deletion, shell and OpenClaw CLI execution, gateway/port probing, and misleading claims about image-upload functionality. A skill that looks like a local chat UI but also probes services and manipulates host resources creates a substantial risk of unauthorized system interaction and user deception.

Ae1

High
Category
analysis-evasion
Content
在 `server-gemini.js` 中,使用参数化命令:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

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
97% confidence
Finding
path-to-regexp 0.1.12 is a transitive dependency of Express and is associated with a Regular Expression Denial of Service issue. In an internet-facing multi-agent chat platform, attacker-controlled request paths can potentially trigger expensive regex evaluation, causing request handling slowdown or service unavailability.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The server exposes OS shell execution through a helper that is later used in chat and deletion flows, even though this skill is described as a conversation-management UI. In this context, invoking shell commands with user-influenced data materially expands attack surface and can lead to command injection or unsafe execution of local system operations.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
The server wraps child_process.exec in a generic helper and later uses it with user-influenced values such as agent IDs, workspace paths, and chat messages. Although some quoting is attempted, the design still routes HTTP input into a shell command, which is a dangerous command-injection pattern and increases exposure to shell metacharacter, quoting, and path-manipulation bugs.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
});

/**
 * DELETE /api/agents/:id - 删除 Agent
 */
app.delete('/api/agents/:id', async (req, res) => {
  try {
Confidence
96% confidence
Finding
The delete-agent endpoint accepts a user-controlled :id and performs a destructive filesystem operation via a shell command: rm -rf on a path derived from that input. Because there is no authentication and no strict validation/canonicalization of the ID, an attacker who can reach the API may delete arbitrary agent data and potentially abuse path traversal semantics to target unintended directories.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The guide markets browser local storage as 'safe and private' while also stating that chat history is automatically saved and images are supported, without warning that browser persistence can retain sensitive conversations and uploaded data on disk. On shared devices, compromised browsers, synced profiles, or systems with local malware, this can expose private content users may reasonably believe is protected.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation instructs users to extract an Operator Token directly from a local credential store and place it into a config file, but it gives no warning that this token is sensitive, high-privilege authentication material. That increases the chance of accidental disclosure through shell history, screenshots, copied config files, source control, or insecure file permissions, which could let an attacker control or impersonate the user's OpenClaw environment.

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
95% confidence
Finding
The quickstart explicitly documents a delete command for agents without any warning that it is destructive or may permanently remove agent configuration, identity files, or registration state. In an operational management skill, users often copy-paste commands directly, so omission of a deletion warning materially increases the risk of accidental data loss.

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
95% confidence
Finding
The API example shows a DELETE request with no caution about destructive effects, making accidental invocation more likely in scripts, tests, or copied commands. Because this skill manages persistent agent state under ~/.openclaw, undocumented deletion semantics can lead to unintended removal of agents and associated metadata.

Description-Behavior Mismatch

Medium
Confidence
81% confidence
Finding
The manifest focuses on multi-agent conversation management with UI features like image upload, chat history, and message isolation. The README adds '飞书配对' (Feishu pairing) as part of adding/managing agents, which is a separate integration/account-linking capability not reflected in the stated description.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file describes operations such as deleting/deactivating agents and generating a Feishu pairing code, both of which can affect user data, access, or system state. The description lists these capabilities plainly but provides no cautionary note about deletion impact, deactivation consequences, or the sensitivity of pairing operations.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The markdown lists `DELETE /api/agents/:id` as an available operation, which is a destructive action affecting system state. There is no accompanying warning about confirmation, reversibility, backups, or expected impact on the managed agent.

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill declares no explicit tool scope even though the documentation indicates capabilities involving shell execution, network access, environment/credential handling, and filesystem interaction. Missing permission declarations reduces transparency and can cause operators to run a skill with broader effective access than expected, which is especially risky for a skill that manages local agents and tokens.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The skill claims data is stored locally in the browser, but elsewhere states it needs access to local OpenClaw agent directories and workspaces. This inconsistency can mislead users about where data resides and what host resources are touched, undermining informed consent for filesystem access to potentially sensitive agent data.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The documentation instructs users to extract an operator token from a local credential store using a shell command. Exposing or copying privileged tokens outside their normal storage path increases the chance of credential leakage, misuse, or reuse by unintended components, especially since the stated purpose is merely UI/chat management.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The token retrieval instructions directly expose sensitive credentials without any warning, masking, or safer handling guidance. In practice, users may paste the token into terminals, logs, screenshots, or configuration files, creating avoidable credential-compromise risk.

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
93% confidence
Finding
The code builds a shell command string for curl and inserts JSON request data directly into a single-quoted -d argument, then executes it with execSync. If attacker-controlled input contains shell metacharacters or a single quote, it can break out of quoting and trigger arbitrary command execution on the host running the CLI.

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 helper repeats the same unsafe pattern: user-controlled request bodies are JSON-stringified and embedded directly into a shell command executed via execSync with shell:'zsh'. In this CLI, fields such as message, name, and description come from user input, so crafted input can lead to local command injection rather than merely external transmission.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The delete command issues a DELETE request to remove an Agent after only checking that an ID was provided. Although it prints a status message, there is no confirmation prompt or warning that the action is destructive and may be irreversible.

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