T09 · Insecure Skill Coding Practices
- Location
scripts/brain_fullness.py:23- Finding
Shell Command Injection Through Unvalidated PID File Content
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is purpose-aligned as a memory and self-maintenance system, but it broadly persists, copies, recalls, and backs up private workspace and cross-skill state with insufficient scoping.
Install only if you explicitly want a local agent memory system that writes durable files and may duplicate private workspace state. Review or remove the cross-skill authority reads, broad backup scope, raw recall outputs, watcher behavior, and PID shell check before using it in a sensitive workspace.
scripts/brain_fullness.py:23Shell Command Injection Through Unvalidated PID File Content
scripts/remember.py:6Persistent Agent Memory Poisoning Through Arbitrary Recall Content
scripts/boot_recall.py:6Raw Private Memory and Cross-Skill Authority State Exposed Through Recall Output
scripts/context_checkpoint.py:19Unredacted Sensitive State Duplicated Into Checkpoints, Consolidations, and Dream Files
scripts/brain_backup.sh:3Overbroad Unencrypted Backup of Private and Cross-Skill Workspace Data
scripts/status_dashboard.py:12Unnecessary Privilege and Host Reconnaissance in Status Dashboard
The skill describes itself as a cognitive operating protocol, but also references file monitoring, hot-reload watching, event logging, and automatic subprocess execution across other resources. This materially changes the risk profile from passive guidance to active automation, creating opportunities for unintended code execution chains and persistent surveillance of workspace changes.
The skill describes itself as a cognitive operating protocol, but also references file monitoring, hot-reload watching, event logging, and automatic subprocess execution across other resources. This materially changes the risk profile from passive guidance to active automation, creating opportunities for unintended code execution chains and persistent surveillance of workspace changes.
Referenced artifact was not completely inspected
- Skill installed → expect directory and `SKILL.md` to exist.
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
lob(str(ws/'skills/brain-system/backups/openclaw-brain-backup-*.tar.gz')))))
pidfile=ws/'skills/brain-system/state/hot-reload.pid'
hot=False
if pidfile.exists():
pid=pidfile.read_text().strip()
hot=subprocess.run(['bash','-lc',f'kill -0 {pid}'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('hot reload running', hot))
cron=subprocess.run(['bash','-lc','crontab -l 2>/dev/null | grep -q OPENCLAW_BRAIN_SYSTEM'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('cron installed', cron))
score=sum(v for _,v in checks); total=len(checks)
print(f'brain_fullness={score}/{total} ({score/total*10:.1f}/10)')
for k,v in checks: print(('✅' if v else '❌'), k)
The code intentionally aggregates sensitive durable state into a daily markdown file, including authority and task-queue information that may reveal privileges, internal policies, plans, or other operationally sensitive context. Consolidation amplifies risk because it centralizes disparate secrets or sensitive metadata into an easy-to-find, human-readable artifact that could be exfiltrated or misused if accessed.
The skill repeatedly instructs the agent to read, write, checkpoint, back up, and run local scripts, yet the manifest does not declare any explicit tool scope or permissions. That mismatch weakens operator visibility and review, making it easier for a broadly triggered skill to access or mutate workspace state without clear user awareness.
The trigger phrases are extremely broad, including everyday terms like memory, reflection, optimization, and attention management. Broad activation increases the chance the skill engages in contexts where users did not intend persistent memory, maintenance actions, or script-backed workflow changes.
The skill strongly promotes episodic, semantic, and procedural memory storage into multiple files, but does not present an upfront warning that user/project data may be persisted across sessions. This is risky because users may disclose sensitive information under the assumption of transient chat behavior while the skill externalizes it into durable storage.
The guidance to 'fix the issue first' and 'act directly' encourages the agent to take autonomous action based on inferred user preference, which can bypass meaningful confirmation in ambiguous situations. In a skill that also supports persistent memory, configuration changes, installs, and maintenance actions, this increases the chance of unauthorized or overly broad changes.
- Fix the issue first, then summarize evidence.
- Convert the correction into a durable rule if likely to recur.
- Match verbosity to the user’s current preference; if they ask “just do it”, act directly.
- Avoid defensiveness and avoid claiming success without verification.
## Goal Stack
The maintenance stack includes backup, consolidation, dashboard, queue, and hot-reload scripts that can write files and create archives, yet this behavior is not surfaced as a clear warning before use. Users may therefore enable a seemingly organizational skill without understanding that autonomous maintenance can create additional copies of workspace data and modify local state.
The script copies content from multiple durable memory/state files, including authority-related state, into a new markdown file under workspace storage without minimization, consent, or access-control checks. This creates data propagation and retention risk: sensitive operational context may be duplicated into a broader or less-governed location, increasing exposure if other skills, users, or processes can read the dreams directory.
The script enumerates and prints multiple workspace state files that are likely to contain sensitive internal context, including pinned memory, checkpoints, authority state, task queue contents, and tool metadata. Even though it only reads local files, its purpose is to surface potentially confidential data into agent-visible/output-visible context without access control, minimization, or user disclosure, which can enable prompt/context exfiltration and leakage of secrets, system state, or privileged operational instructions.
The script creates a compressed backup of workspace files that appear to include memory, context, agent instructions, and other potentially sensitive operational data, and stores it on disk under a predictable root-owned path. Even though this looks like a maintenance feature rather than malicious behavior, writing such archives without explicit consent, retention controls, or permission hardening increases the risk of sensitive data exposure if the host is later accessed, backed up elsewhere, or the archive is mishandled.
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
ws=Path('/root/.openclaw/workspace')
checks=[]
def exists(label, rel): checks.append((label, (ws/rel).exists()))
exists('brain skill', 'skills/brain-system/SKILL.md')
exists('brain state', 'skills/brain-system/state/brain-state.json')
exists('server authority', 'skills/server-body-ops/state/authority.json')
exists('pinned memory', 'memory/DO_NOT_FORGET.md')
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
ws=Path('/root/.openclaw/workspace')
checks=[]
def exists(label, rel): checks.append((label, (ws/rel).exists()))
exists('brain skill', 'skills/brain-system/SKILL.md')
exists('brain state', 'skills/brain-system/state/brain-state.json')
exists('server authority', 'skills/server-body-ops/state/authority.json')
exists('pinned memory', 'memory/DO_NOT_FORGET.md')
The script reads a PID from a workspace file and interpolates it directly into a bash -lc command. If an attacker can tamper with skills/brain-system/state/hot-reload.pid, they could inject shell metacharacters and execute arbitrary commands in the script's security context.
hot=False
if pidfile.exists():
pid=pidfile.read_text().strip()
hot=subprocess.run(['bash','-lc',f'kill -0 {pid}'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('hot reload running', hot))
cron=subprocess.run(['bash','-lc','crontab -l 2>/dev/null | grep -q OPENCLAW_BRAIN_SYSTEM'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('cron installed', cron))
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
pid=pidfile.read_text().strip()
hot=subprocess.run(['bash','-lc',f'kill -0 {pid}'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('hot reload running', hot))
cron=subprocess.run(['bash','-lc','crontab -l 2>/dev/null | grep -q OPENCLAW_BRAIN_SYSTEM'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('cron installed', cron))
score=sum(v for _,v in checks); total=len(checks)
print(f'brain_fullness={score}/{total} ({score/total*10:.1f}/10)')
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.
pid=pidfile.read_text().strip()
hot=subprocess.run(['bash','-lc',f'kill -0 {pid}'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('hot reload running', hot))
cron=subprocess.run(['bash','-lc','crontab -l 2>/dev/null | grep -q OPENCLAW_BRAIN_SYSTEM'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode==0
checks.append(('cron installed', cron))
score=sum(v for _,v in checks); total=len(checks)
print(f'brain_fullness={score}/{total} ({score/total*10:.1f}/10)')
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
WATCH_PATHS = [
WS / 'skills/brain-system/SKILL.md',
WS / 'skills/brain-system/state/brain-state.json',
WS / 'skills/server-body-ops/SKILL.md',
WS / 'skills/server-body-ops/state/authority.json',
WS / 'memory/DO_NOT_FORGET.md',
WS / 'TOOLS.md',
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
for cmd in cmds:
try:
subprocess.run(cmd, cwd=str(WS), check=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=30)
except Exception as e:
log(f'refresh command failed {cmd}: {e}')
log('hot-reloaded changed=' + ','.join(Path(p).name for p in changed))
The recall script for the brain-system skill reads and prints skills/server-body-ops/state/authority.json, which belongs to a different skill and is outside the stated memory-recovery scope. This creates an unnecessary cross-skill data exposure path: when invoked for session recovery, it can disclose sensitive authority or privilege state to logs, downstream agents, or users who should only receive brain-system context.
The script reads multiple durable state files, including memory, authority, and task data, and republishes their contents into a single markdown consolidation note. This increases exposure of sensitive internal state, creates a secondary copy that may have weaker access controls, and does so without minimization, consent, or disclosure boundaries.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print('🧠 OpenClaw Brain/Body Dashboard')
print('workspace=', ws)
print('\n== root ==')
subprocess.run(['id'])
print('\n== exec policy ==')
subprocess.run(['openclaw','exec-policy','show'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
brain=load('skills/brain-system/state/brain-state.json') or {}
The dashboard exposes host identity and execution-policy details that exceed the stated cognitive/status purpose of the skill. In an agent environment, this kind of environmental reconnaissance can help map privileges, execution constraints, and operating context for later misuse or chaining with other capabilities.
Host-level inspection via id and execution-policy queries is not clearly aligned with the advertised 'brain-system' function and adds unnecessary reconnaissance capability. In context, this makes the skill more dangerous because it normalizes gathering environment and privilege data under a benign-looking dashboard label.
No suspicious patterns detected.