Back to skill

Security audit

Mio Companion

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent companion/chat helper, but it silently persists raw conversation content and inferred tasks and can surface them as executable actions without clear user control.

Review this skill carefully before installing. It keeps local plaintext records of recent chat content, habits, and inferred todos, may create tasks from normal conversation without asking first, and may later present those tasks for execution. Use it only if you are comfortable with local behavioral memory and ensure the host requires explicit confirmation before acting on any returned task.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:190
Finding

Plaintext Retention of Complete Conversation Content

Content
View full analysis
100) { logs.splice(0, logs.length - 100); } writeJson(LOG_FILE, logs); ``` ### Technical Analysis `ChatLearning.log()` writes message roles and complete message contents to `log.json` without encryption, redaction, sensitivity filtering, or an explicit consent check. Conversations may contain personal information, confidential business data, authentication tokens, or other secrets. The count-based limit of 100 entries reduces the amount of active data but does not impose a time-based retention policy. The implementation also does not provide a user-facing deletion mechanism or explicitly create the data directory and files with owner-only permissions. ### Attack Path 1. A user sends a message containing personal, confidential, or credential-like data. 2. `handleSkill()` passes `context.message.content` to `ChatLearning.log()`. 3. `ChatLearning.log()` stores the complete content in `mio-companion-data/log.json`. 4. A local user, process, backup service, or compromised component with access to the workspace reads the plaintext log. 5. The stored information is exposed or used for subsequent attacks. ### Impact Assessment The vulnerability affects the confidentiality of up to 100 recently recorded messages. An attacker does not gain additional application privileges directly, but any process or account that can read the workspace may obtain sensitive conversation content. Copies retained in backups or snapshots may extend the exposure beyond the application's active retention window. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:113
Finding

Unvalidated Conversation Text Can Become an Executable Task Request

Content
View full analysis
{ const patterns = [ /(.+)一下/, // "帮我查一下" /(.+)一下/, // "做一下" /(?:需要|要)(.+)/, // "需要处理" /(?:记住|记得)(.+)/, // "记住" /TODO[::]\s*(.+)/, // "TODO: xxx" /待办[::]\s*(.+)/, /(.+?)(吧|呀|哈|哦)/ // 语气词结尾的命令 ]; const todos = []; for (const pattern of patterns) { const match = text.match(pattern); if (match && match[1]) { const todoText = match[1].trim(); if (todoText.length > 2 && todoText.length < 100) { todos.push(todoText); } } } return todos; } ``` ```js if (typeof input === 'string') { const minedTodos = Todos.mineFromText(input); for (const todo of minedTodos) { Todos.add(todo, 'mining'); } } ``` ```js if (text.includes('执行') || text.includes('做任务')) { const executable = Schedule.getExecutableTasks(); if (executable.length > 0) { return { action: 'execute', data: executable }; } } ``` ### Technical Analysis The task-mining expressions are overly broad. Ordinary conversational statements, quoted text, or attacker-controlled content can match patterns such as `/(?:需要|要)(.+)/` or the pattern accepting text ending in common sentence particles. Matched content is automatically persisted as a todo without user confirmation, task-type validation, or trust-provenance checks. A later execution request returns these inferred todos using the `execute` action. The module does not directly run shell commands or external tools, so exploitation depends on how the surrounding host interprets that action. However, the skill creates an unsafe trust boundary if the host treats ` ...[truncated 1426 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
index.js:244
Finding

Undefined Method Call Causes Skill-Wide Denial of Service

