T02 · Agent Memory Poisoning
- Location
bundle/install_wizard.py:236- Finding
Persistent Modification of Agent Behavior Through SOUL.md Injection
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a high-privilege OpenClaw plugin that discloses broad features, but it also performs persistent and overbroad workspace changes that need manual review.
Install only after reviewing the workspace changes. Expect persistent memory/index files, message hooks, SOUL.md behavior-rule changes, local script execution, external version checks, and recurring cron jobs. Back up existing OpenClaw cron jobs first, and avoid installing in workspaces where other users or skills can write executable files.
bundle/install_wizard.py:236Persistent Modification of Agent Behavior Through SOUL.md Injection
bundle/register_crons.sh:54Installer Deletes All Existing OpenClaw Cron Jobs
index.js:129Mutable Workspace Scripts Can Hijack Privileged Plugin Hooks
index.js:242Shell Command Injection Through OPENCLAW_WORKSPACE
The file claims the plugin’s purpose is only 'system file navigation,' but the architecture documents a much broader autonomous agent platform with self-evolution, background execution, memory persistence, hook interception, and sub-agent spawning. This mismatch is dangerous because it can conceal expansive capabilities from reviewers and users, undermining informed consent and increasing the chance of unauthorized actions in the host environment.
The architecture presents itself as a simple file-navigation component while describing a full autonomous agent framework with orchestration, memory, self-evaluation, workflow execution, and lifecycle hooks. This contradiction is security-relevant because it obscures the true trust boundary and can mislead review, approval, and deployment decisions.
The cron-based maintenance design performs recurring health checks, memory consolidation, cleanup, archive/index operations, version checks, and skill scans far beyond passive file navigation. Scheduled autonomous tasks can persist behavior after installation and continue modifying state without per-action user awareness, which materially increases operational risk.
The installation instructions tell users to run a command with 'dangerously-force-unsafe-install', which strongly signals that normal safety controls are being bypassed, yet the skill page does not explain the risks or justify why this is necessary. Encouraging unsafe installation without warnings materially increases the chance that users will install a powerful plugin with broad system hooks, scheduled tasks, and scanning behavior without understanding the security consequences.
The README explicitly advertises persistent cross-session memory, dream consolidation, background sub-agents, health checks, and automated cleanup/replay behaviors, but it does not present a clear, prominent consent and retention warning. In an agent skill context, these features can continuously collect, retain, and transform user and workspace data beyond a single session, increasing privacy, integrity, and operational risk if users are not fully informed.
The install instructions tell users to run a command with --dangerously-force-unsafe-install and justify child_process execution as a false positive, which normalizes bypassing a platform safety control without a strong risk disclosure. In context, the package also deploys many bundled engines and scripts, so encouraging forced unsafe installation materially raises the chance of arbitrary code execution and system compromise.
The documentation states that system rules and multiple Python/shell scripts are auto-deployed into the workspace, which indicates the package can change agent behavior and install executable artifacts without granular review. In this skill context, that is especially sensitive because the package also claims lifecycle hooking, orchestration, cron registration, and self-evolution, amplifying the impact of any hidden or unsafe logic in deployed components.
| Architecture reference | `bundle/ARCHITECTURE.md` | Full architecture with file lookup |
| System rules | `bundle/SOUL.md` | Iron rules for agent behavior (deployed to workspace) |
| Install guide | `bundle/INSTALL_GUIDE.md` | Installation wizard documentation |
| Auto-deployed scripts | `bundle/*.py`, `bundle/*.sh` | 8 scripts deployed to workspace scripts/ |
## 🔧 Configuration
The install command explicitly tells users to use a force-unsafe installation path and provides no warning, trust model, or verification guidance. In the context of a plugin that claims broad orchestration, multiple engines, cron behavior, and auto-deployed scripts, this materially increases the chance of users bypassing normal safety controls and installing a package with extensive system access.
The skill advertises first-install scans, daily maintenance jobs, memory scanning, and outbound version checks, but the page does not clearly disclose scope, affected data, network destinations, consent, or opt-out controls. That creates a real security and privacy risk because users may authorize filesystem inspection, persistent scheduled tasks, and external communications without informed consent.
The architecture description indicates auto-deployed scripts, exclusive plugin-slot enforcement, and scheduled initialization/version-check behavior, all of which suggest autonomous actions that can alter the environment without an explicit per-action approval model. In a plugin advertising 90+ Python engines and workflow orchestration, this expands the blast radius of any defect or malicious update and makes the autonomous behavior more dangerous than a narrow single-purpose skill.
plugin (index.js) ──► 90+ Python engines ──► 10-stage message pipeline
8 engine groups: init/memory/quality/operations/workflow/hooks/tools/compat
+ 3 subsystems: pipeline/planner/capability
+ 8 auto-deployed scripts
Plugin slot: exclusive — detects any overlapping plugin and blocks install
Cron: unified maintenance (01:00), engine init + version check (05:00)
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
│ ├── pipeline/ ← 10-stage message pipeline
│ ├── planner/ ← Task decomposition & goal planning
│ └── capability/ ← Task graph models
├── scripts/ ← Shell & Python helper scripts (8 auto-deployed)
├── skills/ ← OpenClaw skill definitions
├── memory/ ← Daily memory logs
├── projects/ ← Active project context (optional)
The documented version check against clawhub.ai introduces outbound network behavior unrelated to file navigation. Even if intended for updates, undisclosed external communication can leak installation metadata or create a remote dependency channel that expands the attack surface beyond the stated purpose.
The document describes automatic deployment into the workspace, file writes, copied scripts, initialization steps, and ongoing scheduled maintenance without clearly warning users that the skill modifies the system and installs persistent components. Lack of disclosure is dangerous because users may approve what appears to be a low-risk navigation helper while actually granting broad file-system and persistence changes.
The architecture explicitly describes persistent memory storage, execution logs, DAG context tracking, and an evolving user profile, but provides no user-facing privacy notice, retention policy, or consent model. In a skill context, silent collection and persistence of user interaction data can expose sensitive information and create compliance, trust, and misuse risks.
The guide explicitly states that installation and first-run initialization will automatically deploy many engines, scan memory and skills directories, connect to local databases/knowledge bases, rebuild indexes, and register scheduled tasks, but it does not present a prominent consent/impact warning or require explicit opt-in for these invasive actions. In the context of an agent skill/plugin, undisclosed automatic scanning and persistence changes increase risk because users may grant installation privileges without understanding that local data sources and system state will be modified and indexed.
The skill content appears to impose Chinese-language user-facing behavior without checking the user's language preference or offering opt-in. This can cause misleading, inaccessible, or unusable outputs for users expecting another language, and may interfere with safe communication during important operational steps such as confirmations, deletions, or restart warnings.
The trigger phrase "铁律" is very generic and likely to appear in ordinary Chinese conversation, which can unintentionally activate or steer the skill outside the user's intent. Because this file defines behavior-changing rules on trigger, accidental invocation could cause unwanted workflow changes, response style shifts, or execution gating in unrelated tasks.
The script builds its output path from the OPENCLAW_WORKSPACE environment variable and then writes to that location without validating or constraining it. If an attacker can influence the runtime environment, they can redirect the write to an unintended file path, causing arbitrary file overwrite within the permissions of the running process.
}
try:
os.makedirs(os.path.dirname(CAPSULE_FILE), exist_ok=True)
with open(CAPSULE_FILE, "w", encoding="utf-8") as f:
json.dump(state, f, indent=2, ensure_ascii=False)
print(json.dumps({"status": "ok", "path": CAPSULE_FILE}))
except Exception as e:
Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.
# Gateway 状态
try:
import urllib.request
req = urllib.request.Request("http://localhost:18789/health", method="GET")
with urllib.request.urlopen(req, timeout=5) as resp:
status = resp.status
checks["gateway"] = {"status": status}
When more than 100 records are present, the code rewrites records.jsonl and drops older entries, which is an irreversible data-modifying operation. The function docstring is terse and the runtime output does not disclose that historical replay data may be discarded.
The main run path invokes garbage_scan(clean=True) automatically, which deletes pycache directories, .pyc files, old memory files, and matching /tmp artifacts. Although progress is printed, the user-facing output does not clearly warn that destructive cleanup will occur before it starts, and there is no confirmation step in the default execution path.
This Python file's docstring, comments, and user-facing CLI output are written in Chinese, which imposes a specific language on users without offering a language choice or documenting a justified region-specific constraint. Under the policy, forcing a specific language without opt-in is a natural-language policy violation.
In force mode, the script truncates and recreates existing JSON/JSONL files in a fixed workspace path without any interactive warning, backup, or dry-run safeguard. This can destroy operational data such as memories, replay buffers, or tuning history, which is a security-relevant integrity risk if an operator or automation invokes --force unintentionally.
Force mode also overwrites config and tracker state under the workspace skill directory, silently resetting behavior and registered rules. In an agent/automation context, this can remove safeguards or operational state and cause integrity and availability issues, especially because the script targets persistent workspace files and presents itself as initialization rather than destructive reset.
_run_py() locates and executes Python scripts from the user-controlled WORKSPACE before falling back to the bundled copy. Because WORKSPACE is derived from environment variables and the installer later calls this helper for multiple script names, a malicious workspace can plant files like scan_memory.py or auto_engines.py and achieve arbitrary code execution during installation.
return {"status": "error", "message": f"脚本未找到: {script}"}
try:
result = subprocess.run(
[sys.executable, target] + (args or []),
cwd=WORKSPACE, capture_output=True, text=True, timeout=60
)
Detected: suspicious.dangerous_exec