Back to skill

Security audit

Agent Soul System

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with managing agent personality files, but its web editor exposes unauthenticated read/write access to persistent agent instructions and documents background startup.

Review this carefully before installing. Use the scripts only in a trusted local environment, avoid enabling the documented auto-start server, do not expose the editor port to a network, and back up SOUL.md files before editing. The server should be fixed to bind to localhost, require authentication, remove wildcard CORS, validate agent names and paths, and limit request sizes before it is treated as low risk.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T02 · Agent Memory Poisoning

Error
Location
scripts/soul-server.js:27
Finding

Unauthenticated Network API Permits Persistent Agent Instruction Poisoning

Content
View full analysis
body += chunk); req.on('end', () => { try { const data = JSON.parse(body); fs.writeFileSync(soulPath, data.content, 'utf-8'); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ ok: true, path: soulPath })); } catch (e) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: e.message })); } }); return; } ``` ```javascript server.listen(PORT, () => { console.log(`SOUL Editor server running at http://localhost:${PORT}`); console.log(`Agents directory: ${AGENTS_DIR}`); console.log('Press Ctrl+C to stop'); }); ``` ### Technical Analysis The HTTP server does ...[truncated 2613 chars]
Remediation
View remediation
{ console.log(`SOUL Editor server running at http://127.0.0.1:${PORT}`); }); ``` 2. Require authentication for every API endpoint. Generate a cryptographically random token and require it in an `Authorization` header. 3. Replace wildcard CORS with an explicit trusted origin. If the editor is served by the same server, disable CORS and use same-origin requests. 4. Implement authorization so that authenticated users can access only approved agent files. 5. Add CSRF protection if browser cookies or session authentication are used. 6. Require explicit confirmation for persistent instruction changes and retain backups or version history. 7. Validate saved content against an expected SOUL schema and reject unexpected instruction sections where appropriate. 8. Apply restrictive filesystem permissions to the agents directory and run the server under a dedicated, least-privileged account. 9. Add request logging and audit records for every read and modification operation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/soul-create.py:77
Finding

Path Traversal Through Unsanitized Agent Name in Creation Script

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/soul-server.js:109
Finding

Prefix-Based Static File Containment Check Can Be Bypassed

