T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/openclaw-session-rotator.sh:17
- Finding
- Cross-Agent Conversation Content Is Duplicated into Plaintext Archives Without Restrictive Permissions## 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**: Medium ### Vulnerable 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 fi ``` ```bash 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
- ## Remediation Suggestions 1. Set restrictive defaults before creating any state or archive files: ```bash umask 077 ``` 2. 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" ``` 3. Create archive, handoff, map, cooldown, and temporary files with mode `0600`. After writing or copying files, enforce permissions with `chmod 600`. 4. Replace unrestricted `--all-agents` processing with an explicit, user-configured agent allowlist. Require affirmative opt-in before reading or archiving each agent's sessions. 5. 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. 6. Avoid retaining verbatim conversation content where possible. Generate a minimal structured summary that excludes credentials, personal information, and full message text. 7. Establish configurable retention limits and securely remove expired archives, handoff files, temporary session data, and stale `latest` copies. 8. Write files atomically using securely created temporary files in a private directory, apply mode `0600`, and then rename them into place. 9. Document the cross-agent collection behavior and archive locations clearly so users can make an informed decision before enabling the scheduled task.
