T09 · Insecure Skill Coding Practices
- Location
scripts/mbti_common.py:389- Finding
Sensitive historical data is persisted without explicit private filesystem permissions
- Content
View full analysis
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: MediumVulnerable 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 generatedsource_summary.jsonalso 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
View remediation
Remediation Suggestions
- Create report directories with owner-only mode
0700. - Create sensitive JSON, JSONL, Markdown, and HTML files atomically with mode
0600, rather than relying on the process umask. - Resolve and validate the output path before writing. Reject symlinks and ensure each output file remains within the intended report directory.
- Use temporary files opened with secure exclusive-creation semantics, then atomically replace the final destination.
- Add a privacy-preserving mode that streams records through evidence extraction without retaining full
raw_records.jsonl. - Minimize
source_summary.jsonby omitting content previews unless the user explicitly requests them. - Document artifact retention and add a secure cleanup command for raw records, evidence excerpts, and follow-up answers.
- Warn users when they select a report directory outside the private default location.
- Create report directories with owner-only mode
