T09 · Insecure Skill Coding Practices
- Location
tools/teeho_skill/diagnosis.py:119- Finding
Automatic cross-user disclosure of anonymous reports and local material paths
- Content
View full analysis
Vulnerability Details
File Location:
tools/teeho_skill/diagnosis.py:119-123,tools/teeho_skill/public_history.py:42-79,tools/teeho_skill/history.py:107-110, andSKILL.md:199
Vulnerability Type: Plaintext sensitive-data exposure through shared storage
Risk Level: HighComplete Code Snippet
tools/teeho_skill/diagnosis.py:119-123:python try: HistoryTools(self.root, scope.user_id).save(task, media=local_media(state)) if scope.anonymous: publish_report(HistoryTools(self.root, scope.user_id).read(task["id"]), scope.user_id)tools/teeho_skill/history.py:107-110:python write_json(path, { "task": task, "cover": None, "localMedia": locations, "savedAt": saved_at, })tools/teeho_skill/public_history.py:42-79:python else: directory.chmod(0o1777) def publish_report(report: dict[str, Any], owner: str) -> None: """原子发布明文匿名报告;其他用户可读,不能覆写已有报告。""" task_id = _identifier(report.get("task", {}).get("id")) validated = _report(report, task_id) value = {**validated, "anonymousOwner": _identifier(owner)} data = json.dumps(value, ensure_ascii=False, allow_nan=False).encode("utf-8") if len(data) > MAX_JSON_BYTES: raise TeehoError("invalid_local_data") directory = _checked_directory() _prepare_directory(directory) target = directory / (task_id + ".json") if target.exists() or is_link(target): read_public_report(task_id) return descriptor, temporary = tempfile.mkstemp(dir=directory, suffix=".tmp") temporary_path = Path(temporary) try: with os.fdopen(descriptor, "wb") as stream: stream.write(data) stream.flush() os.fsync(stream.fileno()) if os.name == "nt": _windows_dacl(temporary_path, f"D:P(A;;FA;;;{_windows_user_sid()})(A;;GR;;;WD)") else: temporary_path.c ...[truncated 2675 chars]- Remediation
View remediation
Remediation Suggestions
- Keep anonymous reports in the existing private account history by default.
- Require explicit, informed user confirmation before exporting each report to machine-wide shared storage.
- Clearly enumerate the fields that will be shared before confirmation.
- Remove
localMedia,anonymousOwner, absolute paths, and other account-specific metadata from any public export. - Construct public exports from a strict field allowlist rather than copying the complete private report.
- Use mode
0700for directories and0600for files unless cross-user sharing was explicitly requested. - If sharing is required, export to a user-selected destination and warn that other local users may be able to read it.
- Add regression tests verifying that ordinary anonymous diagnosis does not create world-readable files and that public exports contain no local paths.
