T09 · Insecure Skill Coding Practices
- Location
templates/ingest-url.md:28- Finding
Shell Command Injection Through User-Controlled Alias Interpolation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is purpose-coherent and not clearly malicious, but it handles sensitive workplace/person data and has risky URL fetching, command execution, dependency, and retention practices that need review before installation.
Install only if you are comfortable storing sensitive interpersonal/workplace material as local plaintext files. Use a dedicated private directory, avoid shared drives and repositories, review every diff before writes, do not fetch internal/private URLs through the skill, and treat delete_corpus as archive/comment-out rather than deletion. Pin and install dependencies in an isolated environment, and avoid executing template commands through a shell with untrusted aliases or IDs.
templates/ingest-url.md:28Shell Command Injection Through User-Controlled Alias Interpolation
templates/ingest-url.md:16Unrestricted User-Supplied URL Fetching Enables SSRF
scripts/requirements.txt:1Unpinned Dependency Is Eligible for Automatic Installation
scripts/update_memory.py:227Deletion Retains Sensitive Records in Comments and Backup Files
This skill is specifically designed to ingest emails, chats, meeting notes, annotations, and URL-sourced communications about identifiable individuals, then store distilled profiles locally. Without a prominent upfront warning and consent/privacy guidance, users may unintentionally process confidential or personal data, creating substantial privacy, compliance, and insider-surveillance risks.
The documented activation triggers are very broad and include common natural-language phrases, which can cause the skill to auto-activate on unrelated user requests. In this skill’s context, unintended activation is more dangerous because it handles sensitive interpersonal data and may prompt collection, storage, or transformation of private communications without a clear, deliberate opt-in boundary.
The skill documents file read/write behavior and instructs the agent to modify local memory files, but it does not declare any explicit tool scope or permission boundaries. In agents that auto-wire tools based on skill content, this can enable unintended filesystem access or broader writes than the user expects, especially because the skill is triggered by common collaboration scenarios.
The trigger phrases are broad enough to match ordinary requests like drafting, rehearsal, or discussing a person's preferences, which can cause the skill to activate unexpectedly. In this skill, unexpected activation is more dangerous because it may start ingesting, summarizing, and persisting sensitive interpersonal communications to local storage without sufficiently clear user intent.
This markdown skill presents all operative guidance, examples, and instructions in Chinese only, with no indication that the user can choose another language or that the locale restriction is intentional and justified. That can violate a language/locale policy when users are not given an opt-in or alternative.
The document states that some hosts may automatically run pip install pyyaml on first use, but it does not warn users about the risks of installing packages at runtime on the host system. Automatic dependency installation can modify the local environment, pull code from external package indexes, and create supply-chain exposure or unexpected execution on machines where the skill is supposed to remain local and privacy-preserving.
The entire specification mandates a Chinese-language memory format and field semantics, such as Chinese section names and examples, with no indication that users can opt into another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.
This markdown file contains operational guidance to rewrite the entire memory file and create backup copies before modification. Those actions affect user data on disk, but the document does not include any warning or disclosure about file modification, backup artifact creation, or the need to obtain user awareness before proceeding.
This code file contains user-facing natural-language content such as the module docstring and argument help text that assumes Chinese as the only language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified.
The script creates and updates a persistent local memory file without any explicit user-facing disclosure or confirmation at the point of write. In this skill’s context, the stored data consists of sensitive interpersonal communications and inferred profiles, so silent persistence can violate user expectations and increase privacy and compliance risk even if storage is only local.
The script ingests arbitrary signals JSON and persists its contents into long-lived memory without disclosing that supplied text, URLs, and extracted traits will be stored. Because this skill is specifically designed to accumulate speech, emails, chats, and behavioral inferences about named individuals, the lack of disclosure is more dangerous than usual and can lead to covert retention of highly sensitive personal or corporate data.
The entire skill is written as mandatory Chinese prompts and response templates, including fixed user-facing confirmations and follow-up suggestions. There is no indication that the user may choose another language or that the locale restriction is optional or justified as region-specific, which is a natural-language policy violation under the language/locale rule.
The file’s operational prompts and instructions are exclusively in Chinese, which can force a specific language on users or operators without any stated opt-in. The policy only permits this when a language choice is offered or the locale restriction is clearly justified, neither of which appears here.
The entire skill instruction set, trigger text, and user-facing scripted responses are written only in Chinese, and the workflow directs the assistant to use those responses during operation. There is no indication that the user can choose another language or that the Chinese-only constraint is justified as a region-specific requirement, which makes this a natural-language policy violation under the language/locale rule.
The entire skill is written as mandatory Chinese workflow and output templates, including fixed Chinese prompts and report structure, with no indication that the user may choose another language. This creates a natural-language policy concern because it imposes a specific language/locale without opt-in or documented justification.
The workflow explicitly tells the agent to search a shared memory.md corpus for relevant historical material after loading a per-person profile, which conflicts with the stated privacy model of keeping data isolated in memory-{npc_id}.md. In a skill built around sensitive communications and executive/persona modeling, this can cause cross-person data mixing and unauthorized disclosure of another subject's messages, notes, or behavioral profile.
The '反例' section says '不要替用户回答提问', framing the exercise as practice rather than doing the work for the user. However, step 7 option 2 tells the agent to '帮你把雷区都改掉,润色到符合他风格', which actively performs the substantive revision instead of keeping the interaction purely as rehearsal.
The README consistently presents the skill interface, examples, and expected usage in Chinese, and the contribution section notes templates are mainly Chinese. There is no explicit statement that users may choose their preferred language at runtime, which can be a locale/language policy concern when the skill is used in broader multilingual environments.
The manifest description says '所有数据存储在本地单一memory文件中', which implies one single memory file. However, the Quick Reference later documents storage as '~/npc-distill/memory-{npc_id}.md', indicating one file per NPC rather than a single file overall. This is a semantic mismatch between the claimed storage model and the actual documented behavior.
The Quick Reference states '永远不要写真名', suggesting strict avoidance of real names in stored representations. Elsewhere, the usage documentation repeatedly frames the workflow around analyzing 'X 说的/写的' and specific people's content, which does not itself guarantee contradiction, but the stronger contradiction is that the storage guidance claims strict pseudonymization while no documented enforcement mechanism is described. The documentation therefore overstates the guarantee compared with what the skill actually specifies.
The dependency is specified as pyyaml>=6.0 without an upper bound or exact pin, which makes builds non-reproducible and allows different environments to install different releases over time. In a skill that may process user-supplied content and URLs, dependency drift increases supply-chain risk and makes it harder to verify that a safe version is consistently deployed.
pyyaml>=6.0
PyYAML has a history of deserialization and input-validation advisories, and because the requirement is not pinned, it is impossible to determine from this manifest alone whether deployments will receive an affected version. Given this skill's purpose of ingesting pasted text, meeting notes, chats, and URL-derived content, any unsafe YAML handling elsewhere in the project would be more concerning because inputs may be attacker-controlled or sensitive.
No suspicious patterns detected.