Back to skill

Security audit

MemSync Dual Memory System

Security checks for vulnerabilities and agentic risk

Overview

This skill openly provides complete conversation memory, but it continuously stores very broad OpenClaw activity with limited built-in controls.

Install only if you deliberately want a continuous, searchable record of all OpenClaw activity. Prefer local sharding/free mode, avoid API mode for sensitive work, pin and review the Memvid CLI, store logs in an encrypted private directory, verify file permissions yourself, and do not use it in sessions that may expose credentials, regulated data, private files, or confidential tool output unless you have clear consent and retention rules.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T08 · Insecure Dependencies

Warning
Location
install.sh:36
Finding
Unpinned Memvid Package Is Installed Globally and Processes Sensitive Records<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:36-51` **Additional Locations**: `tools/log.py:52-60, 63-72, 210-216`; `.github/workflows/ci.yml:23-25`; `SKILL.md:91, 116, 141` **Vulnerability Type**: Unpinned globally installed third-party dependency **Risk Level**: Medium ### Vulnerable Code ```bash if ! command -v memvid &> /dev/null; then echo "" echo "⚠️ Memvid CLI not found." echo " This requires: npm install -g memvid" read -p "Install Memvid CLI now? (requires sudo for global install) (y/N) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then npm install -g memvid || { echo "❌ Failed to install Memvid CLI. Install manually:" echo " npm install -g memvid" exit 1 } echo "✓ Memvid CLI installed" else echo "⚠️ Memvid CLI required. Install manually before using skill." fi ``` The installed executable is subsequently trusted to process sensitive records: ```python _MEMVID_PATHS = [ "/usr/local/bin/memvid", "/usr/bin/memvid", os.path.expanduser("~/.npm-global/bin/memvid"), os.path.expanduser("~/.local/bin/memvid"), ] _DEFAULT_MEMVID = next((p for p in _MEMVID_PATHS if os.path.exists(p)), "memvid") MEMVID_BIN = os.environ.get("MEMVID_BIN", _DEFAULT_MEMVID) ``` ```python result = subprocess.run( cmd, capture_output=True, text=True, timeout=30 ) ``` ### Technical Analysis The installer executes `npm install -g memvid` without an exact version, package-lock file, or integrity verification. It therefore installs whichever release the registry resolves at installation time. The effective dependency can change after this Skill has been reviewed. Global npm installation also expands the potential impact beyond the project directory. Depending on the npm configuration, users may run this command with elevated privileges, which the installer explicitly anticipates by stating that sudo may be required. This depe ...[truncated 2017 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin Memvid to a reviewed exact version rather than using an unconstrained package: ```bash npm install --save-exact memvid@<reviewed-version> ``` 2. Install it project-locally rather than globally and invoke the binary from a controlled project path. 3. Commit a lockfile and use `npm ci` so dependency resolution is reproducible. 4. Verify package integrity against a trusted, published digest or signed release before installation. 5. Do not recommend sudo for npm installation. Configure a user-owned installation directory if a global CLI is unavoidable. 6. Review the package's transitive dependencies and npm lifecycle scripts before release. 7. Restrict the environment inherited by the Memvid subprocess to only the variables it requires. 8. Verify the executable's ownership, permissions, canonical path, and expected version before invoking it. 9. Update CI to install the same exact audited version used in production rather than the latest release. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
tools/log.py:168
Finding
Sensitive Conversation Log Is Created Without Enforced Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `tools/log.py:168-179` **Vulnerability Type**: Insecure plaintext data storage and access control **Risk Level**: Medium ### Vulnerable Code ```python def log_to_jsonl(log_entry: Dict) -> bool: """Append conversation turn to JSONL file.""" try: os.makedirs(os.path.dirname(LOG_PATH), exist_ok=True) with open(LOG_PATH, "a", encoding="utf-8") as f: f.write(json.dumps(log_entry, ensure_ascii=False) + "\n") f.flush() return True except Exception as e: print(f"[jsonl-logger error] {e}", file=sys.stderr) return False ``` ### Technical Analysis The Skill intentionally records broad and potentially sensitive OpenClaw activity in a plaintext JSONL file. The file is opened with Python's standard append mode, so the permissions assigned to a newly created file depend on the process umask. The parent directory is similarly created without an explicit restrictive mode. The documentation recommends manually applying `chmod 600`, but the implementation does not enforce or verify this requirement. Under a permissive umask, the resulting file may be readable by other local users. The implementation also does not verify that the destination is a regular file owned by the expected user. Consequently, unsafe pre-existing files or symbolic links are not rejected. This access is necessary only to the extent that the logger must write its own data file. Read access for unrelated local accounts and writes through an attacker-controlled link exceed the minimum privileges required for conversation logging. ### Attack Path 1. OpenClaw starts the logger under an environment with a permissive umask, or the configured log path already has unsafe permissions. 2. `log_to_jsonl` creates or appends to `conversation_log.jsonl` without enforcing mode `0600`. 3. The logger continuously writes user messages, assistant output, tool results, commands, and system ev ...[truncated 1133 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the workspace directory with mode `0700` and verify its ownership: ```python os.makedirs(parent, mode=0o700, exist_ok=True) os.chmod(parent, 0o700) ``` 2. Create the log using low-level flags that enforce mode `0600`: ```python fd = os.open( LOG_PATH, os.O_WRONLY | os.O_CREAT | os.O_APPEND | os.O_NOFOLLOW, 0o600, ) with os.fdopen(fd, "a", encoding="utf-8") as f: ... ``` 3. Before appending, use `os.fstat` to confirm that the opened destination is a regular file owned by the current effective user. 4. Reject symbolic links and paths whose parent directories are writable by untrusted users. 5. Correct the permissions of existing log files or fail safely with a clear error if they are insecure. 6. Consider encryption at rest for deployments that retain credentials, proprietary source code, or regulated data. 7. Add configurable redaction rules for tokens, passwords, authorization headers, and other high-risk fields. 8. Implement retention limits and secure deletion procedures rather than retaining all records indefinitely. 9. Add automated tests that assert `0600` file and `0700` directory permissions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
tools/log.py:181
Finding
Failed Memvid Operations Leave Plaintext Conversation Records in Temporary Files<![CDATA[ ## Vulnerability Details **File Location**: `tools/log.py:181-224` **Vulnerability Type**: Unsafe temporary-file lifecycle and sensitive-data residue **Risk Level**: Medium ### Vulnerable Code ```python def log_to_memvid(log_entry: Dict) -> bool: """Append conversation turn to Memvid .mv2 file.""" try: ensure_memory_file() # Create temp file with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(log_entry, f, ensure_ascii=False, indent=2) temp_path = f.name # Build metadata title = get_frame_title(log_entry) ts = log_entry.get("timestamp", dt.now(timezone.utc).isoformat()) date_only = ts.split('T')[0] if 'T' in ts else ts[:10] tags = build_tags(log_entry) # Build command with multiple --tag arguments cmd = [ MEMVID_BIN, "put", MEMVID_PATH, "--title", title, "--timestamp", date_only, "--input", temp_path ] for tag in tags: cmd.extend(["--tag", tag]) # Call memvid put result = subprocess.run( cmd, capture_output=True, text=True, timeout=30 ) os.unlink(temp_path) return result.returncode == 0 except Exception: return False ``` ### Technical Analysis Each Memvid write serializes the complete `log_entry` to a named plaintext JSON file with `delete=False`. The file is deleted only after `subprocess.run` returns normally. Cleanup is not placed in a `finally` block. If process creation fails, Memvid hangs beyond the 30-second timeout, the subprocess call raises another exception, or deletion itself is interrupted, execution reaches the broad exception handler and returns `False` without removing the temporary file. Because exceptions are silen ...[truncated 1825 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Initialize `temp_path` before the operation and always delete it in a `finally` block: ```python temp_path = None try: with tempfile.NamedTemporaryFile( mode="w", suffix=".json", delete=False, encoding="utf-8", ) as f: json.dump(log_entry, f, ensure_ascii=False) temp_path = f.name result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) return result.returncode == 0 finally: if temp_path: try: os.unlink(temp_path) except FileNotFoundError: pass ``` 2. Prefer passing the serialized record through standard input if the Memvid CLI supports it, eliminating plaintext disk staging. 3. If disk staging is mandatory, create a private temporary directory with mode `0700` and verify that each temporary file has mode `0600`. 4. Log sanitized failure information so operators know cleanup or Memvid processing failed; do not silently suppress all exceptions. 5. Add startup cleanup for stale files created by this specific logger, using a private directory and strict filename/ownership checks. 6. Add tests that force subprocess launch failures and timeouts, then verify that no temporary files remain. 7. Apply data minimization or redaction before serializing records to reduce the sensitivity of unavoidable temporary data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (30)

Ssd 3

High
Confidence
97% confidence
Finding
The skill is described as 'always on' and capturing 'everything,' including user messages, assistant responses, sub-agent conversations, tool executions, and system events. This is dangerous because agent and tool traces commonly contain highly sensitive data such as API keys, authentication headers, local file contents, internal prompts, and private user information, all of which become persistently stored and searchable.

Ssd 3

High
Confidence
96% confidence
Finding
The README explicitly states that every user message and all AI, tool, and system outputs are saved and searchable, which normalizes comprehensive retention of private interaction data. Searchable long-term storage increases blast radius because any later compromise, misuse, or unauthorized access can expose historical sensitive content at scale.

Credential Access

High
Category
Privilege Escalation
Content
**Cost:** $59-299/month via [memvid.com](https://memvid.com)

```bash
# 1. Get API key from memvid.com ($59/month for 1GB, $299 for 25GB)
export MEMVID_API_KEY="your_api_key_here"
export MEMVID_MODE="single"
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Ssd 3

High
Confidence
97% confidence
Finding
The warning confirms that all OpenClaw activity is captured, including sub-agent conversations, tool outputs, and system events, and that data may be sent to a cloud service when API mode is used. This materially increases risk because highly sensitive data may leave the local environment and be retained externally, potentially violating least-privilege, privacy, or compliance expectations.

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill explicitly states it captures every user message, assistant response, sub-agent conversation, tool execution, and system event, but provides no warning, consent flow, redaction guidance, or limits on sensitive-data collection. This creates a real privacy and security risk because credentials, personal data, proprietary prompts, command output, and other secrets may be persistently stored and later exposed through backup files or semantic search.

Ssd 3

High
Confidence
99% confidence
Finding
The instructions direct comprehensive retention of all conversation content and tool activity for long-term memory, including sub-agent and system events, which materially increases the blast radius of any compromise or misuse of the memory files. In this context, the skill is more dangerous because it is positioned as an always-on logging layer for AI-agent activity, so it is likely to ingest sensitive operational data at scale without boundaries or filtering.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The README promotes exhaustive, always-on capture of conversations, sub-agent chatter, tool output, and system events without any privacy warning, consent guidance, retention limits, or redaction controls. In an agent skill context, this can lead operators to deploy broad logging that persistently stores secrets, personal data, credentials, and other sensitive content that users may not expect to be retained and made searchable.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Use **Free/Sharding mode** to keep data local (no API key needed)
- Change default paths to encrypted locations
- Review `tools/log.py` before installing to understand exactly what gets logged
- File permissions: restrict access to log files (`chmod 600`)

**This skill is for users who want complete conversation memory and accept the privacy trade-offs.**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- Use **Free/Sharding mode** to keep data local (no API key needed)
- Change default paths to encrypted locations
- Review `tools/log.py` before installing to understand exactly what gets logged
- File permissions: restrict access to log files (`chmod 600`)

**This skill is for users who want complete conversation memory and accept the privacy trade-offs.**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
export MEMVID_API_KEY="your_key_here"
export MEMVID_MODE="single"

# Create memory
memvid create ~/anthony_memory.mv2

# Start OpenClaw - everything logs to one searchable file
Confidence
97% confidence
Finding
The skill openly advertises always-on capture of user messages, assistant responses, sub-agent conversations, tool outputs, and system events into persistent local files and optionally a third-party service. In this context, session persistence is the core behavior, and it is dangerous because it can retain secrets, tokens, private file contents, and sensitive tool output far beyond the active session, materially increasing confidentiality and compliance risk.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Add to /etc/environment (requires sudo)
sudo tee -a /etc/environment << 'EOF'
MEMVID_MODE="monthly"
MEMVID_PATH="/home/YOUR_USERNAME/.openclaw/workspace/anthony_memory_2026-02.mv2"
JSONL_LOG_PATH="/home/YOUR_USERNAME/.openclaw/workspace/conversation_log.jsonl"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Add to /etc/environment (requires sudo)
sudo tee -a /etc/environment << 'EOF'
MEMVID_MODE="monthly"
MEMVID_PATH="/home/YOUR_USERNAME/.openclaw/workspace/anthony_memory_2026-02.mv2"
JSONL_LOG_PATH="/home/YOUR_USERNAME/.openclaw/workspace/conversation_log.jsonl"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Add to /etc/environment (requires sudo)
sudo tee -a /etc/environment << 'EOF'
MEMVID_MODE="monthly"
MEMVID_PATH="/home/YOUR_USERNAME/.openclaw/workspace/anthony_memory_2026-02.mv2"
JSONL_LOG_PATH="/home/YOUR_USERNAME/.openclaw/workspace/conversation_log.jsonl"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
ls ~/.openclaw/hooks/unified-logger/
# Should show: handler.js (NOT handler.ts)

# If you have handler.ts, rename/create handler.js instead
```

**Correct hook structure:**
Confidence
92% confidence
Finding
The documented hook structure under ~/.openclaw/hooks/unified-logger/ shows the logger is installed as a persistent managed hook that runs automatically with OpenClaw. In context, this persistence materially increases risk because the comprehensive logging behavior becomes continuous and ambient, making accidental long-term capture of sensitive conversations and tool results more likely.

Session Persistence

Medium
Category
Rogue Agent
Content
git clone https://github.com/stackBlock/openclaw-memvid-logger.git
cp -r openclaw-memvid-logger ~/.openclaw/workspace/skills/

# 3. Create unified memory file
memvid create ~/memory.mv2

# 4. Start OpenClaw - everything logs to one searchable file
Confidence
95% confidence
Finding
This skill is explicitly designed for persistent session logging and long-term retention of all conversations, sub-agent chatter, tool outputs, and system events. In security terms, that creates a high-risk data aggregation point: sensitive prompts, file contents, commands, tokens, and personal data may be retained indefinitely and become available to anyone who can access the local files or configured backend.

Ssd 3

Medium
Confidence
92% confidence
Finding
The skill is designed to capture full conversation context and retain it long-term, which creates a genuine sensitive-data collection risk. Even if intended as a memory/logging feature, storing comprehensive user messages, assistant outputs, tool outputs, and system activity can expose secrets, personal data, and internal workflow details if logs are accessed, mishandled, or later uploaded.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
echo ""
    echo "⚠️  Memvid CLI not found."
    echo "   This requires: npm install -g memvid"
    read -p "Install Memvid CLI now? (requires sudo for global install) (y/N) " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        npm install -g memvid || {
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
echo ""
    echo "⚠️  Memvid CLI not found."
    echo "   This requires: npm install -g memvid"
    read -p "Install Memvid CLI now? (requires sudo for global install) (y/N) " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        npm install -g memvid || {
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The message_out hook is configured to run after each assistant response with no stated scope limits, filtering, consent boundary, or sensitivity exclusions. In a memory/logging skill, that broad trigger can cause systematic capture of all assistant outputs, including secrets, credentials, personal data, or privileged workflow content, making over-collection and downstream exposure a real security risk rather than just a documentation issue.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The module is designed to persist every conversation turn, including potentially sensitive user inputs and tool outputs, without any visible consent, notice, minimization, or opt-in control. In an agent context, this can capture credentials, personal data, proprietary prompts, and operational secrets into long-lived local storage unexpectedly.

Ssd 3

Medium
Confidence
94% confidence
Finding
The design explicitly states that it stores all conversation content, tool calls, agent spawns, and related metadata in persistent searchable memory. In a multi-agent or tool-using system, that creates a broad and durable data-retention surface for secrets, personal data, internal prompts, and execution artifacts, magnifying harm if the host is compromised or logs are mishandled.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""Create memory file for current month if it doesn't exist."""
    if not os.path.exists(MEMVID_PATH):
        try:
            subprocess.run(
                [MEMVID_BIN, "create", MEMVID_PATH],
                capture_output=True,
                timeout=30
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Tainted flow: 'MEMVID_BIN' from os.environ.get (line 60, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
"""Create memory file for current month if it doesn't exist."""
    if not os.path.exists(MEMVID_PATH):
        try:
            subprocess.run(
                [MEMVID_BIN, "create", MEMVID_PATH],
                capture_output=True,
                timeout=30
Confidence
95% confidence
Finding
MEMVID_BIN is sourced from an environment variable and then executed during memory-file creation without validation. If an attacker can set or tamper with that environment variable, they can achieve arbitrary code execution as soon as the logger initializes or rotates storage files.

Tainted flow: 'LOG_PATH' from os.environ.get (line 34, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"""Append conversation turn to JSONL file."""
    try:
        os.makedirs(os.path.dirname(LOG_PATH), exist_ok=True)
        with open(LOG_PATH, "a", encoding="utf-8") as f:
            f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")
            f.flush()
        return True
Confidence
86% confidence
Finding
LOG_PATH is taken from an environment variable and used for file creation/appending without validation. An attacker who can control the environment could redirect logs to arbitrary writable paths, causing unintended file modification, overwriting of sensitive application data, or leakage into locations with weaker protections.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code exports conversation data to an external tool process, broadening the trust boundary beyond the application itself. Even if memvid is local, forwarding complete conversation records and metadata to another binary increases the risk of unintended disclosure, secondary storage, and misuse without any apparent warning or policy gate.

Static analysis

No suspicious patterns detected.