T09 · Insecure Skill Coding Practices
- Location
scripts/openclaw-session-rotator.sh:17- Finding
Cross-Agent Conversation Content Is Duplicated into Plaintext Archives Without Restrictive Permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/openclaw-session-rotator.sh:17, 44, 101-111, 126-160, 173-198
Vulnerability Type: Plaintext storage of potentially sensitive conversation data
Risk Level: MediumVulnerable Code
bash mkdir -p "$STATE_ROOT" "$COOLDOWN_DIR" "$ARCHIVE_ROOT" "$ARCHIVE_ROOT/latest" if ! "$OPENCLAW_BIN" sessions --all-agents --json > "$TMP_SESSIONS_JSON" 2>/dev/null; then log "sessions list unavailable, skip" exit 0 fibash session_file="$HOME/.openclaw/agents/$agent_id/sessions/${session_id}.jsonl" [[ -f "$session_file" ]] || continue agent_archive_dir="$ARCHIVE_ROOT/$agent_id" mkdir -p "$agent_archive_dir" stamp="$(date +%Y%m%d-%H%M%S)" archive_file="$agent_archive_dir/${stamp}-${safe_key:0:10}.md" handoff_file="$agent_archive_dir/${stamp}-${safe_key:0:10}.handoff.txt" latest_file="$ARCHIVE_ROOT/latest/${agent_id}.md" python3 - "$session_file" "$archive_file" "$handoff_file" "$session_key" "$agent_id" "$pct" "$total" "$context" "$MAX_ITEMS_PER_ROLE" <<'PY'python for raw in session_file.read_text(encoding="utf-8").splitlines(): if not raw.strip(): continue try: row = json.loads(raw) except json.JSONDecodeError: continue if row.get("type") != "message": continue ts = row.get("timestamp") if isinstance(ts, str): if first_ts is None: first_ts = ts last_ts = ts msg = row.get("message") or {} role = msg.get("role") if role not in ("user", "assistant"): continue parts = msg.get("content") or [] texts = [] for part in parts: if isinstance(part, dict) and part.get("type") == "text": t = (part.get("text") or "").strip() if t: texts.append(t) if not texts: continue merged = norm(" ".join(texts)) if role == "user ...[truncated 3897 chars]- Remediation
View remediation
Remediation Suggestions
-
Set restrictive defaults before creating any state or archive files:
bash umask 077 -
Explicitly secure all relevant directories:
bash install -d -m 700 "$STATE_ROOT" "$COOLDOWN_DIR" "$ARCHIVE_ROOT" "$ARCHIVE_ROOT/latest" install -d -m 700 "$agent_archive_dir" -
Create archive, handoff, map, cooldown, and temporary files with mode
0600. After writing or copying files, enforce permissions withchmod 600. -
Replace unrestricted
--all-agentsprocessing with an explicit, user-configured agent allowlist. Require affirmative opt-in before reading or archiving each agent's sessions. -
Add secret redaction before archival. At minimum, detect common API-key, bearer-token, private-key, password, and credential patterns. Prefer omitting sensitive messages entirely rather than relying only on pattern matching.
-
Avoid retaining verbatim conversation content where possible. Generate a minimal structured summary that excludes credentials, personal information, and full message text.
-
Establish configurable retention limits and securely remove expired archives, handoff files, temporary session data, and stale
latestcopies. -
Write files atomically using securely created temporary files in a private directory, apply mode
0600, and then rename them into place. -
Document the cross-agent collection behavior and archive locations clearly so users can make an informed decision before enabling the scheduled task.
-
