Back to skill

Security audit

ClawForage Prompt Optimizer

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-aligned but needs review because it reads private transcript history more broadly than described and stores a derived report.

Review before installing. This skill can read your OpenClaw conversation history and SOUL.md, and the current script may process all available session transcripts despite the one-day invocation. Use it only if you are comfortable exposing that local history to the active agent context, and prefer a version that enforces date filtering, redacts sensitive text, and asks before writing reports.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/extract-transcripts.sh:8
Finding

Transcript extraction ignores the requested time limit and exposes complete conversation history

Content
View full analysis

Vulnerability Details

File Location: scripts/extract-transcripts.sh, lines 8-28
Vulnerability Type: Excessive access to sensitive transcript data
Risk Level: Medium

Vulnerable Code

bash
INPUT="${1:?Usage: extract-transcripts.sh <jsonl_file_or_dir> [days_back]}"
DAYS_BACK="${2:-7}"

# Collect JSONL files
FILES=()
if [ -d "$INPUT" ]; then
  while IFS= read -r f; do FILES+=("$f"); done < <(find "$INPUT" -name "*.jsonl" -type f)
else
  FILES=("$INPUT")
fi

if [ ${#FILES[@]} -eq 0 ]; then
  echo "No JSONL files found in $INPUT"
  exit 1
fi

# Read all files into a single stream
ALL_MESSAGES=""
for FILE in "${FILES[@]}"; do
  ALL_MESSAGES+=$(cat "$FILE")
  ALL_MESSAGES+=$'\n'
done

The resulting data is later emitted as complete message text:

bash
echo "$ALL_MESSAGES" | jq -r '
  select(.type == "message" and .message.role == "user")
  | .timestamp + " | " + (.message.content[] | select(.type == "text") | .text)
' 2>/dev/null | sort || true

Technical Analysis

The script accepts a days_back argument and assigns it to DAYS_BACK, but never uses that variable to filter files or individual JSONL records. When given a directory, it recursively discovers every .jsonl file and concatenates all of their contents into ALL_MESSAGES.

This behavior conflicts with the documented invocation in SKILL.md, which passes 1 to request transcripts from the past day. Instead, the script processes every transcript available under the supplied directory. It then outputs full user-message text rather than a minimized or redacted summary.

Conversation transcripts can contain credentials, access tokens, personal information, proprietary data, or unrelated historical conversations. Although the project contains no mechanism that transmits this data to an external service, the unnecessarily broad data set is exposed to the invoking agent and its active mo ...[truncated 1340 chars]

Remediation
View remediation

Remediation Suggestions

  1. Enforce DAYS_BACK by calculating a trusted cutoff timestamp and filtering each JSONL record by its parsed timestamp before any content is aggregated or displayed.
  2. Validate that DAYS_BACK is a non-negative integer and reject malformed values.
  3. Prefer record-level timestamp filtering over file modification-time filtering, because a transcript file may contain records from multiple dates.
  4. Avoid storing the complete transcript corpus in a shell variable. Stream records through jq to reduce unnecessary retention and memory exposure.
  5. Emit local aggregates, hashes, truncated descriptions, or redacted pattern summaries instead of complete user messages.
  6. Remove or mask likely credentials, tokens, email addresses, and other sensitive values before output reaches the agent context.
  7. Restrict accepted input to the intended sessions directory, or require explicit confirmation when another directory is supplied.
  8. Add automated tests proving that records older than the requested cutoff are excluded.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
SKILL.md:30
Finding

Persistent agent configuration is read without data minimization or explicit confirmation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 30-34
Vulnerability Type: Unrestricted access to persistent agent configuration
Risk Level: Low

Vulnerable Code

bash
## Step 2: Read Current SOUL.md

```bash
cat memory/SOUL.md 2>/dev/null || echo "No SOUL.md found"
text

### Technical Analysis

The skill instructs the agent to read the complete `memory/SOUL.md` file. Access to agent preferences is relevant to producing configuration suggestions, but the implementation does not request explicit confirmation, select only necessary sections, limit file size, or redact sensitive values.

Persistent agent configuration may contain private preferences, operational instructions, internal paths, identifiers, or secrets placed there by a user. Reading the entire file makes all such content available in the current agent and model context even when only a subset is required for optimization.

This is a least-privilege and data-minimization weakness rather than an operating-system privilege escalation. The audited project does not modify `SOUL.md`, establish persistence through it, or transmit its contents to a remote endpoint.

### Attack Path

1. The user invokes the optimization skill.
2. The skill follows its documented workflow and executes `cat memory/SOUL.md`.
3. Every readable value in the file enters the current agent context.
4. Sensitive or unrelated configuration content can consequently influence or appear in generated analysis and reports.

Exploitation requires sensitive information to already exist in `SOUL.md` and remains bounded by the invoking process's existing file permissions.

### Impact Assessment

The exposed scope is the complete readable content of `memory/SOUL.md`. This may disclose private preferences, internal configuration, or secrets to the active model context. The skill obtains no additional system permissions, does not write persistent rules, and contains no id
...[truncated 39 chars]
Remediation
View remediation

Remediation Suggestions

  1. Request explicit user consent before reading persistent agent configuration.
  2. Ask the user to provide or approve only the sections required for optimization instead of reading the complete file.
  3. Add a documented rule prohibiting storage of credentials, tokens, private keys, and similar secrets in SOUL.md.
  4. Apply secret-pattern redaction before configuration content is included in analysis or model context.
  5. Impose a reasonable file-size limit and reject symbolic links or unexpected file types where the runtime permits such validation.
  6. Ensure generated reports contain only summarized configuration recommendations and never reproduce sensitive source values.
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code does partially align with the transcript-analysis portion of the description because it parses conversation transcripts and identifies simple patterns such as repeated questions, tool usage, failures, and costs. However, the declared purpose promises higher-level outcomes that are not implemented here: there is nothing that suggests SOUL.md improvements or recommends skills. It also claims to run daily, but the supplied code is only a manual command-line extraction script with no scheduling or trigger logic. Additionally, the description declares no permissions, while the script reads transcript files from disk, which is an access pattern not reflected in the declaration. Overall, the actual behavior is a narrower transcript summarization utility rather than the fuller daily advisory analyzer described.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear mismatch between the declared purpose and the actual code. The description claims an analytical skill that processes conversation transcripts and produces insights and recommendations. The supplied code does none of that; it only checks whether a markdown report file contains required sections such as 'Repeated Patterns', 'SOUL.md Suggestions', and 'Recommended Skills'. Its primary purpose is report validation, not transcript analysis or recommendation generation. The presence of those section names aligns only superficially with the description's output categories, but the script neither computes nor derives any content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill directs access to the user's conversation transcript directory and creates a new file under memory/optimization without requiring an upfront warning or explicit consent at runtime. Because transcripts can contain sensitive prompts, secrets, or personal data, silently analyzing history and persisting derivative summaries increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.