Back to skill

Security audit

CLAW Agent 智控驾驶舱

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent local monitoring dashboard, but its deployment exposes workspace files and unauthenticated mutable APIs broadly enough that users should review and harden it before installing.

Install only in an isolated workspace and bind both services to 127.0.0.1 or place them behind authentication. Do not expose ports 8888 or 8889 to a network, avoid serving the whole workspace, sanitize dashboard-rendered data, pin PM2 or use a reviewed local dependency, and treat the recommended Cron job as an opt-in background collector.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/dashboard/ecosystem.config.js:3
Finding

Entire OpenClaw Workspace Exposed by Unauthenticated Static Server

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/dashboard/agent-api.js:41
Finding

Unauthenticated Agent and Quota API Exposed on All Network Interfaces

Content
View full analysis
body += chunk); req.on('end', () => { try { const input = JSON.parse(body); const q = JSON.parse(fs.readFileSync(QUOTA_FILE, 'utf8')); if (typeof input.manualTotal === 'number') { q.manualTotal = input.manualTotal; q.manualUpdatedAt = Date.now(); ``` ```javascript } else if (urlPath === '/api/cron-update' && req.method === 'POST') { // 保存 Cron 修改请求 let body = ''; req.on('data', chunk => body += chunk); req.on('end', () => { try { const input = JSON.parse(body); const pendingFile = path.join(__dirname, 'cron-pending.json'); fs.writeFileSync(pendingFile, JSON.stringify({ changes: input.changes, requestedAt: Date.now(), status: 'pending' }, null, 2)); ``` ```javascript server.listen(PORT, '0.0.0.0', () => { ``` ### Technical Analysis The API listens on every network interface a ...[truncated 1988 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/dashboard/agent-dashboard.html:1173
Finding

Stored DOM XSS Through Unescaped Agent and Cron Data

Content
View full analysis
{ const statusDesc = a.statusText ? a.statusText : (a.progress >= 100 ? '✅ 已完成' : '🔄 进行中'); return `
${a.emoji}
${a.name}
${a.role}
${statusLabel(a.status)}
📌 当前任务
${a.task}
${statusDesc} ${a.progress}%
🕐 ${timeAgo(a.lastActive)} 🧠 ${a.model} 📊 ${a.contextPct}%
`; }).join(''); } ``` Additional affected rendering occurs in the Cron and token sections: ```javascript tbody.innerHTML = cronData.jobs.map(job => { // ... return ` // ...
${job.name}
${job.description || ''}
``` ```javascript document.getElementById('tokenBars').innerHTML = sorted.map(a => { // ... return `
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/dashboard/agent-api.js:71
Finding

Unbounded HTTP Request Bodies Permit Memory-Exhaustion Denial of Service

Content
View full analysis
body += chunk); req.on('end', () => { try { const input = JSON.parse(body); ``` The same pattern is repeated for the Cron update endpoint: ```javascript } else if (urlPath === '/api/cron-update' && req.method === 'POST') { // 保存 Cron 修改请求 let body = ''; req.on('data', chunk => body += chunk); req.on('end', () => { try { const input = JSON.parse(body); ``` ### Technical Analysis Both POST handlers append incoming chunks to an in-memory string without enforcing a maximum size. Because the server is unauthenticated and listens on all interfaces, a remote client can send a very large body or keep a request open while continuously transmitting data. String concatenation and later JSON parsing amplify memory and CPU consumption. Multiple concurrent requests can exhaust the Node.js heap or make the event loop unresponsive. ### Attack Path 1. The API starts on `0.0.0.0:8889`. 2. An attacker opens one or more connections to `/api/quota` or `/api/cron-update`. 3. The attacker sends oversized or continuous request bodies. 4. The server repeatedly appends chunks to the `body` string. 5. Process memory and CPU usage increase until the API slows, crashes, or is restarted by PM2. 6. Repeated requests can create a restart loop and make the dashboard unavailable. ### Impact Assessment The attacker can disrupt: - Agent status retrieval - Quota monitoring and updates - Cron management requests - Dashboard refresh operations PM2 autorestart may restore the process, but it does not prevent repeated resource-exhaustion attacks and may increase restart churn. ]]>
Remediation
View remediation
{ received += chunk.length; if (received > MAX_BODY_BYTES) { res.writeHead(413, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Request body too large' })); req.destroy(); return; } body += chunk; }); ``` 2. Add request-header and body timeouts. 3. Limit concurrent connections and apply per-client rate limiting. 4. Reject unexpected content types. 5. Authenticate callers before accepting mutable requests. 6. Place the API behind a reverse proxy configured with body-size, timeout, and connection limits. 7. Validate parsed payload depth and structure to reduce parser and serialization abuse. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:34
Finding

Unpinned Global PM2 Installation Creates Supply-Chain Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The skill advertises significant operational features that are not substantiated by the described or detected behavior, creating a trust gap between what users expect and what is actually deployed. In a monitoring/operations context, overstated capabilities can cause users to rely on nonexistent alerting, cron control, renewal, or agent-status features, leading to missed incidents, quota overruns, or unsafe administrative assumptions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The header comment states this is a '轻量级 HTTP 服务,提供 Agent 状态数据', which suggests a read-oriented status API. In reality, the server also accepts POST requests to /api/quota and /api/cron-update and writes persistent changes to local JSON files, expanding the behavior beyond merely serving status data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This HTML file declares lang="zh-CN" and the interface strings are consistently rendered in Chinese, with later logic also formatting dates/times using the zh-CN locale. Under the policy, forcing a specific language or locale without user opt-in is a natural-language policy violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest advertises '订阅到期倒计时与一键续订' / 'one-click renewal', which implies an actual subscription renewal capability. However, the UI's renewal flow only opens a modal and later updates local in-memory countdown variables, with no backend/API call to any subscription service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The modal tells the user '续订后到期日将自动顺延', suggesting a real persisted subscription update. In reality, confirmRenew merely adds 30 days to the JavaScript variable 'subExpire' and increments 'subTotalDays', so the effect is temporary and local to the page session.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

This file explicitly instructs users to create a recurring cron job that continuously refreshes session-derived monitoring data, which introduces persistent automated access to agent/session metadata over time. In this skill context, persistence is expected for monitoring, but it still increases exposure by enabling ongoing collection and storage without per-run user review.

Content

Scanner excerpt · references/cron-setup.md (reported line 5)May include surrounding context.

md
## Data Update Cron (Recommended)

Create a Cron job to update agent-data.json with fresh session data.

### Recommended Settings

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The guide recommends a silent background cron that writes to {workspace}/agent-data.json without an explicit notice about ongoing file modification, retention, or overwrite behavior. Silent persistence can surprise users, create integrity issues for workspace files, and normalize unattended collection of session-derived data without clear consent or review.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest description and heading prominently present the skill in Chinese alongside English branding, but the document does not state that language is optional or user-selectable. Under the policy, locale or language constraints should either be opt-in or clearly justified; here the skill appears generally applicable rather than region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file’s natural-language description and many user-facing messages are written in Chinese, including the header and endpoint descriptions, with no indication that users may choose another language. This can violate a language/locale policy when a skill implicitly forces one language without opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

At startup, the service prints an endpoint list containing only GET /api/agents and GET /api/health, while the code also implements GET/POST /api/quota, GET /api/cron, and POST /api/cron-update. This operational documentation gives a materially incomplete picture of the API surface, especially hiding state-changing endpoints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code calls toLocaleString('zh-CN', ...), which enforces a specific locale for displayed schedule times regardless of user preference. This is a locale policy issue because the file does not provide any user choice or documented regional justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

new Date().toLocaleTimeString('zh-CN') forces Chinese locale formatting for a user-facing timestamp. Because the file does not offer locale selection or explain a region-specific limitation, this conflicts with the language/locale policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code uses subExpire.toLocaleDateString('zh-CN', ...), which fixes expiry-date presentation to Chinese locale formatting. This is another user-facing locale constraint that is neither configurable nor explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This JavaScript file contains natural-language comments and console output in Chinese, including the title and operational messages. Under the stated policy, forcing a specific language without user opt-in or a documented locale-specific justification is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file describes a recurring cron job and payload template, but it does not clearly specify the exact activation boundaries for when this skill should run beyond a generic recommended schedule. Because the guidance is broad and lacks explicit negative examples or tighter constraints, it could lead to unintended or overly broad background invocation patterns.

Content

No source excerpt is available for this finding.