Back to skill

Security audit

Minimal Memory

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local memory-management skill with some implementation and scoping cautions, but no evidence of hidden, destructive, or deceptive behavior.

Install only if you want an agent to maintain persistent local memory files. Avoid storing secrets, credentials, private personal details, or untrusted copied text without review, and review entries before promoting them into long-term MEMORY.md.

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 (2)

T02 · Agent Memory Poisoning

Warning
Location
scripts/add.sh:24
Finding

Persistent Agent Memory Poisoning Through Unvalidated Multiline Entries

Content
View full analysis

Vulnerability Details

File Location: scripts/add.sh, lines 24-25 and 64-86
Vulnerability Type: Persistent memory-content injection
Risk Level: Medium

Vulnerable Code

bash
CATEGORY=$(echo "$1" | tr '[:lower:]' '[:upper:]')
ENTRY="$2"

# Add entry to the file using sed
TEMP_FILE=$(mktemp)

# Find the section and add entry after the header
awk -v cat="$CATEGORY" -v entry="$ENTRY" '
    BEGIN { in_section = 0 }
    /^## \['"$CATEGORY"'\]/ {
        print
        in_section = 1
        next
    }
    in_section && /^## / {
        in_section = 0
    }
    in_section && /^- $/ {
        print "- ["cat"] "entry
        in_section = 0
        next
    }
    { print }
' "$TODAY_FILE" > "$TEMP_FILE"

mv "$TEMP_FILE" "$TODAY_FILE"

Technical Analysis

The entry supplied through the second command-line argument is assigned directly to ENTRY and passed to awk without structural validation. Although shell quoting prevents direct shell-command injection, it does not prevent newline characters, Markdown headings, fabricated categories, or instruction-like content from being stored.

When entry contains newline characters, the print operation emits those newlines into the daily memory file. An attacker-controlled entry can consequently escape the intended Markdown list item and create arbitrary additional sections or text. For example, an entry could add a fabricated heading followed by instructions that appear to be trusted persistent memory.

This is especially relevant because the Skill is explicitly designed to make future Agent sessions search, review, and potentially promote daily entries into the long-term MEMORY.md file. The injected content therefore crosses a persistence boundary and may influence subsequent Agent decisions.

Attack Path

  1. An attacker causes untrusted content to be supplied as the entry argument to add.sh, directl ...[truncated 1291 chars]
Remediation
View remediation

Remediation Suggestions

  1. Reject entries containing carriage returns or newline characters unless multiline storage is explicitly required.

  2. Normalize every entry to a single logical line before writing it:

    bash
    ENTRY=${2//$'\r'/ }
    ENTRY=${ENTRY//$'\n'/ }
    
  3. Enforce a reasonable maximum entry length to reduce abuse and accidental memory corruption.

  4. Escape or encode Markdown control characters if entries must remain data rather than document structure.

  5. Store memory in a structured format such as JSON with explicit fields for category, date, and content, then generate Markdown only for display.

  6. Treat recalled memory as untrusted data rather than executable Agent instructions.

  7. Require explicit review and confirmation before promoting daily content into long-term MEMORY.md.

  8. Validate that generated files contain only the expected headings and entry structure before replacing the original file.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/search.sh:111
Finding

Grep Option Injection Through an Untrusted Search Query

Content
View full analysis

Vulnerability Details

File Location: scripts/search.sh, lines 111-114
Vulnerability Type: Command option injection and unsafe pathname expansion
Risk Level: Low

Vulnerable Code

bash
# Perform search
if [[ -n "$FILES_TO_SEARCH" ]]; then
    RESULTS=$(grep -r -i -n "$QUERY" $FILES_TO_SEARCH 2>/dev/null | grep -i "$PATTERN" | head -20)

The unsafe command is constructed from file paths accumulated earlier as a space-delimited string:

bash
FILES_TO_SEARCH="$WORKSPACE/MEMORY.md"
...
FILES_TO_SEARCH="$FILES_TO_SEARCH $FILE"
...
FILES_TO_SEARCH="$FILES_TO_SEARCH $MEMORY_DIR/*.md"

Technical Analysis

The user-controlled QUERY is passed to grep without a preceding -- option terminator. Quoting protects the value from shell word splitting, but it does not stop grep from interpreting a value beginning with - as a command-line option.

Depending on the installed grep implementation, option-shaped values such as --file=PATH can alter how patterns are sourced, while other options can change matching behavior, consume resources, or cause the search to fail. This is argument or option injection rather than shell-command injection: shell metacharacters inside QUERY are not executed by this code.

In addition, $FILES_TO_SEARCH is deliberately expanded without quotes. Consequently, workspace or memory paths containing spaces, tabs, wildcard characters, or leading hyphens may be split or interpreted incorrectly. This can change which files are searched and can cause unreliable behavior.

Attack Path

  1. An attacker or untrusted caller supplies a query beginning with a hyphen.
  2. The argument parser stores that value in QUERY.
  3. The script invokes grep without an option terminator.
  4. grep interprets the query as an option instead of as the intended search pattern.
  5. The attacker modifies search behavior, triggers errors or excessive processing, or causes ...[truncated 1013 chars]
Remediation
View remediation

Remediation Suggestions

  1. Insert the -- option terminator before the untrusted query:

    bash
    grep -r -i -n -- "$QUERY"
    
  2. Use fixed-string matching if regular-expression searches are not required:

    bash
    grep -r -F -i -n -- "$QUERY"
    
  3. Store filenames in a Bash array instead of a space-delimited string:

    bash
    files_to_search=()
    
    [[ -f "$WORKSPACE/MEMORY.md" ]] &&
        files_to_search+=("$WORKSPACE/MEMORY.md")
    
    [[ -f "$FILE" ]] &&
        files_to_search+=("$FILE")
    
    RESULTS=$(
        grep -i -n -- "$QUERY" "${files_to_search[@]}" 2>/dev/null |
        grep -i -- "$PATTERN" |
        head -20
    )
    
  4. Use nullglob or find with null-delimited output when collecting all daily files, rather than embedding an unresolved glob in a string.

  5. Validate --recent as a bounded positive integer before using it in arithmetic or seq, preventing malformed input and excessive iteration.

  6. Add regression tests for queries beginning with - and for workspace paths containing spaces, wildcard characters, and leading hyphens.

Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger description is broad enough to activate on ordinary discussion about memory, organization, or remembering, which can cause the skill to run outside its intended scope. Over-broad activation increases the chance of unintended persistence behaviors and exposes users to unnecessary memory-handling logic during normal conversation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill explicitly instructs creation of daily memory files and adding entries, which establishes session persistence by storing conversational or operational data across interactions. Even though this is the skill's purpose, persistent storage can retain sensitive, unnecessary, or user-unapproved information, making accidental data retention and later misuse more likely.

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

Daily Memory

bash
# Create today's memory file with template
~/.openclaw/skills/minimal-memory/scripts/daily.sh

# Add entry with auto-tagging

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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/add.sh (reported line 64)May include surrounding context.

sh
echo "- " >> "$TODAY_FILE"
fi

# Add entry to the file using sed
TEMP_FILE=$(mktemp)

# Find the section and add entry after the header

Static analysis

No suspicious patterns detected.