Content
View full analysis
{ const habits = readJson(HABITS_FILE, { activeHours: {}, preferences: {}, topics: [] }); habits.activeHours[hour] = (habits.activeHours[hour] || 0) + 1; let maxHour = 0, maxCount = 0; for (const [h, c] of Object.entries(habits.activeHours)) { if (c > maxCount) { maxCount = c; maxHour = parseInt(h); } } habits.mostActiveHour = maxHour; writeJson(HABITS_FILE, habits); return habits; }, ``` The call sites invoke a nonexistent method: ```js const hour = new Date().getHours(); Habits.recordActiveHour(hour); ``` ```js const hour = new Date().getHours(); Habits.recordActiveHour(hour); ``` ### Technical Analysis `Habits` defines `recordActiveTime()` but does not define `recordActiveHour()`. Both `handleSkill()` and `ChatLearning.log()` invoke the nonexistent name. JavaScript therefore raises a synchronous `TypeError`. In `handleSkill()`, the failing call occurs before task mining, command processing, heartbeat processing, and normal response generation. Consequently, any ordinary skill invocation can terminate prematurely. When `ChatLearning.log()` is called directly, it writes the conversation log before reaching the failing call, which can leave partial state changes despite reporting an error. ### Attack Path 1. Any user or scheduler invokes `handleSkill()`. 2. The function calls `Habits.recordActiveHour(hour)`. 3. Because the property is undefined, the runtime throws a `TypeError`. 4. The invocation terminates before the requested command is processed. 5. Repeated invocations consistently reproduce the failure, denying normal skill functionality. ### Impact Assessme ...[truncated 360 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill description states that it records routines, preferences, and chat habits, but provides no warning about what behavioral data is collected, how long it is stored, or how it is used. Because the skill persists this data in local files and combines it with proactive engagement, users may be subject to opaque profiling and privacy-invasive monitoring without informed consent.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
- `index.js` - 主技能代码

Ssd 3

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill is explicitly designed to collect and retain habits, preferences, conversations, and mined tasks in natural-language form, which concentrates sensitive behavioral data in plain JSON files. In the context of a 'companion' skill that encourages ongoing personal interaction, this makes inadvertent collection of intimate or identifying information especially likely and increases downstream leakage risk.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The logging path stores raw user messages and the skill later uses stored habits/topics/todos to generate future prompts, creating a feedback loop where sensitive prior disclosures can resurface in later responses. Even without external exfiltration code, this is a real natural-language disclosure channel because private content may be echoed back in contexts where it is inappropriate or visible to others.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill persistently stores raw conversation content, habits, and behavioral metadata to local JSON files without any notice, consent, minimization, or retention controls beyond a 100-message cap for logs. In a companion/chat skill, users are likely to disclose sensitive personal information, so silent collection materially increases privacy and disclosure risk if the workspace is accessed by other components, users, or backups.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

All user-facing instructions and the explicit manual trigger phrase are presented only in Chinese, with no indication that users can choose another language. This can constitute a language policy violation when the skill implicitly requires a specific language without opt-in or documented locale restriction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill advertises proactive messaging, task extraction from conversation, and automatic scheduling/execution, but does not warn users that it may act autonomously based on inferred intent. This is dangerous because users may not expect background actions or outbound messages, increasing the risk of surprise actions, misinterpreted tasks, and erosion of user control.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manual trigger phrase “陪我聊天” is common natural language and can easily appear in ordinary conversation, causing the skill to activate unintentionally. In a skill that proactively chats, mines tasks, and manages schedules, accidental activation can lead to unwanted data collection or autonomous actions without clear user intent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Several trigger phrases are generic everyday-language commands such as chatting, checking tasks, and heartbeat/timed checks, which can cause accidental activation or overlap with other skills. In an agent environment, broad triggers increase the chance the skill runs without clear user intent, potentially exposing user data or performing unintended background actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Natural-language descriptions, commands, and responses are limited to Chinese, such as the trigger checks for 陪我聊天, 查看习惯, and 查看待办. Because the file does not offer language selection or explain that the skill is intentionally region-specific, it appears to impose a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The top-level documentation states the skill will '自动安排时间执行任务' (automatically arrange time to execute tasks). However, the main handler never invokes Schedule.scheduleTask or performs any automatic scheduling logic; it only checks existing schedules and returns executable tasks. This is an intent/documentation contradiction rather than a mere omission because the advertised automatic behavior is not implemented in code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill mines todos from arbitrary user text and persists them automatically, which can capture sensitive plans, obligations, or personal details the user did not intend to store as structured records. Because this occurs implicitly during normal conversation, it creates a privacy and user-expectation violation and may also lead to unwanted task execution workflows later.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The natural-language description is presented only in Chinese and indicates a companion behavior style, but there is no indication that users can choose another language or opt into a locale-specific experience. This can violate language/locale policy when the skill implicitly constrains interaction language without documenting that limitation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The inline comment says '如果有习惯数据,使用用户习惯' and the code reads habits.mostActiveHour, implying behavior adapts to learned user habits. In reality, isFreeTime returns only whether the current hour is in a fixed defaultFreeHours array, and userActiveHour is never used. That directly contradicts the stated intent of the comment.

Content

No source excerpt is available for this finding.