T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/mbti_common.py:389
- Finding
- Sensitive historical data is persisted without explicit private filesystem permissions## Vulnerability Details **File Location**: `scripts/ingest_all_content.py:254-267`; `scripts/mbti_common.py:389-411` **Vulnerability Type**: Sensitive-data persistence with insufficient access controls **Risk Level**: Medium ### Vulnerable Code ```python records: List[Dict] = [] for source_type in approved_source_types: ingestor = INGESTORS.get(source_type) if ingestor is None: continue target_root = workspace_root if source_type.startswith("workspace") else openclaw_home records.extend(ingestor(target_root)) write_jsonl(output_dir / "raw_records.jsonl", records) write_json( output_dir / "source_summary.json", build_summary( records, approved_source_types, workspace_root, openclaw_home, ), ) ``` The shared output helpers create directories and files using process-default permissions: ```python def ensure_dir(path: Path) -> Path: path.mkdir(parents=True, exist_ok=True) return path def write_json(path: Path, payload: Any) -> None: ensure_dir(path.parent) path.write_text( json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", ) def write_jsonl(path: Path, rows: Iterable[Dict[str, Any]]) -> None: ensure_dir(path.parent) with path.open("w", encoding="utf-8") as handle: for row in rows: handle.write(json.dumps(row, ensure_ascii=False) + "\n") ``` ### Technical Analysis The ingestion stage reads authorized OpenClaw sessions, workspace memory, memory-index content, task summaries, or cron records and duplicates that information into `raw_records.jsonl`. The generated `source_summary.json` also includes content previews. Follow-up processing creates additional persistent files containing direct user answers. These files are sensitive because they can contain private conversation history, personal ...[truncated 2179 chars]
- Remediation
- ## Remediation Suggestions 1. Create report directories with owner-only mode `0700`. 2. Create sensitive JSON, JSONL, Markdown, and HTML files atomically with mode `0600`, rather than relying on the process umask. 3. Resolve and validate the output path before writing. Reject symlinks and ensure each output file remains within the intended report directory. 4. Use temporary files opened with secure exclusive-creation semantics, then atomically replace the final destination. 5. Add a privacy-preserving mode that streams records through evidence extraction without retaining full `raw_records.jsonl`. 6. Minimize `source_summary.json` by omitting content previews unless the user explicitly requests them. 7. Document artifact retention and add a secure cleanup command for raw records, evidence excerpts, and follow-up answers. 8. Warn users when they select a report directory outside the private default location.
