T09 · Insecure Skill Coding Practices
- Location
scripts/liuyao.py:345- Finding
Automatic Plaintext Retention of Sensitive Consultation Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/liuyao.py, lines 345-348 and 416-445
Vulnerability Type: Automatic plaintext storage of potentially sensitive user data
Risk Level: MediumVulnerable Code
python def save_history(history_path: Path, payload: Dict[str, object]) -> None: history_path.parent.mkdir(parents=True, exist_ok=True) with history_path.open("a", encoding="utf-8") as f: f.write(json.dumps(payload, ensure_ascii=False) + "\n")The function is invoked unconditionally with the raw question and generated consultation details:
python save_history( Path(args.history), { "ts": now.isoformat(), "question": args.question, "ben_gua": {"name": ben.name, "code": ben.code}, "bian_gua": {"name": bian.name, "code": bian.code}, "day_ganzhi": day_gz, "month_jian": month_branch, "kongwang": f"{kongwang[0]}{kongwang[1]}", "yongshen": yongshen, "judgment": judgment, "score": score, "advice": advice, "judge_trace": judge_meta.get("trace", []), "lines": [ { "line": ln.index, "value": ln.ben.value, "moving": ln.ben.is_moving, "yin_yang": "阳" if ln.ben.is_yang else "阴", "bian_yin_yang": "阳" if ln.bian_is_yang else "阴", "branch": ln.branch, "element": ln.element, "liuqin": ln.liuqin, "liushen": ln.liushen, "shi": ln.is_shi, "ying": ln.is_ying, } for ln in pan_lines ], }, )Technical Analysis
Every execution unconditionally appends the user's raw question and the complete generated result to a JSONL file. Consultation questions can contain sensitive information concerning health, employment ...[truncated 2236 chars]
- Remediation
View remediation
Remediation Suggestions
- Make history retention opt-in rather than unconditional, such as through an explicit
--save-historyoption. - Provide a clear
--no-historymode and document the default retention behavior before accepting user data. - Avoid storing the raw question unless it is essential. Offer redaction, pseudonymization, or storage of only non-sensitive result metadata.
- Create new history files with owner-only permissions, such as mode
0600, and verify existing files are not group- or world-readable. - Validate the selected history destination and warn when it is inside a shared, synchronized, temporary, or publicly accessible directory.
- Implement configurable retention limits, record deletion, and history-clearing functionality.
- If durable sensitive storage is required, use encryption at rest with keys managed separately from the history file.
- Inform users exactly which fields are retained, where the file is located, and how to disable or delete the stored history.
- Make history retention opt-in rather than unconditional, such as through an explicit
