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## 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
## 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## 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
## 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
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Daily Memory
```bash
# Create today's memory file with template
~/.openclaw/skills/minimal-memory/scripts/daily.sh

# Add entry with auto-tagging
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.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "- " >> "$TODAY_FILE"
fi

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

# Find the section and add entry after the header
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.

Static analysis

No suspicious patterns detected.