Back to skill

Security audit

Savemaintenance

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent local memory-maintenance tool, but it needs Review because it can rewrite saved memory data and its snapshot tag handling can write sensitive memory copies outside the intended snapshot directory.

Install only if you are comfortable with a local maintenance tool that reads, copies, and rewrites OpenClaw saved-memory files. Run dry mode first, avoid custom snapshot tags containing slashes or absolute paths, inspect generated backups/snapshots for sensitive content, and treat this version as needing fixes before relying on restore or full reconciliation.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
snapshot.py:34
Finding

Snapshot Tag Path Traversal Allows Memory Artifacts to Be Written Outside the Snapshot Directory

Content
View full analysis
2 and sys.argv[1] == "take": take_snapshot(sys.argv[2] if len(sys.argv) > 2 else None) ``` Files are subsequently copied to the derived directory: ```python if CONV_LOG.exists(): shutil.copy2(CONV_LOG, snap_dir / "conversation-log.md") if TOPIC_PATH.exists(): shutil.copy2(TOPIC_PATH, snap_dir / "topic-index.json") if STUB_PATH.exists(): shutil.copy2(STUB_PATH, snap_dir / "stub-index.md") if FTS5_DB.exists(): db_dest = snap_dir / "memory-index.db" shutil.copy2(FTS5_DB, db_dest) ``` ### Technical Analysis The `tag` value is used as a path component without validation or containment checking. Python's `pathlib` permits both traversal components such as `../` and absolute paths: - A tag such as `../../exported-memory` escapes `SNAPSHOT_DIR`. - An absolute tag such as `/tmp/exported-memory` causes the intended base directory to be discarded. - `mkdir(parents=True, exist_ok=True)` creates the attacker-selected directory hierarchy. - `shutil.copy2()` writes fixed-name conversation and index artifacts into that location and may overwrite existing same-named files. This is a local path traversal vulnerability. Exploitation requires the ability to invoke the script with a chosen snapshot tag, directly or through another component that exposes this argument. ### Attack Path 1. An attacker or untrusted caller obtains the ability to supply the argument to `snapshot.py take`. ...[truncated 1421 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
full-reconcile.py:44
Finding

Undefined Configuration Variable Prevents the Reconciliation Pipeline from Starting

Content
View full analysis
Remediation
View remediation
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented purpose focuses on reconciliation, but the skill also advertises archival snapshot features and references extra resources outside that scope. Overbroad or inaccurate behavioral claims reduce transparency and can hide state-changing operations from users who only intended to run a repair workflow.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose focuses on reconciliation, but the skill also advertises archival snapshot features and references extra resources outside that scope. Overbroad or inaccurate behavioral claims reduce transparency and can hide state-changing operations from users who only intended to run a repair workflow.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares no explicit tool scope or permissions even though it clearly performs shell execution and reads/writes persistent files under the user's workspace. That omission weakens review and containment because an operator cannot easily tell, from the manifest alone, that the skill can modify memory state and invoke local scripts.

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

md
install:
      - id: setup
        kind: setup
        label: "Create savemaintenance directory"
        run: "mkdir -p ~/.openclaw/workspace/savemaintenance && mkdir -p ~/.openclaw/workspace/savemaintenance/backups && mkdir -p ~/.openclaw/workspace/savemaintenance/snapshots"
      - id: check-prereqs
        kind: check

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill describes reconciliation steps that remove log entries, rewrite indexes, and alter memory state, but it does not prominently warn that these actions are destructive or semi-destructive. A user may run it expecting harmless maintenance and unintentionally lose references or overwrite state, especially if dry-run is skipped.

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 · full-reconcile.py (reported line 7)May include surrounding context.

python
Usage:
  python3 full-reconcile.py          # Full run: backup → reconcile → rebuild → audit
  python3 full-reconcile.py --dry    # Dry run: show what would change, don't write
  python3 full-reconcile.py --step log   # Run a single step

Steps (run consecutively in full mode):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code performs a file write to conversation-log.md after automatically removing entries for files no longer on disk and adding orphan entries. Although the module docstring describes the pipeline, the live write path lacks any runtime confirmation before modifying user data, which is a safety-relevant operation for a maintenance script.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · full-reconcile.py (reported line 217)May include surrounding context.

python
log("Rebuilding FTS5 index + stub-index.md...")
    
    if not dry_run:
        result = subprocess.run(
            ["python3", str(INDEX_SCRIPT), "build"],
            cwd=str(WORKSPACE),
            capture_output=True, text=True, timeout=60

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The maintenance script executes separate Python programs from disk, which means its effective trust boundary includes whatever code is present at those paths at runtime. If an attacker can replace or tamper with memory-index.py or memory-audit.py in the workspace, running this maintenance command becomes an indirect arbitrary code-execution path.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · full-reconcile.py (reported line 249)May include surrounding context.

python
return
    
    log("Running memory audit...")
    result = subprocess.run(
        ["python3", str(AUDIT_SCRIPT)],
        capture_output=True, text=True, timeout=30
    )

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes this skill as performing deterministic reconciliation of conversation-log.md, the FTS5 index, and saved conversations, but this file implements a separate backup/snapshot manager with archival and listing functionality. Creating persistent snapshots of multiple files and inventories is a materially different operational scope than a one-shot fix or maintenance reconciliation run.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script copies conversation logs, topic metadata, and the memory index into snapshot directories without any access-control hardening, encryption, retention controls, or user-facing warning about the sensitivity of that data. In this skill context, those files likely contain private conversation history and memory artifacts, so silent archival increases the risk of unintended disclosure from local compromise, backups, or shared environments.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · snapshot.py (reported line 109)May include surrounding context.

python
def has_command(cmd):
    """Check if a command exists."""
    return subprocess.run(["which", cmd], capture_output=True).returncode == 0


if __name__ == "__main__":

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The docstring says the function backs up both conversation-log.md and topic-index.json, implying preservation of those files as such. However, the destination path is always constructed with a .md suffix, so the JSON backup is not stored with its original extension, contradicting the stated behavior/documentation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The audit step launches another script via subprocess, which is a shell/process execution operation covered by the warning rule for code files. While the file-level documentation mentions that audit runs in the full pipeline, this function does not present any step-specific warning or confirmation when invoking external code.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest specifically names conversation-log.md, the FTS5 index, and saved conversations as the reconciliation scope. This code additionally captures topic-index.json and stub-index.md, extending behavior beyond the described artifacts without explanation in the manifest or module documentation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.