Back to skill

Security audit

Session Cleaner

Security checks for vulnerabilities and agentic risk

Overview

This skill performs the session cleanup it advertises, but users should dry-run it first because its file classification and backup handling are imperfect.

Run the skill with --dry-run before allowing it to move files, and consider making a separate backup of important session transcripts. The behavior is not hidden or unrelated, but recovery is not guaranteed if filenames collide or if the heuristic parser picks the wrong active or group session.

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
scripts/clean-sessions.sh:85
Finding
Backup filename collisions can overwrite previously archived sessions## Vulnerability Details **File Location**: `scripts/clean-sessions.sh:85-86` **Vulnerability Type**: Unsafe file replacement **Risk Level**: Medium ```bash mkdir -p "$BACKUP_DIR" mv "$f" "$BACKUP_DIR/" ``` ### Technical Analysis The script moves session files into a shared backup directory without checking whether the destination filename already exists. Standard `mv` behavior can replace an existing destination file with the same basename. This violates the documented guarantee that moved session files remain recoverable. The operation also lacks collision-resistant naming, a no-clobber option, and post-move integrity verification. ### Attack Path 1. A session file is moved into `sessions/backup/`. 2. A new active-directory session file is subsequently created or restored with the same basename. 3. The cleanup script classifies the new file as stale. 4. The script runs `mv "$f" "$BACKUP_DIR/"`. 5. Depending on the platform's `mv` behavior and filesystem conditions, the existing backup is replaced by the newer file. 6. The prior transcript can no longer be recovered from the backup directory. Exploitation requires the ability to cause or influence a same-named session file in the sessions directory. No privilege escalation is obtained. ### Impact Assessment The impact is limited to files accessible under the invoking user's OpenClaw session directory. A collision can cause permanent loss of an older archived transcript, undermine recovery guarantees, and remove historical session records that may be needed for operational recovery or investigation. The issue does not grant additional system privileges or network access.
Remediation
## Remediation Suggestions - Use collision-resistant destination names containing a timestamp or UUID. - Check destination existence before moving and fail safely on collisions. - Use no-clobber semantics such as `mv -n` where supported, while checking the result because behavior varies by platform. - Prefer an explicit destination path rather than moving only to a directory. - Verify that the destination file exists and matches the source size or checksum before reporting success. - Preserve restrictive permissions on the backup directory and archived files. - Add tests covering repeated cleanup of files with identical basenames.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/clean-sessions.sh:18
Finding
Heuristic transcript parsing can misclassify active and group sessions## Vulnerability Details **File Location**: `scripts/clean-sessions.sh:18-50` **Vulnerability Type**: Insecure input classification and fail-open fallback **Risk Level**: Medium ```bash find_current_main() { local latest="" local latest_mtime=0 for f in "$SESSIONS_DIR"/*.jsonl; do [ -f "$f" ] || continue if grep -q '"sessionKey":"agent:main:main"' "$f" 2>/dev/null; then local mtime mtime=$(stat -c '%Y' "$f" 2>/dev/null || stat -f '%m' "$f" 2>/dev/null) if (( mtime > latest_mtime )); then latest_mtime=$mtime latest="$f" fi fi done # Fallback: most recently modified .jsonl with "to":"user:" pattern if [ -z "$latest" ]; then latest=$(ls -t "$SESSIONS_DIR"/*.jsonl 2>/dev/null | head -1) fi echo "$latest" } is_group_session() { local f="$1" # Check if target address contains oc_ (group chat ID) local to to=$(grep -o '"to":"[^"]*"' "$f" 2>/dev/null | head -1 | cut -d'"' -f4) if echo "$to" | grep -q 'oc_'; then return 0 fi # Check if session key contains feishu:group local key key=$(grep -o '"sessionKey":"[^"]*"' "$f" 2>/dev/null | head -1 | cut -d'"' -f4) if echo "$key" | grep -q 'feishu:group'; then return 0 fi return 1 } ``` ### Technical Analysis Session metadata is identified through raw substring searches rather than structured JSON parsing or an authoritative session index. The logic therefore depends on exact serialization, field order, and the first matching text in each transcript. A marker-like value in an unexpected record can cause a stale transcript to be retained. Conversely, whitespace, alternative JSON serialization, changed field placement, malformed records, or an address format not recognized by these expressions can cause a legitimate main or group session to be moved. The fallback is additionally inconsistent with its comment: it does not verify a `"t ...[truncated 1591 chars]
Remediation
## Remediation Suggestions - Obtain the active main-session identifier from authoritative OpenClaw metadata or an official API rather than transcript content. - Parse each JSONL record with a JSON-aware tool and validate exact field values and expected schemas. - Require exact equality for the main-session key and validated group-address prefixes or formats instead of unrestricted substring matching. - Inspect the appropriate metadata record rather than accepting the first textual match anywhere in the file. - If the active main session cannot be identified unambiguously, abort without moving files and emit a clear error. - Remove the arbitrary newest-file fallback or implement the documented condition using structured fields. - Add tests for whitespace variations, reordered fields, malformed JSON, multiple metadata records, misleading marker-like content, and unsupported address formats. - Encourage users to run `--dry-run` before destructive maintenance and display the selected active-session filename in the summary.
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.