Back to skill

Security audit

Agency HQ

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real OpenClaw dashboard, but live mode can read private agent logs and host telemetry and expose them through unauthenticated web endpoints.

Install only if you are comfortable treating live mode as sensitive monitoring software. Keep it in demo mode unless needed; if live mode is enabled, bind it to localhost or put it behind authentication, do not expose the Next.js port to a network, avoid displaying raw prompts, validate agent IDs, and update vulnerable dependencies.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/app/api/agents/activity/route.ts:43
Finding

Unauthenticated Disclosure of OpenClaw Session and Cron Messages

Content
View full analysis
15 && entry.content.length < 200) { const text = entry.content.replace(/\n/g, ' ').substring(0, 120); if (text.startsWith('[') || text.startsWith('Read ') || text.startsWith('HEARTBEAT')) continue; activities.push({ timestamp: entry.timestamp || file.mtime.toISOString(), agentId: agent.id, agentName: agent.name, agentEmoji: agent.emoji, agentColor: agent.color, message: text, type: classifyMessage(text), }); } } catch { continue; } } ``` ```ts if (fs.existsSync(cronRunsDir)) { const cronFiles = fs.readdirSync(cronRunsDir) .filter(f => f.endsWith('.jsonl')) .map(f => ({ name: f, mtime: fs.statSync(path.join(cronRunsDir, f)).mtime })) .sort((a, b) => b.mtime.getTime() - a.mtime.getTime()) .slice(0, 10); for (const file of cronFiles) { try { const content = fs.readFileSync(path.join(cronRunsDir, file.name), 'utf-8'); const lines = content.trim().split('\n').slice(0, 5); for (const line of lines) { try { const entry = JSON.parse(line); if (entry.role === 'user' && typeof entry.content === 'string') { const text = entry.content.replace(/\n/g, ' ').substring(0, 120); activities.push({ timestamp: file.mtime.toISOString(), agentId: 'cron', agentName: 'Cron', agentEmoji: '⏰', ag ...[truncated 2583 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/app/api/agents/status/route.ts:41
Finding

Unauthenticated Disclosure of Assistant Output and Agent Operational State

Content
View full analysis
= 0; i--) { try { const entry = JSON.parse(recent[i]); if (entry.role === 'assistant' && typeof entry.content === 'string' && entry.content.length > 10) { const text = entry.content.substring(0, 80).replace(/\n/g, ' '); return text; } if (entry.role === 'assistant' && entry.tool_calls) { const toolName = entry.tool_calls[0]?.function?.name; if (toolName) return `Using ${toolName}...`; } } catch { continue; } } return null; } catch { return null; } } ``` ```ts export async function GET() { try { if (isDemoMode()) { return NextResponse.json({ agents: getDemoAgentStates(), timestamp: new Date().toISOString(), mode: 'demo', }); } const openclawHome = process.env.OPENCLAW_HOME || path.join(process.env.HOME || '/home/user', '.openclaw'); const agentsHome = path.join(openclawHome, 'agents'); const states: AgentState[] = AGENTS.map(agent => { const sessionsDir = path.join(agentsHome, agent.id, 'sessions'); const newest = getNewestFile(sessionsDir); const running = isAgentRunning(agent.id); let status: AgentStatus = 'offline'; let lastActiveRelative = 'unknown'; let currentTask: string | null = null; let idleMinutes = 999; if (newest) { const diffMs = Date.now() - newest.mtime.getTime(); const diffMin = diffMs / 60000; idl ...[truncated 2540 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/app/api/agents/status/route.ts:67
Finding

Shell Command Injection Through Customizable Agent Identifiers

Content
View full analysis
0; } catch { return false; } } ``` The value is supplied by the customizable agent configuration: ```ts export interface AgentConfig { id: string; name: string; emoji: string; role: string; model: string; color: string; desk: string; accessory: 'glasses' | 'hat' | 'badge' | 'headphones' | 'scarf' | 'cap' | 'bowtie' | 'visor' | 'antenna' | 'crown' | 'monocle'; } ``` ### Technical Analysis `execSync()` receives a dynamically constructed string, causing Node.js to execute it through a shell. The `agentId` value is inserted inside a double-quoted shell argument without validation or shell escaping. The shipped identifiers are benign, but the project explicitly instructs users to customize `src/lib/agents.ts`. The TypeScript type permits any string. Shell substitutions and other metacharacters can therefore alter command behavior. For example, command substitution syntax remains active inside double quotes in common Unix shells. The vulnerable function is called for each configured agent whenever the unauthenticated status endpoint is requested. ### Attack Path 1. An attacker or compromised configuration source gains the ability to add or modify an agent entry in `src/lib/agents.ts`. 2. The attacker places shell syntax in the agent `id`, such as a command-substitution expression. 3. The project is built or restarted with the malicious configuration. 4. Any user requests `GET /api/agents/status`. 5. `isAgentRunning()` interpolates the crafted identifier into the shell command. 6. The shell evaluates the in ...[truncated 752 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/lib/demo-data.ts:120
Finding

Fail-Open Mode Selection Automatically Enables Sensitive Live-Mode Access

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
src/app/api/agents/stats/route.ts:8
Finding

Unauthenticated Exposure of Host Resource and Activity Telemetry

Content
View full analysis
parseInt(s)); return { total: parts[0], used: parts[1] }; } catch { return { total: 0, used: 0 }; } } ``` ```ts export async function GET() { try { if (isDemoMode()) { return NextResponse.json(getDemoStats()); } const ram = getRam(); const disk = getDisk(); const stats: SystemStats = { cpuLoad: getCpuLoad(), ramUsed: ram.used, ramTotal: ram.total, diskUsed: disk.used, diskTotal: disk.total, activeAgents: 0, sessionsToday: getSessionsToday(), uptime: getUptime(), }; return NextResponse.json(stats); } catch (err) { console.error('[api/agents/stats]', err); return NextResponse.json( { error: 'Failed to fetch stats' }, { ...[truncated 1564 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill performs backend collection of host metrics, reads OpenClaw session files, and exposes an API endpoint while presenting itself primarily as a harmless visualization, that is a meaningful transparency gap. Operators may deploy it with broader trust than intended, leading to unintended local data exposure or over-privileged installation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill performs backend collection of host metrics, reads OpenClaw session files, and exposes an API endpoint while presenting itself primarily as a harmless visualization, that is a meaningful transparency gap. Operators may deploy it with broader trust than intended, leading to unintended local data exposure or over-privileged installation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the skill performs backend collection of host metrics, reads OpenClaw session files, and exposes an API endpoint while presenting itself primarily as a harmless visualization, that is a meaningful transparency gap. Operators may deploy it with broader trust than intended, leading to unintended local data exposure or over-privileged installation.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 56)May include surrounding context.

Copy .env.example to .env.local:

bash
cp .env.example .env.local

Set ARENA_MODE=live to connect to your OpenClaw instance, or leave as demo for simulated data.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 35)May include surrounding context.

Copy .env.example to .env.local:

bash
cp .env.example .env.local

Set ARENA_MODE=live to connect to your OpenClaw instance, or leave as demo for simulated data.

Known Vulnerable Dependency: brace-expansion==5.0.4 — 5 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-45149 (brace-expansion: Large numeric range defeats documented `max` DoS protection) +2 more

High
Category
Supply Chain
Confidence
89% confidence
Finding

brace-expansion 5.0.4 is associated with multiple denial-of-service issues involving pathological expansion patterns. Here it appears in a dev-tooling path under TypeScript/ESLint-related packages, so it is less dangerous than a network-facing parser, but it can still hang or exhaust memory if attacker-controlled patterns reach the toolchain.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @xmldom/xmldom==0.8.11 — 15 advisory(ies): CVE-2026-83608 (xmldom: DocType `name` Injection Bypasses requireWellFormed); CVE-2026-41673 (xmldom: Uncontrolled recursion in XML serialization leads to DoS); CVE-2026-83605 (xmldom: Attribute name injection via setAttribute() bypasses requireWellFormed) +12 more

High
Category
Supply Chain
Confidence
93% confidence
Finding

@xmldom/xmldom 0.8.11 has numerous reported XML parsing and serialization issues, including input validation bypasses and denial-of-service conditions. This is more concerning than many other findings because it is a runtime dependency through pixi.js, so if the skill ingests attacker-controlled SVG/XML-like content, malformed input could crash processing or trigger unsafe parser behavior.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: brace-expansion==1.1.12 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
90% confidence
Finding

brace-expansion 1.1.12 is an older vulnerable branch with multiple DoS vectors related to expansion complexity and memory use. Even though this instance is in dev dependencies, old globbing components are commonly reachable from file-matching operations in tooling and can be abused to stall CI or developer workflows when given crafted patterns.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: browserslist==4.28.1 — 2 advisory(ies): CVE-2026-73088 (Browserslist: Uncaught crash / prototype write via untrusted browserslist-stats.); CVE-2026-73089 (Browserslist: Unbounded memory growth (no cache eviction) via distinct query res)

High
Category
Supply Chain
Confidence
84% confidence
Finding

browserslist 4.28.1 is reported vulnerable to crash and unbounded memory growth when handling untrusted stats/query inputs. In this skill it is primarily part of build tooling, which reduces exposure, but if CI, automation, or developer scripts process attacker-provided Browserslist configuration or stats files, this can become a practical denial-of-service vector.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: flatted==3.4.1 — 1 advisory(ies): CVE-2026-33228 (Prototype Pollution via parse() in NodeJS flatted)

High
Category
Supply Chain
Confidence
82% confidence
Finding

flatted 3.4.1 is flagged for prototype pollution via parse(), which is a real class of vulnerability when parsing attacker-controlled serialized data. In this lockfile it is only a dev dependency through flat-cache/file-entry-cache, so runtime exposure in the shipped skill is not evident, but compromised tooling or malicious workspace data could still affect lint/build processes.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 91)May include surrounding context.

md
### Customize Agent Chat

Edit `src/lib/agent-chat.ts` to write personality-driven banter for your agents. Each agent has `general` lines and optional directed lines (e.g., `toScotty`, `toCipher`).

---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly says live mode reads real agent session files, cron activity, and system statistics from local paths, but it does not prominently warn users about the privacy and system-access implications of enabling this mode. In a visualization skill, this matters because operators may enable live mode expecting harmless UI behavior while exposing sensitive operational metadata, prompts, task history, or host telemetry to the app.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
74% confidence
Finding

The skill documentation describes use of environment-based configuration (.env.local, ARENA_MODE) and live-mode access to local system state, but it does not declare an explicit tool/permission scope. Missing capability declarations can cause operators to underestimate what the skill needs and weaken review and sandboxing decisions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · SKILL.md (reported line 57)May include surrounding context.

md
### 4. Customize Chat Lines (Optional)

Edit `src/lib/agent-chat.ts` to write personality-driven banter. Each agent has:
- `general` — random lines said to the room
- `to{AgentName}` — directed lines at specific agents (30% chance)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Live mode is documented to scan local OpenClaw session .jsonl files and extract user messages and tool calls, which can contain sensitive prompts, secrets, tokens, or proprietary workflow data. Without a prominent privacy warning, minimization rules, and consent boundaries, users may enable live mode without understanding that historical session content is being ingested and displayed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This endpoint reads raw OpenClaw session and cron JSONL files from disk and returns excerpts of user prompts and agent activity through an API. Even though it truncates and filters some content, it still exposes potentially sensitive local workflow data well beyond what a simple visualization feature strictly needs, and any caller able to hit this route may obtain internal prompt/task information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code collects user-originated content from session and cron logs and serves it via the activity API without any disclosure, consent gate, or visible privacy control in this path. In the context of a visual office dashboard, this creates an unnecessary privacy exposure because user prompts may contain operational details, secrets, or personal data that observers of the UI or API consumers were not meant to see.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This endpoint executes multiple shell commands via execSync to gather host uptime, CPU, RAM, and disk data. Even though the command strings are hardcoded and not directly injectable here, exposing server host telemetry and relying on shell execution in a web API expands attack surface and exceeds the stated office-visualization purpose, especially if this skill is deployed in shared or hosted environments.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code traverses OPENCLAW_HOME/.openclaw/agents and enumerates per-agent session files to compute session counts, which accesses local application data outside a narrow visualization-only scope. This can leak behavioral metadata about local agents and user activity, and in some deployments may reveal information about filesystem layout or the presence of sensitive agent/session artifacts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The status API reads local session transcript files and returns assistant content snippets as currentTask in the HTTP response. Those transcripts may contain sensitive prompts, secrets, internal reasoning, customer data, or tool usage details, so exposing even truncated excerpts can leak confidential information to anyone who can access the endpoint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The endpoint builds a shell command with unsanitized agentId interpolation and executes it via execSync. If an agent ID can contain shell metacharacters or be influenced through configuration or supply-chain changes, this can become command injection; even without injection, exposing process-inspection behavior from a web route increases attack surface and leaks runtime state.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @babel/core==7.29.0 — 1 advisory(ies): CVE-2026-49356 (@babel/core: Arbitrary File Read via sourceMappingURL Comment)

Low
Category
Supply Chain
Confidence
75% confidence
Finding

The lockfile pins @babel/core 7.29.0, and the cited advisory indicates an arbitrary file read condition via sourceMappingURL handling. In this skill, Babel is a development dependency and not obviously exposed to untrusted runtime input, so exploitability is limited, but keeping a known-vulnerable parser/tooling component is still a real supply-chain risk.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @humanfs/node==0.16.7 — 1 advisory(ies): GHSA-p498-v437-472g (humanfs: Recursive copy follows symlinked files and copies data from outside the)

Low
Category
Supply Chain
Confidence
73% confidence
Finding

@humanfs/node 0.16.7 is flagged for recursive copy following symlinks outside the intended tree. Although this package is only a dev dependency here through ESLint tooling, the issue is still real if repository or CI workflows copy attacker-controlled paths, which could leak or overwrite unintended files.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: baseline-browser-mapping==2.10.8 — 1 advisory(ies): CVE-2026-45819 (baseline-browser-mapping process termination on invalid input causes denial of s)

Low
Category
Supply Chain
Confidence
66% confidence
Finding

baseline-browser-mapping 2.10.8 is flagged for invalid-input process termination, which is a genuine availability issue. In this project it is a transitive dependency of Next/Browserslist tooling rather than a direct runtime component, so the practical risk is mostly limited to build or CI disruption.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 13)May include surrounding context.

json
},
  "dependencies": {
    "next": "16.1.6",
    "pixi.js": "^8.17.0",
    "react": "19.2.3",
    "react-dom": "19.2.3"
  },

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/app/api/agents/stats/route.ts:10

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/app/api/agents/status/route.ts:69