T09 · Insecure Skill Coding Practices
- Location
dist/kernel/persona-store.js:11- Finding
Unrestricted Filesystem Access and Recursive Directory Deletion
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its Bazi persona purpose, but it gives broad file-backed persona management powers with weak path controls and risky persistent memory import behavior.
Review before installing. Use only a trusted, contained persona directory; avoid passing arbitrary base_dir values; do not import private or third-party chat logs unless you are comfortable with them being stored and reused; and be careful with delete actions because they can remove stored persona data. Avoid the unpinned npx development command unless you have pinned and verified the tooling.
dist/kernel/persona-store.js:11Unrestricted Filesystem Access and Recursive Directory Deletion
dist/kernel/workflow-orchestrator.js:281Persistent Prompt Injection Through Automatically Imported Chat Memory
SKILL.md:44Unpinned Remote Package Execution Through npx Documentation
The declared description centers on Bazi-based persona creation/chat and astrology/calendar features. The actual code shown is a command-line interface declaration for inspecting and deleting stored personas plus help/main functions. These capabilities are materially different from the declared astrology-focused purpose, and one of them—deleting stored persona data—is an undeclared capability affecting stored resources. While this is only a type declaration file and may not show the full implementation, based on the supplied chunk the described functionality is not represented, and the exposed CLI/data-management behavior is not disclosed in the description.
The declared description presents the skill as a full Bazi persona system supporting creation, updates, conversation, Bazi analysis, flow-time analysis, and almanac lookup. However, the supplied code chunk does not implement those capabilities. Instead, it provides a command-line interface for inspecting stored personas, listing them when no match is found, and deleting them. It also reveals file locations and metadata for stored persona artifacts. The help text explicitly says the CLI is 'storage-only' and that generation, updates, dialogue, flow analysis, and calendar lookup belong elsewhere. This is a material description-versus-behavior mismatch for the supplied code chunk: the chunk’s actual purpose is file/storage management, including deletion, rather than the end-user Bazi/persona functionality described.
The declared description is specifically about a BaZi astrology/personality skill with chart generation, fortune-flow analysis, and calendar/almanac lookup. The provided code chunk instead exposes generic infrastructure for parsing inputs and routing intents in a persona system. There is no evidence in this chunk of domain-specific BaZi computations, calendrical lookup, or Huangli functionality. Because the code’s observable behavior is materially different from the declared primary purpose, this is a description-behavior mismatch.
The declared description centers on astrology-style 八字 functionality: charting, fortune-cycle analysis, and calendar/almanac queries. The provided code chunk does not implement or expose those capabilities. Instead, it defines TypeScript declarations for loading prompt/persona resources and resetting a cache. These are materially different from the declared primary purpose. While such utilities could be supporting infrastructure for a persona system, nothing in this chunk reflects the stated 八字-specific features, so the description is not accurately represented by the supplied code.
Yes, this is a mismatch. The declared description promises substantial domain-specific functionality, but the provided code chunk is effectively empty and does not implement any of the stated capabilities. There are no resource accesses, triggers, or hidden behaviors in this snippet—just an empty module. Therefore the actual behavior does not match the declared purpose.
声明描述覆盖了核心八字相关能力:人格创建、更新、对话、八字排盘、流时分析、万年历/黄历查询,这些都与代码一致。但代码还包含若干未在描述中体现的实质能力:1) 可导入外部聊天内容并从中提取/合并记忆;2) 持久化维护 persona memory 和对话历史;3) 响应 startup injection 请求,生成专门的 persona 启动注入文本;4) 支持开启/关闭“作弊模式”,将人格切换到分析/cheatsheet 模式。这些不是单纯的内部实现细节,而是可由输入触发的面向功能行为,尤其聊天导入和注入/作弊模式与声明明显不符。因此应判定为描述与实际行为存在不完全一致的 mismatch。
The declared purpose is a domain-specific astrology/Bazi personality skill, but the supplied code chunk contains only low-level shared utility declarations unrelated to Bazi analysis, personality creation/chat, or calendar/almanac logic. It exposes file I/O and CLI parsing capabilities that are not reflected in the description. While such utilities could support a larger system, this chunk by itself does not implement the declared behavior and instead represents a materially different, generic support module.
Referenced artifact was not completely inspected
node dist/cli.js --action inspect
The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.
The function applyDayRollover returns the original date when hour < dayRolloverHour, but increments the date when hour >= dayRolloverHour. With the default rollover hour of 23, this means 23:00 and later are shifted, which is the opposite of the common intent implied by the chart note that missing time uses 12:00 only for internal calculation and by the parameter name dayRolloverHour, which suggests rollover should apply to hours before that threshold. This is an active intent/behavior contradiction in the implementation logic.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
The workflow directs the system to retain and reuse user-provided facts in persistent persona memories and snapshots by default, with broad guidance to preserve relationship and reality information. In a skill centered on identity profiles and birth data, this creates meaningful privacy risk because sensitive personal information can accumulate over time without clear minimization, retention, or consent boundaries.
The file defines an explicit alternate interaction state called '作弊模式' ('cheat mode') and instructs the model to switch into it on user request. Although framed as analysis enhancement, this role/state transition semantically resembles jailbreak phrasing because it creates a special mode with modified behavior and privileged prompt layering, which could evade simple keyword-based detection when localized or reframed.
The skill explicitly supports importing external chat records, extracting facts, and storing them into persona memory/history, but it does not require user confirmation of ownership, consent from third parties, or any privacy notice before retention. In a persona skill handling intimate chat logs and inferred traits, this materially increases the risk of collecting and persisting sensitive personal data without informed consent.
The external chat import flow encourages extracting and storing historical conversation content as reusable memory/history without defining privacy boundaries, redaction expectations, or third-party consent handling. Because imported chat logs may contain large volumes of sensitive and non-user data, this materially raises the chance of over-collection and long-term retention of personal information.
The file documents persistent writes of persona profiles, Bazi data, memories, and history into on-disk files, yet does not clearly disclose to users that sensitive birth data, relationship context, and conversation-derived facts will be stored locally. This creates a real privacy and data-handling risk because users may provide highly sensitive information without understanding it will persist beyond the current session.
The CLI exposes a destructive delete action that immediately removes stored persona data once a slug or matching name is resolved, with no confirmation prompt, dry-run mode, or force flag separation. In this skill’s context, personas appear to contain persistent user data and conversation history, so an accidental invocation, ambiguous name match, or scripted misuse can cause irreversible data loss.
The transient persona preferences default preferred_language to "zh", which imposes a specific language choice automatically. The policy requires offering language/locale choice or documenting a justified locale restriction; neither is evident in this file.
The delete action removes persona data by calling deletePersona, but there is no confirmation prompt, warning comment/docstring, or user-visible disclosure around this irreversible operation in the code shown. Because deletion affects stored user data, the file should disclose that this action is destructive.
The delete branch filters out memory entries and immediately saves the modified persona record, which permanently changes stored data. In this file there is no confirmation prompt, print/log disclosure, or explanatory comment indicating that the operation deletes persisted memory.
The fallback in resolveLanguage returns "zh" whenever detection fails and the preferred mode is "auto". This imposes a specific language choice by default rather than asking the user or preserving neutrality, which is a natural-language locale policy concern.
This string instructs the skill to default to Chinese whenever the user's language cannot be determined. That imposes a specific language without user opt-in, which matches the locale-policy violation criteria.
The skill is explicitly designed to preserve conversation fragments and real-world changes for reuse in future persona outputs. In a persona/imitation skill, this increases the chance of unintentionally retaining and resurfacing sensitive user-provided details, especially because later responses are shaped by stored memory rather than being limited to the current turn.
The English locale pack explicitly says to start in Chinese if the language is unclear. Even though the skill supports multiple languages, this is still a forced language fallback without user opt-in.
This instruction directs the skill to begin in Chinese when language detection is ambiguous. That is a natural-language locale constraint applied without opt-in or documented regional justification.
No suspicious patterns detected.