Content
View full analysis
{ if (err) { res.writeHead(404); res.end('Not found: ' + pathname); return; } const ext = path.extname(filePath); res.writeHead(200, { 'Content-Type': MIME_TYPES[ext] || 'text/plain' }); res.end(data); }); ``` ### Technical Analysis The server attempts to enforce static-file containment using a string-prefix comparison: ```javascript filePath.startsWith(canvasDir) ``` A matching string prefix does not prove that a path is a child of a directory. For example, a normalized path in a sibling directory named `canvas-backup` can still begin with the string representing the `canvas` directory. The implementation also does not resolve symlinks before validating containment. Therefore, even a syntactically contained path could refer to a file outside the intended directory through a symlink or junction. The endpoint is unauthenticated and inherits the server's wildcard CORS and broad network binding, increasing the accessibility of the flaw. ### Attack Path 1. The attacker identifies or guesses a readable sibling path whose name begins with the canvas directory name, such as `canvas-backup`. 2. The attacker submits a traversal-style static-file request that normalizes from `canvas` into the matching sibling directory. 3. `path.join` normalizes the path. 4. The resulting path still starts with the `canvasDir` string even though it is not insi ...[truncated 652 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/soul-server.js:88
Finding

Unbounded Request Body Allows Memory and Disk Exhaustion

Content
View full analysis
body += chunk); req.on('end', () => { try { const data = JSON.parse(body); fs.writeFileSync(soulPath, data.content, 'utf-8'); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ ok: true, path: soulPath })); } catch (e) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: e.message })); } }); return; } ``` ### Technical Analysis The POST handler appends every incoming chunk to an in-memory string without enforcing a maximum request size. Once parsed, `data.content` is written synchronously without validating its type or length. An attacker can send a very large body or maintain multiple slow, concurrent uploads. Accumulated strings can exhaust heap memory, trigger garbage-collection pressure, or terminate the Node.js process. If parsing succeeds, a very large `content` value can also consume disk space. Synchronous file writes block the event loop during the operation. The absence of authentication or rate limiting makes this behavior directly reachable by any client that can connect to the service. ### Attack Path 1. The attacker connects to the exposed HTTP service. 2. The attacker sends one or more POST requests to `/api/agents/`. 3. Each request streams a very large JSON body without a configured limit. 4. The server repeatedly concatenates chunks into memory. 5. Process memory and CPU usage increase until requests stall or the process terminates. 6. If the JSON ...[truncated 559 chars]
Remediation
View remediation
{ received += chunk.length; if (received > MAX_BODY_SIZE) { res.writeHead(413, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Request body too large' })); req.destroy(); return; } body += chunk; }); ``` 2. Validate that `data.content` is a string and enforce a separate maximum content length. 3. Reject invalid or excessive `Content-Length` values before reading the body. 4. Add connection, header, and request timeouts to mitigate slow uploads. 5. Add per-client rate limiting and concurrency limits. 6. Use asynchronous and atomic file writes to reduce event-loop blocking and prevent partially written files. 7. Require authentication before accepting body data so unauthenticated clients cannot consume application resources. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims personality-file management features but also documents launching a local HTTP server and exposing editing of local agent files, which is materially different and riskier than the stated purpose. Undisclosed or underemphasized network exposure combined with file read/write behavior can create an unexpected attack surface and unauthorized modification path.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims personality-file management features but also documents launching a local HTTP server and exposing editing of local agent files, which is materially different and riskier than the stated purpose. Undisclosed or underemphasized network exposure combined with file read/write behavior can create an unexpected attack surface and unauthorized modification path.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script uses the unvalidated agent name directly in os.path.join(AGENTS_DIR, name), so an attacker can supply path traversal values such as '../' or absolute paths to create directories and write SOUL.md outside the intended agents directory. Because the tool performs filesystem writes and creates parent directories automatically, this can overwrite or plant files in arbitrary user-writable locations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation advertises commands that read, write, and serve local files, but it does not declare any explicit tool scope or permissions boundaries. In an agent ecosystem, missing capability declarations weakens least-privilege controls and makes it harder to assess or constrain what the skill may access.

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 60)May include surrounding context.

md
# Validate all agents have SOUL.md
python ~/.openclaw/workspace/skills/agent-soul-system/scripts/soul-check.py

# Create a new agent with interactive prompts
python ~/.openclaw/workspace/skills/agent-soul-system/scripts/soul-create.py

# List all agents and their souls

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation introduces a web server and browser-based editor that are not necessary for basic SOUL.md validation and substantially expand the attack surface. Adding a persistent service to a content-management skill increases the chance of unauthorized access, misuse, or unnoticed background exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill advertises direct editing and saving of all agent SOUL.md files without warning users that it will modify local files. In agent environments, silent or poorly signposted write operations can lead to accidental corruption, privilege misuse, or unauthorized changes to operational personas and rules.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Documenting automatic startup on Windows login describes persistence behavior that changes the user's system state without an adequate warning or explicit opt-in. Persistence is security-sensitive because it can keep a service running indefinitely and increase the window for exploitation or unauthorized file access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file presents a substantial portion of its persona library entirely in Chinese, including headings, table columns, and descriptions, without indicating that language selection is optional. This can violate language/locale policy when used in a broader skill context because it implicitly constrains users to a specific language without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown template is entirely structured with Chinese section headings and placeholders, which implicitly requires the skill author or downstream agent to operate in Chinese. The file does not offer any language choice or indicate that Chinese is optional, which can violate language/locale policy requirements for user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README advertises direct saving to agent directories through a REST API and elsewhere describes hidden auto-start behavior, but does not prominently warn users that this changes local files and may run persistently in the background. In the context of an agent-personality management skill, this creates unnecessary risk because a local web service with file-write capability can be misused to modify agent behavior or be abused if exposed or triggered unexpectedly.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README documents persistence via a Windows Registry Run key and a hidden launcher for a local server, which exceeds the stated need of editing SOUL.md files. Even though this is documentation rather than executable code, it normalizes stealthy persistence behavior that can keep a file-writing service running continuously and increase the attack surface on the host.

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 · scripts/soul-create.py (reported line 2)May include surrounding context.

python
#!/usr/bin/env python3
"""Enhanced create a new agent with SOUL.md template and interactive personality selection."""
import os, sys

AGENTS_DIR = os.path.expanduser("~/.openclaw/agents")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script embeds its personality library and generated SOUL.md template largely in Chinese, including section headers and example values, which steers the created agent toward Chinese-language operation by default. There is no user-facing choice of language or locale, so this constitutes a language/locale policy concern rather than a technical issue.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest describes a personality-file management skill, but this file implements a long-running web server with static file hosting and REST-style endpoints. Serving arbitrary editor assets and exposing agent data over HTTP is a broader operational behavior than simply creating, managing, or validating SOUL.md content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The POST endpoint writes attacker-controlled content directly to a filesystem path derived from an unvalidated URL segment, with no authentication, authorization, CSRF protection, or path sanitization. Because CORS is set to '*', any website the user visits can potentially issue cross-origin requests to overwrite SOUL.md files and, depending on path handling, possibly other files under or outside the agents directory.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The static file handler attempts to confine access to the canvas directory using a naive startsWith check on a non-normalized joined path. An attacker can supply traversal-style paths that still satisfy the prefix check before normalization, potentially allowing reads of arbitrary files outside the intended directory.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The template and directory annotations use Chinese section names and labels such as 人格, 核心特质, and related workflow text, implying a fixed language/locale for generated SOUL.md content. There is no indication that users may choose another language or that the Chinese locale is a documented requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This markdown defines agent names and roles using Chinese descriptors alongside English labels, but it does not state that the language choice is optional or limited to a specific locale. Under the natural-language policy rule, forcing or assuming a specific language without opt-in can be a policy concern.

Content

No source excerpt is available for this finding.