T09 · Insecure Skill Coding Practices
- Location
scripts/generate.py:256- Finding
User-Controlled Filenames Permit Path Traversal and File Overwrite
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is for creating Obsidian study notes, but it needs review because it can create or overwrite many local vault files and does not safely constrain output paths.
Review before installing. Use it only if you want English-Chinese Obsidian notes written into the configured vault, confirm the target folder and file tree before any run, avoid untrusted titles or concept names, keep backups, and prefer a dedicated sandbox/output folder. Install optional Python dependencies in an isolated, pinned environment, and treat URL/video extraction as external processing that may reveal the provided links or content.
scripts/generate.py:256User-Controlled Filenames Permit Path Traversal and File Overwrite
SKILL.md:163Unpinned Third-Party Dependency Installation
The description overstates the implemented functionality. The code does generate Obsidian-compatible markdown scaffolds with wikilinks and bilingual glossary fields, so it is related in theme. However, it does not process the broad declared input modalities at all; it only uses CLI arguments. Its 'recursive atomic decomposition' is not implemented as automatic multi-layer generation—lecture mode generates only the main note and first-level atomic notes, while deeper layers require manual separate runs. Rich outputs like Mermaid diagrams and comparison tables are not synthesized by code, only left as TODO/template content. Additionally, the code supports generating a course MOC, an undeclared capability. Therefore the declared description does not accurately represent the actual behavior.
The declared description centers on creating structured Obsidian lecture notes and recursively decomposed atomic notes from source materials. The supplied code does not perform note generation, decomposition, source ingestion, or Obsidian vault construction. Instead, it loads local CSV files and runs BM25-based search over glossary, Mermaid templates, writing rules, and review questions, then formats search results for display. While glossary and Mermaid-related content are tangentially related to the declared domain, the code’s actual primary purpose is search/retrieval of reference data, not lecture note generation. This is a material description-behavior mismatch.
The declared description presents a full lecture-note generation system for Obsidian, centered on transforming source materials into richly structured markdown notes with diagrams, tables, glossary content, and wikilinks. In contrast, this code chunk only implements a visualization generator script. It accepts command-line arguments for chart type, title, JSON data, and output path, then renders and saves image files using Matplotlib. While charts could be a supporting component of a larger note-generation workflow, this specific code neither ingests the declared educational inputs nor produces the declared note outputs. Its primary purpose is materially different from the declared skill purpose, so this is a clear mismatch.
This markdown example presents the skill being invoked and used in Chinese, and the rest of the examples consistently structure outputs with Chinese labels and bilingual Chinese-first formatting. Because the file does not indicate that language choice is optional or user-configurable, it suggests a fixed locale behavior that may violate language/locale policy expectations.
The skill instructs file reads/writes into the user's Obsidian vault but does not declare an explicit tool scope such as allowed tools or permissions. In an agentic environment, undeclared filesystem capabilities reduce transparency and make it easier for a broadly triggered skill to modify local content unexpectedly.
The trigger phrases are broad enough to match ordinary summarization or note-taking requests, increasing the chance the skill activates when the user did not intend large-scale vault modifications. Because the skill also prescribes directory creation, many file writes, and optional network fetching, overbroad activation materially raises the chance of unintended side effects.
The user profile hard-codes the language policy as "Bilingual — English primary, Chinese secondary" and mandates a specific term format. This forces a locale/language preference rather than offering the user a choice or making the behavior clearly optional.
The skill explicitly instructs creation of directories and writing numerous files into the user's vault without an explicit user-facing warning or confirmation step. In context, this is risky because activation may be broad and the write pattern is recursive and high-volume, making accidental content sprawl or overwriting more likely.
The rule explicitly requires all technical terms to be presented as English plus Chinese, regardless of user preference or locale. In a note-generation skill that accepts arbitrary user inputs and produces educational content, this creates a policy-level prompt injection/output steering issue: it can force unsolicited language transformation and disclosure of translated terminology that the user did not request. The skill context makes this more relevant because the CSV appears to define mandatory generation behavior across all notes, so the requirement is likely to be applied broadly and consistently.
This code generates note content containing Chinese text such as '详见' and '关键要点' directly in the output scaffold. Because the skill does not present this as an opt-in language choice or justify it as a region-specific tool, it violates the policy against forcing a specific language/locale by default.
The template hardcodes bilingual formatting in the title and throughout the document, requiring Chinese alongside English rather than letting the user choose a preferred language. This is a natural-language policy concern because it imposes a specific locale/language convention without visible opt-in or documented justification.
The template repeatedly hardcodes Chinese labels such as 概述, 关键要点, 总结, and 相关笔记, establishing a fixed bilingual locale across the document. Because no user choice or scope limitation is provided, this can violate language/locale policy expectations for user-controlled output language.
The standalone trigger "Exam prep / study materials" is too vague to distinguish this skill from many other educational or summarization workflows. It lacks constraints about format, required outputs, or Obsidian-specific context, increasing the risk of unintended invocation.
The skill directs the agent to fetch URLs, extract transcripts, and use external tools without disclosing that network requests and third-party processing may occur. This can expose user-provided links, study materials, or browsing intent to external services and may surprise users who expected local-only note generation.
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
Generates Obsidian-compatible markdown notes from templates.
Usage:
# Main lecture note with N concepts (not limited to 3)
python3 generate.py --type lecture --title "Memory Optimization" \
--concepts "Shared Memory,Bank Conflicts,Tiling,Coalescing" \
--output "/path/to/00-Inbox/Topic/"
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
Generates Obsidian-compatible markdown notes from templates.
Usage:
# Main lecture note with N concepts (not limited to 3)
python3 generate.py --type lecture --title "Memory Optimization" \
--concepts "Shared Memory,Bank Conflicts,Tiling,Coalescing" \
--output "/path/to/00-Inbox/Topic/"
The docstring states 'Supports both English and Chinese queries,' which communicates an explicit language constraint. Under the policy rule, forcing a specific language set without user opt-in or a clear justification can be a natural-language locale-policy issue.
The template consistently requires both English and Chinese fields and section headings, such as paired title aliases and bilingual headings throughout the document. This imposes a specific language/locale format by default rather than offering a user choice or documenting that the template is region-specific.
The markdown explicitly states 'Language(语言) | English (Bilingual notes)', which imposes a specific language setting in the template. Under the policy rules, forcing a language without offering user choice or documenting a justified locale constraint is a natural-language policy violation.
This markdown template hardcodes Chinese punctuation and section labels such as '定义' and '相关笔记', and requires bilingual English/Chinese output. That imposes a specific language/locale convention in the generated content without indicating that the user can choose another language or opt in to this format.
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
<!--
REPEAT for as many sections as the content demands.
NOT limited to 3. Typically 3-7 sections.
Each section corresponds to one L1 atomic note.
-->
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
<!--
REPEAT for as many sections as the content demands.
NOT limited to 3. Typically 3-7 sections.
Each section corresponds to one L1 atomic note.
-->
No suspicious patterns detected.