T09 · Insecure Skill Coding Practices
- Location
scripts/add_mistake.py:126- Finding
Topic-Based Path Traversal Enables Writes Outside the Data Directory
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent study-mistake tracker, but its export and topic handling can write outside the intended folders and its HTML export can carry unsafe injected content.
Review before installing. This skill appears intended for local study tracking, not theft or system compromise, but use it only in a constrained workspace. Avoid exporting to arbitrary paths, do not open or share HTML exports made from untrusted content, and treat mistake records and reports as private educational data.
scripts/add_mistake.py:126Topic-Based Path Traversal Enables Writes Outside the Data Directory
scripts/export.py:271Caller-Controlled Export Path Enables Arbitrary File Overwrite
scripts/export.py:190Unescaped Stored Data Enables Script Injection in HTML Exports
错误答案: {m.get('wrong_answer', '')}
正确答案: {m.get('correct_answer', '')}
错误原因: {m.get('reason', '')}
The skill describes capabilities that imply reading images, writing JSON data, exporting files, and potentially accessing environment-backed tooling, but it does not declare any explicit tool scope or permissions boundaries. This creates ambiguity about what the agent may access and increases the risk of over-broad file or environment access if the runtime grants defaults beyond what the skill actually needs.
The skill stores, analyzes, and exports study records that may contain sensitive personal data, including student performance, weaknesses, screenshots, and OCR-extracted content, yet it provides no clear warning or consent language. Users may unknowingly persist or share private educational data, especially when exporting to PDF/HTML/Markdown or syncing through cloud storage.
The export template includes personally identifying and study-history fields such as student name, dates, review records, performance statistics, and learning weaknesses, but provides no warning, minimization guidance, or consent cue before export/sharing. In an education context, these exports can expose sensitive student data if shared, printed, or stored insecurely, creating privacy and profiling risks.
The docstring and parameter description at L46-L53 state that the function calculates the next review date based on created_date, implying the review schedule is anchored to the mistake's creation time. However, the implementation at L61 returns datetime.now() + timedelta(days=interval), never using created_date, which directly contradicts the documented intent of the algorithm.
This file’s natural-language interface elements, including docstrings, comments, sample output, and example content, are all Chinese-only. Under the policy, forcing a specific language without user opt-in or justification is a natural-language policy violation.
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
filtered = [m for m in filtered if m.get('topic') == topic]
if days:
cutoff = datetime.now() - __import__('datetime').timedelta(days=days)
filtered = [
m for m in filtered
if datetime.fromisoformat(m.get('created_at', '')) >= cutoff
User-controlled fields such as title, subject, question, answers, and reason are interpolated directly into HTML without escaping. If a mistake entry contains HTML or JavaScript, opening the exported file in a browser can execute active content, enabling stored XSS in the exported document and possible data exfiltration or local action via the browser context.
This code writes the full exported mistake dataset, including questions, wrong answers, correct answers, reasons, and notes, to a file path supplied by the caller or to a generated file under the workspace. Although the function comment says it exports mistakes, there is no confirmation prompt or explicit user-facing warning that personal study data will be persisted to disk, which matches the missing-disclosure criterion for code files.
The export destination can be influenced by WORKSPACE and, more importantly, directly by the output_file argument, allowing writes to arbitrary filesystem locations accessible to the process. In an agent setting, this can overwrite unrelated files, place exported sensitive study data in unsafe locations, or be abused for persistence/clobbering if an attacker can steer parameters.
output_path = OUTPUT_DIR / f"mistakes_{timestamp}{ext}"
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(content)
return f"✅ 已导出到: {output_path}"
This Python file contains natural-language descriptions and user-facing strings entirely in Chinese, beginning with the module docstring and continuing through output prompts. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified.
The output instructs users to reply with Chinese phrases such as 「开始复习」 or 「查看题目 [ID]」, which imposes a language requirement without presenting alternatives. This can violate language/locale policy when users are not given a choice or advance notice of the constraint.
The skill description, commands, examples, and interaction patterns are entirely specified in Chinese, with no indication that users may choose another language or locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified.
All headings and instructional text in the template are presented in Chinese, and the file does not state that the skill is China-specific or that users can choose another language. This may violate a language or locale policy if the skill is expected to avoid forcing a specific language without opt-in.
This JSON file defines all subject names, topic labels, difficulty values, error types, and status types in Chinese only. Because the file provides no alternative locale values or indication that the skill is intentionally region-specific, it appears to impose a specific language without user opt-in.
This markdown file contains all instructions, templates, and examples exclusively in Chinese. Under the policy for natural-language violations, forcing a specific language without user choice can be a locale/language policy issue when no opt-in or justification is provided.
The file's docstrings and all user-facing return strings are written in Chinese, and the generated HTML explicitly declares lang="zh-CN". There is no indication that the user can opt into another language or that the locale restriction is documented as intentionally region-specific.
This code file contains natural-language documentation and user-facing output exclusively in Chinese, starting with the module docstring. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy concern because the skill does not indicate any language selection or locale justification.
At L159, the docstring labels main() as 测试 (test), which implies a non-production or diagnostic role. In reality, the function invokes generate_stats() and prints the formatted statistics report, making it the actual entrypoint behavior of the script rather than a test helper.